2 * Copyright (C) 2005, 2006, 2008 Free Software Foundation
4 * Author: Simon Josefsson
6 * This file is part of GNUTLS-EXTRA.
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "gnutls_int.h"
23 #include "gnutls_record.h"
24 #include "gnutls_errors.h"
25 #include "gnutls_num.h"
26 #include "gnutls_state.h"
28 #define CHECKSUM_SIZE 12
30 struct gnutls_ia_client_credentials_st
32 gnutls_ia_avp_func avp_func
;
36 struct gnutls_ia_server_credentials_st
38 gnutls_ia_avp_func avp_func
;
42 static const char server_finished_label
[] = "server phase finished";
43 static const char client_finished_label
[] = "client phase finished";
44 static const char inner_permutation_label
[] = "inner secret permutation";
45 static const char challenge_label
[] = "inner application challenge";
48 * The TLS/IA packet is the InnerApplication token, described as
49 * follows in draft-funk-tls-inner-application-extension-01.txt:
52 * application_payload(0), intermediate_phase_finished(1),
53 * final_phase_finished(2), (255)
54 * } InnerApplicationType;
57 * InnerApplicationType msg_type;
59 * select (InnerApplicationType) {
60 * case application_payload: ApplicationPayload;
61 * case intermediate_phase_finished: IntermediatePhaseFinished;
62 * case final_phase_finished: FinalPhaseFinished;
68 /* Send TLS/IA data. If data==NULL && sizeofdata==NULL, then the last
69 send was interrupted for some reason, and then we try to send it
70 again. Returns the number of bytes sent, or an error code. If
71 this return E_AGAIN and E_INTERRUPTED, call this function again
72 with data==NULL&&sizeofdata=0NULL until it returns successfully. */
74 _gnutls_send_inner_application (gnutls_session_t session
,
75 gnutls_ia_apptype_t msg_type
,
76 const char *data
, size_t sizeofdata
)
84 plen
= sizeofdata
+ 4;
85 p
= gnutls_malloc (plen
);
89 return GNUTLS_E_MEMORY_ERROR
;
92 *(unsigned char *) p
= (unsigned char) (msg_type
& 0xFF);
93 _gnutls_write_uint24 (sizeofdata
, p
+ 1);
94 memcpy (p
+ 4, data
, sizeofdata
);
97 len
= _gnutls_send_int (session
, GNUTLS_INNER_APPLICATION
, -1, p
, plen
);
105 /* Receive TLS/IA data. Store received TLS/IA message type in
106 *MSG_TYPE, and the data in DATA of max SIZEOFDATA size. Return the
107 number of bytes read, or an error code. */
109 _gnutls_recv_inner_application (gnutls_session_t session
,
110 gnutls_ia_apptype_t
* msg_type
,
111 opaque
* data
, size_t sizeofdata
)
116 len
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1, pkt
, 4);
120 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
124 len
= _gnutls_read_uint24 (&pkt
[1]);
126 if (*msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
&& len
!= CHECKSUM_SIZE
)
129 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
132 if (sizeofdata
< len
)
134 /* XXX push back pkt to IA buffer? */
136 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
143 len
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1,
149 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
156 /* Apply the TLS PRF using the TLS/IA inner secret as keying material,
157 where the seed is the client random concatenated with the server
158 random concatenated EXTRA of EXTRA_SIZE length (which can be NULL/0
159 respectively). LABEL and LABEL_SIZE is used as the label. The
160 result is placed in pre-allocated OUT of OUTSIZE length. */
162 _gnutls_ia_prf (gnutls_session_t session
,
166 const char *extra
, size_t outsize
, opaque
* out
)
170 size_t seedsize
= 2 * TLS_RANDOM_SIZE
+ extra_size
;
172 seed
= gnutls_malloc (seedsize
);
176 return GNUTLS_E_MEMORY_ERROR
;
179 memcpy (seed
, session
->security_parameters
.server_random
, TLS_RANDOM_SIZE
);
180 memcpy (seed
+ TLS_RANDOM_SIZE
, session
->security_parameters
.client_random
,
182 memcpy (seed
+ 2 * TLS_RANDOM_SIZE
, extra
, extra_size
);
184 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
186 label
, label_size
, seed
, seedsize
, outsize
, out
);
194 * gnutls_ia_permute_inner_secret:
195 * @session: is a #gnutls_session_t structure.
196 * @session_keys_size: Size of generated session keys (0 if none).
197 * @session_keys: Generated session keys, used to permute inner secret
200 * Permute the inner secret using the generated session keys.
202 * This can be called in the TLS/IA AVP callback to mix any generated
203 * session keys with the TLS/IA inner secret.
205 * Return value: Return zero on success, or a negative error code.
208 gnutls_ia_permute_inner_secret (gnutls_session_t session
,
209 size_t session_keys_size
,
210 const char *session_keys
)
212 return _gnutls_ia_prf (session
,
213 sizeof (inner_permutation_label
) - 1,
214 inner_permutation_label
,
218 session
->security_parameters
.inner_secret
);
222 * gnutls_ia_generate_challenge:
223 * @session: is a #gnutls_session_t structure.
224 * @buffer_size: size of output buffer.
225 * @buffer: pre-allocated buffer to contain @buffer_size bytes of output.
227 * Generate an application challenge that the client cannot control or
228 * predict, based on the TLS/IA inner secret.
230 * Return value: Returns 0 on success, or an negative error code.
233 gnutls_ia_generate_challenge (gnutls_session_t session
,
234 size_t buffer_size
, char *buffer
)
236 return _gnutls_ia_prf (session
,
237 sizeof (challenge_label
) - 1,
238 challenge_label
, 0, NULL
, buffer_size
, buffer
);
242 * gnutls_ia_extract_inner_secret:
243 * @session: is a #gnutls_session_t structure.
244 * @buffer: pre-allocated buffer to hold 48 bytes of inner secret.
246 * Copy the 48 bytes large inner secret into the specified buffer
248 * This function is typically used after the TLS/IA handshake has
249 * concluded. The TLS/IA inner secret can be used as input to a PRF
250 * to derive session keys. Do not use the inner secret directly as a
251 * session key, because for a resumed session that does not include an
252 * application phase, the inner secret will be identical to the inner
253 * secret in the original session. It is important to include, for
254 * example, the client and server randomness when deriving a sesssion
255 * key from the inner secret.
258 gnutls_ia_extract_inner_secret (gnutls_session_t session
, char *buffer
)
260 memcpy (buffer
, session
->security_parameters
.inner_secret
, TLS_MASTER_SIZE
);
264 * gnutls_ia_endphase_send:
265 * @session: is a #gnutls_session_t structure.
266 * @final_p: Set iff this should signal the final phase.
268 * Send a TLS/IA end phase message.
270 * In the client, this should only be used to acknowledge an end phase
271 * message sent by the server.
273 * In the server, this can be called instead of gnutls_ia_send() if
274 * the server wishes to end an application phase.
276 * Return value: Return 0 on success, or an error code.
279 gnutls_ia_endphase_send (gnutls_session_t session
, int final_p
)
281 opaque local_checksum
[CHECKSUM_SIZE
];
282 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
283 const char *label
= client
? client_finished_label
: server_finished_label
;
284 int size_of_label
= client
? sizeof (client_finished_label
) :
285 sizeof (server_finished_label
);
289 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
290 TLS_MASTER_SIZE
, label
, size_of_label
- 1,
291 /* XXX specification unclear on seed. */
292 "", 0, CHECKSUM_SIZE
, local_checksum
);
296 len
= _gnutls_send_inner_application
298 final_p
? GNUTLS_IA_FINAL_PHASE_FINISHED
:
299 GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
, local_checksum
, CHECKSUM_SIZE
);
301 /* XXX Instead of calling this function over and over...?
302 * while (len == GNUTLS_E_AGAIN || len == GNUTLS_E_INTERRUPTED)
303 * len = _gnutls_io_write_flush(session);
316 * gnutls_ia_verify_endphase:
317 * @session: is a #gnutls_session_t structure.
318 * @checksum: 12-byte checksum data, received from gnutls_ia_recv().
320 * Verify TLS/IA end phase checksum data. If verification fails, the
321 * %GNUTLS_A_INNER_APPLICATION_VERIFICATION alert is sent to the other
324 * This function is called when gnutls_ia_recv() return
325 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
326 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED.
328 * Return value: Return 0 on successful verification, or an error
329 * code. If the checksum verification of the end phase message fails,
330 * %GNUTLS_E_IA_VERIFY_FAILED is returned.
333 gnutls_ia_verify_endphase (gnutls_session_t session
, const char *checksum
)
335 char local_checksum
[CHECKSUM_SIZE
];
336 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
337 const char *label
= client
? server_finished_label
: client_finished_label
;
338 int size_of_label
= client
? sizeof (server_finished_label
) :
339 sizeof (client_finished_label
);
342 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
344 label
, size_of_label
- 1,
345 "", 0, CHECKSUM_SIZE
, local_checksum
);
352 if (memcmp (local_checksum
, checksum
, CHECKSUM_SIZE
) != 0)
354 ret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
355 GNUTLS_A_INNER_APPLICATION_VERIFICATION
);
362 return GNUTLS_E_IA_VERIFY_FAILED
;
369 * gnutls_ia_send: Send peer the specified TLS/IA data.
370 * @session: is a #gnutls_session_t structure.
371 * @data: contains the data to send
372 * @sizeofdata: is the length of the data
374 * Send TLS/IA application payload data. This function has the
375 * similar semantics with send(). The only difference is that is
376 * accepts a GNUTLS session, and uses different error codes.
378 * The TLS/IA protocol is synchronous, so you cannot send more than
379 * one packet at a time. The client always send the first packet.
381 * To finish an application phase in the server, use
382 * gnutls_ia_endphase_send(). The client cannot end an application
383 * phase unilaterally; rather, a client is required to respond with an
384 * endphase of its own if gnutls_ia_recv indicates that the server has
387 * If the EINTR is returned by the internal push function (the default
388 * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
389 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must call
390 * this function again, with the same parameters; alternatively you
391 * could provide a %NULL pointer for data, and 0 for size.
393 * Returns: The number of bytes sent, or a negative error code.
396 gnutls_ia_send (gnutls_session_t session
, const char *data
, size_t sizeofdata
)
400 len
= _gnutls_send_inner_application (session
,
401 GNUTLS_IA_APPLICATION_PAYLOAD
,
408 * gnutls_ia_recv - read data from the TLS/IA protocol
409 * @session: is a #gnutls_session_t structure.
410 * @data: the buffer that the data will be read into, must hold >= 12 bytes.
411 * @sizeofdata: the number of requested bytes, must be >= 12.
413 * Receive TLS/IA data. This function has the similar semantics with
414 * recv(). The only difference is that is accepts a GNUTLS session,
415 * and uses different error codes.
417 * If the server attempt to finish an application phase, this function
418 * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
419 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke
420 * gnutls_ia_verify_endphase(), and if it runs the client side, also
421 * send an endphase message of its own using gnutls_ia_endphase_send.
423 * If EINTR is returned by the internal push function (the default is
424 * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If
425 * GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call
426 * this function again, with the same parameters; alternatively you
427 * could provide a NULL pointer for data, and 0 for size.
429 * Returns: The number of bytes received. A negative error code is
430 * returned in case of an error. The
431 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED and
432 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED errors are returned when an
433 * application phase finished message has been sent by the server.
436 gnutls_ia_recv (gnutls_session_t session
, char *data
, size_t sizeofdata
)
438 gnutls_ia_apptype_t msg_type
= 0;
441 len
= _gnutls_recv_inner_application (session
, &msg_type
, data
, sizeofdata
);
443 if (msg_type
== GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
)
444 return GNUTLS_E_WARNING_IA_IPHF_RECEIVED
;
445 else if (msg_type
== GNUTLS_IA_FINAL_PHASE_FINISHED
)
446 return GNUTLS_E_WARNING_IA_FPHF_RECEIVED
;
451 /* XXX rewrite the following two functions as state machines, to
452 handle EAGAIN/EINTERRUPTED? just add more problems to callers,
456 _gnutls_ia_client_handshake (gnutls_session_t session
)
460 char tmp
[1024]; /* XXX */
463 const struct gnutls_ia_client_credentials_st
*cred
=
464 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
467 return GNUTLS_E_INTERNAL_ERROR
;
474 ret
= cred
->avp_func (session
, cred
->avp_ptr
,
475 buf
, buflen
, &avp
, &avplen
);
479 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
480 GNUTLS_A_INNER_APPLICATION_FAILURE
);
486 len
= gnutls_ia_send (session
, avp
, avplen
);
491 len
= gnutls_ia_recv (session
, tmp
, sizeof (tmp
));
492 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
493 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
495 ret
= gnutls_ia_verify_endphase (session
, tmp
);
499 ret
= gnutls_ia_endphase_send
500 (session
, len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
);
505 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
511 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
525 _gnutls_ia_server_handshake (gnutls_session_t session
)
527 gnutls_ia_apptype_t msg_type
;
531 const struct gnutls_ia_server_credentials_st
*cred
=
532 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
535 return GNUTLS_E_INTERNAL_ERROR
;
542 len
= gnutls_ia_recv (session
, buf
, sizeof (buf
));
543 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
544 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
546 ret
= gnutls_ia_verify_endphase (session
, buf
);
551 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
553 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
562 ret
= cred
->avp_func (session
, cred
->avp_ptr
, buf
, len
, &avp
, &avplen
);
566 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
567 GNUTLS_A_INNER_APPLICATION_FAILURE
);
575 if (msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
)
577 ret
= gnutls_ia_endphase_send (session
, msg_type
==
578 GNUTLS_IA_FINAL_PHASE_FINISHED
);
584 len
= gnutls_ia_send (session
, avp
, avplen
);
596 * gnutls_ia_handshake_p:
597 * @session: is a #gnutls_session_t structure.
599 * Predicate to be used after gnutls_handshake() to decide whether to
600 * invoke gnutls_ia_handshake(). Usable by both clients and servers.
602 * Return value: non-zero if TLS/IA handshake is expected, zero
606 gnutls_ia_handshake_p (gnutls_session_t session
)
608 tls_ext_st
*ext
= &session
->security_parameters
.extensions
;
610 /* Either local side or peer doesn't do TLS/IA: don't do IA */
612 if (!ext
->gnutls_ia_enable
|| !ext
->gnutls_ia_peer_enable
)
615 /* Not resuming or we don't allow skipping on resumption locally: do IA */
617 if (!ext
->gnutls_ia_allowskip
|| !gnutls_session_is_resumed (session
))
620 /* If we're resuming and we and the peer both allow skipping on resumption:
623 return !ext
->gnutls_ia_peer_allowskip
;
628 * gnutls_ia_handshake:
629 * @session: is a #gnutls_session_t structure.
631 * Perform a TLS/IA handshake. This should be called after
632 * gnutls_handshake() iff gnutls_ia_handshake_p().
634 * Return 0 on success, or an error code.
637 gnutls_ia_handshake (gnutls_session_t session
)
641 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
642 ret
= _gnutls_ia_client_handshake (session
);
644 ret
= _gnutls_ia_server_handshake (session
);
650 * gnutls_ia_allocate_client_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
651 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
653 * This structure is complex enough to manipulate directly thus this
654 * helper function is provided in order to allocate it.
656 * Adding this credential to a session will enable TLS/IA, and will
657 * require an Application Phase after the TLS handshake (if the server
658 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
661 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
662 * an error code is returned.
665 gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t
* sc
)
667 *sc
= gnutls_calloc (1, sizeof (**sc
));
670 return GNUTLS_E_MEMORY_ERROR
;
676 * gnutls_ia_free_client_credentials - Used to free an allocated #gnutls_ia_client_credentials_t structure
677 * @sc: is an #gnutls_ia_client_credentials_t structure.
679 * This structure is complex enough to manipulate directly thus this
680 * helper function is provided in order to free (deallocate) it.
684 gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc
)
690 * gnutls_ia_set_client_avp_function - Used to set a AVP callback
691 * @cred: is a #gnutls_ia_client_credentials_t structure.
692 * @avp_func: is the callback function
694 * Set the TLS/IA AVP callback handler used for the session.
696 * The AVP callback is called to process AVPs received from the
697 * server, and to get a new AVP to send to the server.
699 * The callback's function form is:
700 * int (*avp_func) (gnutls_session_t session, void *ptr,
701 * const char *last, size_t lastlen,
702 * char **next, size_t *nextlen);
704 * The @session parameter is the #gnutls_session_t structure
705 * corresponding to the current session. The @ptr parameter is the
706 * application hook pointer, set through
707 * gnutls_ia_set_client_avp_ptr(). The AVP received from the server
708 * is present in @last of @lastlen size, which will be %NULL on the
709 * first invocation. The newly allocated output AVP to send to the
710 * server should be placed in *@next of *@nextlen size.
712 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
713 * generated session keys with the TLS/IA inner secret.
715 * Return 0 (%GNUTLS_IA_APPLICATION_PAYLOAD) on success, or a negative
716 * error code to abort the TLS/IA handshake.
718 * Note that the callback must use allocate the @next parameter using
719 * gnutls_malloc(), because it is released via gnutls_free() by the
720 * TLS/IA handshake function.
724 gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred
,
725 gnutls_ia_avp_func avp_func
)
727 cred
->avp_func
= avp_func
;
731 * gnutls_ia_set_client_avp_ptr - Sets a pointer to be sent to TLS/IA callback
732 * @cred: is a #gnutls_ia_client_credentials_t structure.
733 * @ptr: is the pointer
735 * Sets the pointer that will be provided to the TLS/IA callback
736 * function as the first argument.
739 gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred
, void *ptr
)
745 * gnutls_ia_get_client_avp_ptr - Returns the pointer which is sent to TLS/IA callback
746 * @cred: is a #gnutls_ia_client_credentials_t structure.
748 * Returns the pointer that will be provided to the TLS/IA callback
749 * function as the first argument.
751 * Returns: The client callback data pointer.
754 gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t cred
)
756 return cred
->avp_ptr
;
760 * gnutls_ia_allocate_server_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
761 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
763 * This structure is complex enough to manipulate directly thus this
764 * helper function is provided in order to allocate it.
766 * Adding this credential to a session will enable TLS/IA, and will
767 * require an Application Phase after the TLS handshake (if the client
768 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
771 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
772 * an error code is returned.
775 gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t
* sc
)
777 *sc
= gnutls_calloc (1, sizeof (**sc
));
780 return GNUTLS_E_MEMORY_ERROR
;
786 * gnutls_ia_free_server_credentials - Used to free an allocated #gnutls_ia_server_credentials_t structure
787 * @sc: is an #gnutls_ia_server_credentials_t structure.
789 * This structure is complex enough to manipulate directly thus this
790 * helper function is provided in order to free (deallocate) it.
794 gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc
)
800 * gnutls_ia_set_server_credentials_function - Used to set a AVP callback
801 * @cred: is a #gnutls_ia_server_credentials_t structure.
802 * @func: is the callback function
804 * Set the TLS/IA AVP callback handler used for the session.
806 * The callback's function form is:
807 * int (*avp_func) (gnutls_session_t session, void *ptr,
808 * const char *last, size_t lastlen,
809 * char **next, size_t *nextlen);
811 * The @session parameter is the #gnutls_session_t structure
812 * corresponding to the current session. The @ptr parameter is the
813 * application hook pointer, set through
814 * gnutls_ia_set_server_avp_ptr(). The AVP received from the client
815 * is present in @last of @lastlen size. The newly allocated output
816 * AVP to send to the client should be placed in *@next of *@nextlen
819 * The AVP callback is called to process incoming AVPs from the
820 * client, and to get a new AVP to send to the client. It can also be
821 * used to instruct the TLS/IA handshake to do go into the
822 * Intermediate or Final phases. It return a negative error code, or
823 * an #gnutls_ia_apptype_t message type.
825 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
826 * generated session keys with the TLS/IA inner secret.
828 * Specifically, return %GNUTLS_IA_APPLICATION_PAYLOAD (0) to send
829 * another AVP to the client, return
830 * %GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED (1) to indicate that an
831 * IntermediatePhaseFinished message should be sent, and return
832 * %GNUTLS_IA_FINAL_PHASE_FINISHED (2) to indicate that an
833 * FinalPhaseFinished message should be sent. In the last two cases,
834 * the contents of the @next and @nextlen parameter is not used.
836 * Note that the callback must use allocate the @next parameter using
837 * gnutls_malloc(), because it is released via gnutls_free() by the
838 * TLS/IA handshake function.
841 gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred
,
842 gnutls_ia_avp_func avp_func
)
844 cred
->avp_func
= avp_func
;
848 * gnutls_ia_set_server_avp_ptr - Sets a pointer to be sent to TLS/IA callback
849 * @cred: is a #gnutls_ia_client_credentials_t structure.
850 * @ptr: is the pointer
852 * Sets the pointer that will be provided to the TLS/IA callback
853 * function as the first argument.
856 gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred
, void *ptr
)
862 * gnutls_ia_get_server_avp_ptr - Returns the pointer which is sent to TLS/IA callback
863 * @cred: is a #gnutls_ia_client_credentials_t structure.
865 * Returns the pointer that will be provided to the TLS/IA callback
866 * function as the first argument.
868 * Returns: The server callback data pointer.
871 gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred
)
873 return cred
->avp_ptr
;
877 * gnutls_ia_enable - Indicate willingness for TLS/IA application phases
878 * @session: is a #gnutls_session_t structure.
879 * @allow_skip_on_resume: non-zero if local party allows to skip the
880 * TLS/IA application phases for a resumed session.
882 * Specify whether we must advertise support for the TLS/IA extension
883 * during the handshake.
885 * At the client side, we always advertise TLS/IA if gnutls_ia_enable
886 * was called before the handshake; at the server side, we also
887 * require that the client has advertised that it wants to run TLS/IA
888 * before including the advertisement, as required by the protocol.
890 * Similarly, at the client side we always advertise that we allow
891 * TLS/IA to be skipped for resumed sessions if @allow_skip_on_resume
892 * is non-zero; at the server side, we also require that the session
893 * is indeed resumable and that the client has also advertised that it
894 * allows TLS/IA to be skipped for resumed sessions.
896 * After the TLS handshake, call gnutls_ia_handshake_p() to find out
897 * whether both parties agreed to do a TLS/IA handshake, before
898 * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_*
902 gnutls_ia_enable (gnutls_session_t session
, int allow_skip_on_resume
)
904 session
->security_parameters
.extensions
.gnutls_ia_enable
= 1;
905 session
->security_parameters
.extensions
.gnutls_ia_allowskip
=
906 allow_skip_on_resume
;