2 * Copyright (C) 2005, 2006 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
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GNUTLS-EXTRA; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "gnutls_int.h"
26 #include "gnutls_record.h"
27 #include "gnutls_errors.h"
28 #include "gnutls_num.h"
29 #include "gnutls_state.h"
31 #define CHECKSUM_SIZE 12
33 struct gnutls_ia_client_credentials_st
35 gnutls_ia_avp_func avp_func
;
39 struct gnutls_ia_server_credentials_st
41 gnutls_ia_avp_func avp_func
;
45 static const char server_finished_label
[] = "server phase finished";
46 static const char client_finished_label
[] = "client phase finished";
47 static const char inner_permutation_label
[] = "inner secret permutation";
48 static const char challenge_label
[] = "inner application challenge";
51 * The TLS/IA packet is the InnerApplication token, described as
52 * follows in draft-funk-tls-inner-application-extension-01.txt:
55 * application_payload(0), intermediate_phase_finished(1),
56 * final_phase_finished(2), (255)
57 * } InnerApplicationType;
60 * InnerApplicationType msg_type;
62 * select (InnerApplicationType) {
63 * case application_payload: ApplicationPayload;
64 * case intermediate_phase_finished: IntermediatePhaseFinished;
65 * case final_phase_finished: FinalPhaseFinished;
71 /* Send TLS/IA data. If data==NULL && sizeofdata==NULL, then the last
72 send was interrupted for some reason, and then we try to send it
73 again. Returns the number of bytes sent, or an error code. If
74 this return E_AGAIN and E_INTERRUPTED, call this function again
75 with data==NULL&&sizeofdata=0NULL until it returns successfully. */
77 _gnutls_send_inner_application (gnutls_session_t session
,
78 gnutls_ia_apptype_t msg_type
,
79 const char *data
, size_t sizeofdata
)
87 plen
= sizeofdata
+ 4;
88 p
= gnutls_malloc (plen
);
92 return GNUTLS_E_MEMORY_ERROR
;
95 *(unsigned char *) p
= (unsigned char) (msg_type
& 0xFF);
96 _gnutls_write_uint24 (sizeofdata
, p
+ 1);
97 memcpy (p
+ 4, data
, sizeofdata
);
100 len
= _gnutls_send_int (session
, GNUTLS_INNER_APPLICATION
, -1, p
, plen
);
108 /* Receive TLS/IA data. Store received TLS/IA message type in
109 *MSG_TYPE, and the data in DATA of max SIZEOFDATA size. Return the
110 number of bytes read, or an error code. */
112 _gnutls_recv_inner_application (gnutls_session_t session
,
113 gnutls_ia_apptype_t
* msg_type
,
114 opaque
* data
, size_t sizeofdata
)
119 len
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1, pkt
, 4);
123 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
127 len
= _gnutls_read_uint24 (&pkt
[1]);
129 if (*msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
&& len
!= CHECKSUM_SIZE
)
132 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
135 if (sizeofdata
< len
)
137 /* XXX push back pkt to IA buffer? */
139 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
146 len
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1,
152 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
159 /* Apply the TLS PRF using the TLS/IA inner secret as keying material,
160 where the seed is the client random concatenated with the server
161 random concatenated EXTRA of EXTRA_SIZE length (which can be NULL/0
162 respectively). LABEL and LABEL_SIZE is used as the label. The
163 result is placed in pre-allocated OUT of OUTSIZE length. */
165 _gnutls_ia_prf (gnutls_session_t session
,
169 const char *extra
, size_t outsize
, opaque
* out
)
173 size_t seedsize
= 2 * TLS_RANDOM_SIZE
+ extra_size
;
175 seed
= gnutls_malloc (seedsize
);
179 return GNUTLS_E_MEMORY_ERROR
;
182 memcpy (seed
, session
->security_parameters
.server_random
, TLS_RANDOM_SIZE
);
183 memcpy (seed
+ TLS_RANDOM_SIZE
, session
->security_parameters
.client_random
,
185 memcpy (seed
+ 2 * TLS_RANDOM_SIZE
, extra
, extra_size
);
187 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
189 label
, label_size
, seed
, seedsize
, outsize
, out
);
197 * gnutls_ia_permute_inner_secret:
198 * @session: is a #gnutls_session_t structure.
199 * @session_keys_size: Size of generated session keys (0 if none).
200 * @session_keys: Generated session keys, used to permute inner secret
203 * Permute the inner secret using the generated session keys.
205 * This can be called in the TLS/IA AVP callback to mix any generated
206 * session keys with the TLS/IA inner secret.
208 * Return value: Return zero on success, or a negative error code.
211 gnutls_ia_permute_inner_secret (gnutls_session_t session
,
212 size_t session_keys_size
,
213 const char *session_keys
)
215 return _gnutls_ia_prf (session
,
216 sizeof (inner_permutation_label
) - 1,
217 inner_permutation_label
,
221 session
->security_parameters
.inner_secret
);
225 * gnutls_ia_generate_challenge:
226 * @session: is a #gnutls_session_t structure.
227 * @buffer_size: size of output buffer.
228 * @buffer: pre-allocated buffer to contain @buffer_size bytes of output.
230 * Generate an application challenge that the client cannot control or
231 * predict, based on the TLS/IA inner secret.
233 * Return value: Returns 0 on success, or an negative error code.
236 gnutls_ia_generate_challenge (gnutls_session_t session
,
237 size_t buffer_size
, char *buffer
)
239 return _gnutls_ia_prf (session
,
240 sizeof (challenge_label
) - 1,
241 challenge_label
, 0, NULL
, buffer_size
, buffer
);
245 * gnutls_ia_extract_inner_secret:
246 * @session: is a #gnutls_session_t structure.
247 * @buffer: pre-allocated buffer to hold 48 bytes of inner secret.
249 * Copy the 48 bytes large inner secret into the specified buffer
251 * This function is typically used after the TLS/IA handshake has
252 * concluded. The TLS/IA inner secret can be used as input to a PRF
253 * to derive session keys. Do not use the inner secret directly as a
254 * session key, because for a resumed session that does not include an
255 * application phase, the inner secret will be identical to the inner
256 * secret in the original session. It is important to include, for
257 * example, the client and server randomness when deriving a sesssion
258 * key from the inner secret.
261 gnutls_ia_extract_inner_secret (gnutls_session_t session
, char *buffer
)
263 memcpy (buffer
, session
->security_parameters
.inner_secret
, TLS_MASTER_SIZE
);
267 * gnutls_ia_endphase_send:
268 * @session: is a #gnutls_session_t structure.
269 * @final_p: Set iff this should signal the final phase.
271 * Send a TLS/IA end phase message.
273 * In the client, this should only be used to acknowledge an end phase
274 * message sent by the server.
276 * In the server, this can be called instead of gnutls_ia_send() if
277 * the server wishes to end an application phase.
279 * Return value: Return 0 on success, or an error code.
282 gnutls_ia_endphase_send (gnutls_session_t session
, int final_p
)
284 opaque local_checksum
[CHECKSUM_SIZE
];
285 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
286 const char *label
= client
? client_finished_label
: server_finished_label
;
287 int size_of_label
= client
? sizeof (client_finished_label
) :
288 sizeof (server_finished_label
);
292 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
293 TLS_MASTER_SIZE
, label
, size_of_label
- 1,
294 /* XXX specification unclear on seed. */
295 "", 0, CHECKSUM_SIZE
, local_checksum
);
299 len
= _gnutls_send_inner_application
301 final_p
? GNUTLS_IA_FINAL_PHASE_FINISHED
:
302 GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
, local_checksum
, CHECKSUM_SIZE
);
304 /* XXX Instead of calling this function over and over...?
305 * while (len == GNUTLS_E_AGAIN || len == GNUTLS_E_INTERRUPTED)
306 * len = _gnutls_io_write_flush(session);
319 * gnutls_ia_verify_endphase:
320 * @session: is a #gnutls_session_t structure.
321 * @checksum: 12-byte checksum data, received from gnutls_ia_recv().
323 * Verify TLS/IA end phase checksum data. If verification fails, the
324 * %GNUTLS_A_INNER_APPLICATION_VERIFICATION alert is sent to the other
327 * This function is called when gnutls_ia_recv() return
328 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
329 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED.
331 * Return value: Return 0 on successful verification, or an error
332 * code. If the checksum verification of the end phase message fails,
333 * %GNUTLS_E_IA_VERIFY_FAILED is returned.
336 gnutls_ia_verify_endphase (gnutls_session_t session
, const char *checksum
)
338 char local_checksum
[CHECKSUM_SIZE
];
339 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
340 const char *label
= client
? server_finished_label
: client_finished_label
;
341 int size_of_label
= client
? sizeof (server_finished_label
) :
342 sizeof (client_finished_label
);
345 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
347 label
, size_of_label
- 1,
348 "", 0, CHECKSUM_SIZE
, local_checksum
);
355 if (memcmp (local_checksum
, checksum
, CHECKSUM_SIZE
) != 0)
357 ret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
358 GNUTLS_A_INNER_APPLICATION_VERIFICATION
);
365 return GNUTLS_E_IA_VERIFY_FAILED
;
372 * gnutls_ia_send: Send peer the specified TLS/IA data.
373 * @session: is a #gnutls_session_t structure.
374 * @data: contains the data to send
375 * @sizeofdata: is the length of the data
377 * Send TLS/IA application payload data. This function has the
378 * similar semantics with send(). The only difference is that is
379 * accepts a GNUTLS session, and uses different error codes.
381 * The TLS/IA protocol is synchronous, so you cannot send more than
382 * one packet at a time. The client always send the first packet.
384 * To finish an application phase in the server, use
385 * gnutls_ia_endphase_send(). The client cannot end an application
386 * phase unilaterally; rather, a client is required to respond with an
387 * endphase of its own if gnutls_ia_recv indicates that the server has
390 * If the EINTR is returned by the internal push function (the default
391 * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
392 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must call
393 * this function again, with the same parameters; alternatively you
394 * could provide a %NULL pointer for data, and 0 for size.
396 * Returns the number of bytes sent, or a negative error code.
399 gnutls_ia_send (gnutls_session_t session
, const char *data
, size_t sizeofdata
)
403 len
= _gnutls_send_inner_application (session
,
404 GNUTLS_IA_APPLICATION_PAYLOAD
,
411 * gnutls_ia_recv - read data from the TLS/IA protocol
412 * @session: is a #gnutls_session_t structure.
413 * @data: the buffer that the data will be read into, must hold >= 12 bytes.
414 * @sizeofdata: the number of requested bytes, must be >= 12.
416 * Receive TLS/IA data. This function has the similar semantics with
417 * recv(). The only difference is that is accepts a GNUTLS session,
418 * and uses different error codes.
420 * If the server attempt to finish an application phase, this function
421 * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
422 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke
423 * gnutls_ia_verify_endphase(), and if it runs the client side, also
424 * send an endphase message of its own using gnutls_ia_endphase_send.
426 * If EINTR is returned by the internal push function (the default is
427 * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If
428 * GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call
429 * this function again, with the same parameters; alternatively you
430 * could provide a NULL pointer for data, and 0 for size.
432 * Returns the number of bytes received. A negative error code is
433 * returned in case of an error. The
434 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED and
435 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED errors are returned when an
436 * application phase finished message has been sent by the server.
439 gnutls_ia_recv (gnutls_session_t session
, char *data
, size_t sizeofdata
)
441 gnutls_ia_apptype_t msg_type
;
444 len
= _gnutls_recv_inner_application (session
, &msg_type
, data
, sizeofdata
);
446 if (msg_type
== GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
)
447 return GNUTLS_E_WARNING_IA_IPHF_RECEIVED
;
448 else if (msg_type
== GNUTLS_IA_FINAL_PHASE_FINISHED
)
449 return GNUTLS_E_WARNING_IA_FPHF_RECEIVED
;
454 /* XXX rewrite the following two functions as state machines, to
455 handle EAGAIN/EINTERRUPTED? just add more problems to callers,
459 _gnutls_ia_client_handshake (gnutls_session_t session
)
463 char tmp
[1024]; /* XXX */
466 const struct gnutls_ia_client_credentials_st
*cred
=
467 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
470 return GNUTLS_E_INTERNAL_ERROR
;
477 ret
= cred
->avp_func (session
, cred
->avp_ptr
,
478 buf
, buflen
, &avp
, &avplen
);
482 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
483 GNUTLS_A_INNER_APPLICATION_FAILURE
);
489 len
= gnutls_ia_send (session
, avp
, avplen
);
494 len
= gnutls_ia_recv (session
, tmp
, sizeof (tmp
));
495 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
496 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
498 ret
= gnutls_ia_verify_endphase (session
, tmp
);
502 ret
= gnutls_ia_endphase_send
503 (session
, len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
);
508 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
514 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
528 _gnutls_ia_server_handshake (gnutls_session_t session
)
530 gnutls_ia_apptype_t msg_type
;
534 const struct gnutls_ia_server_credentials_st
*cred
=
535 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
538 return GNUTLS_E_INTERNAL_ERROR
;
545 len
= gnutls_ia_recv (session
, buf
, sizeof (buf
));
546 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
547 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
549 ret
= gnutls_ia_verify_endphase (session
, buf
);
554 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
556 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
565 ret
= cred
->avp_func (session
, cred
->avp_ptr
, buf
, len
, &avp
, &avplen
);
569 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
570 GNUTLS_A_INNER_APPLICATION_FAILURE
);
578 if (msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
)
580 ret
= gnutls_ia_endphase_send (session
, msg_type
==
581 GNUTLS_IA_FINAL_PHASE_FINISHED
);
587 len
= gnutls_ia_send (session
, avp
, avplen
);
599 * gnutls_ia_handshake_p:
600 * @session: is a #gnutls_session_t structure.
602 * Predicate to be used after gnutls_handshake() to decide whether to
603 * invoke gnutls_ia_handshake(). Usable by both clients and servers.
605 * Return value: non-zero if TLS/IA handshake is expected, zero
609 gnutls_ia_handshake_p (gnutls_session_t session
)
611 tls_ext_st
*ext
= &session
->security_parameters
.extensions
;
613 /* Either local side or peer doesn't do TLS/IA: don't do IA */
615 if (!ext
->gnutls_ia_enable
|| !ext
->gnutls_ia_peer_enable
)
618 /* Not resuming or we don't allow skipping on resumption locally: do IA */
620 if (!ext
->gnutls_ia_allowskip
|| !gnutls_session_is_resumed (session
))
623 /* If we're resuming and we and the peer both allow skipping on resumption:
626 return !ext
->gnutls_ia_peer_allowskip
;
631 * gnutls_ia_handshake:
632 * @session: is a #gnutls_session_t structure.
634 * Perform a TLS/IA handshake. This should be called after
635 * gnutls_handshake() iff gnutls_ia_handshake_p().
637 * Return 0 on success, or an error code.
640 gnutls_ia_handshake (gnutls_session_t session
)
644 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
645 ret
= _gnutls_ia_client_handshake (session
);
647 ret
= _gnutls_ia_server_handshake (session
);
653 * gnutls_ia_allocate_client_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
654 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
656 * This structure is complex enough to manipulate directly thus this
657 * helper function is provided in order to allocate it.
659 * Adding this credential to a session will enable TLS/IA, and will
660 * require an Application Phase after the TLS handshake (if the server
661 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
664 * Returns 0 on success.
667 gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t
* sc
)
669 *sc
= gnutls_calloc (1, sizeof (**sc
));
672 return GNUTLS_E_MEMORY_ERROR
;
678 * gnutls_ia_free_client_credentials - Used to free an allocated #gnutls_ia_client_credentials_t structure
679 * @sc: is an #gnutls_ia_client_credentials_t structure.
681 * This structure is complex enough to manipulate directly thus this
682 * helper function is provided in order to free (deallocate) it.
686 gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc
)
692 * gnutls_ia_set_client_avp_function - Used to set a AVP callback
693 * @cred: is a #gnutls_ia_client_credentials_t structure.
694 * @avp_func: is the callback function
696 * Set the TLS/IA AVP callback handler used for the session.
698 * The AVP callback is called to process AVPs received from the
699 * server, and to get a new AVP to send to the server.
701 * The callback's function form is:
702 * int (*avp_func) (gnutls_session_t session, void *ptr,
703 * const char *last, size_t lastlen,
704 * char **next, size_t *nextlen);
706 * The @session parameter is the #gnutls_session_t structure
707 * corresponding to the current session. The @ptr parameter is the
708 * application hook pointer, set through
709 * gnutls_ia_set_client_avp_ptr(). The AVP received from the server
710 * is present in @last of @lastlen size, which will be %NULL on the
711 * first invocation. The newly allocated output AVP to send to the
712 * server should be placed in *@next of *@nextlen size.
714 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
715 * generated session keys with the TLS/IA inner secret.
717 * Return 0 (%GNUTLS_IA_APPLICATION_PAYLOAD) on success, or a negative
718 * error code to abort the TLS/IA handshake.
720 * Note that the callback must use allocate the @next parameter using
721 * gnutls_malloc(), because it is released via gnutls_free() by the
722 * TLS/IA handshake function.
726 gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred
,
727 gnutls_ia_avp_func avp_func
)
729 cred
->avp_func
= avp_func
;
733 * gnutls_ia_set_client_avp_ptr - Sets a pointer to be sent to TLS/IA callback
734 * @cred: is a #gnutls_ia_client_credentials_t structure.
735 * @ptr: is the pointer
737 * Sets the pointer that will be provided to the TLS/IA callback
738 * function as the first argument.
742 gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred
, void *ptr
)
748 * gnutls_ia_get_client_avp_ptr - Returns the pointer which is sent to TLS/IA callback
749 * @cred: is a #gnutls_ia_client_credentials_t structure.
751 * Returns the pointer that will be provided to the TLS/IA callback
752 * function as the first argument.
756 gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t cred
)
758 return cred
->avp_ptr
;
762 * gnutls_ia_allocate_server_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
763 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
765 * This structure is complex enough to manipulate directly thus this
766 * helper function is provided in order to allocate it.
768 * Adding this credential to a session will enable TLS/IA, and will
769 * require an Application Phase after the TLS handshake (if the client
770 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
773 * Returns 0 on success.
776 gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t
* sc
)
778 *sc
= gnutls_calloc (1, sizeof (**sc
));
781 return GNUTLS_E_MEMORY_ERROR
;
787 * gnutls_ia_free_server_credentials - Used to free an allocated #gnutls_ia_server_credentials_t structure
788 * @sc: is an #gnutls_ia_server_credentials_t structure.
790 * This structure is complex enough to manipulate directly thus this
791 * helper function is provided in order to free (deallocate) it.
795 gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc
)
801 * gnutls_ia_set_server_credentials_function - Used to set a AVP callback
802 * @cred: is a #gnutls_ia_server_credentials_t structure.
803 * @func: is the callback function
805 * Set the TLS/IA AVP callback handler used for the session.
807 * The callback's function form is:
808 * int (*avp_func) (gnutls_session_t session, void *ptr,
809 * const char *last, size_t lastlen,
810 * char **next, size_t *nextlen);
812 * The @session parameter is the #gnutls_session_t structure
813 * corresponding to the current session. The @ptr parameter is the
814 * application hook pointer, set through
815 * gnutls_ia_set_server_avp_ptr(). The AVP received from the client
816 * is present in @last of @lastlen size. The newly allocated output
817 * AVP to send to the client should be placed in *@next of *@nextlen
820 * The AVP callback is called to process incoming AVPs from the
821 * client, and to get a new AVP to send to the client. It can also be
822 * used to instruct the TLS/IA handshake to do go into the
823 * Intermediate or Final phases. It return a negative error code, or
824 * an #gnutls_ia_apptype_t message type.
826 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
827 * generated session keys with the TLS/IA inner secret.
829 * Specifically, return %GNUTLS_IA_APPLICATION_PAYLOAD (0) to send
830 * another AVP to the client, return
831 * %GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED (1) to indicate that an
832 * IntermediatePhaseFinished message should be sent, and return
833 * %GNUTLS_IA_FINAL_PHASE_FINISHED (2) to indicate that an
834 * FinalPhaseFinished message should be sent. In the last two cases,
835 * the contents of the @next and @nextlen parameter is not used.
837 * Note that the callback must use allocate the @next parameter using
838 * gnutls_malloc(), because it is released via gnutls_free() by the
839 * TLS/IA handshake function.
842 gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred
,
843 gnutls_ia_avp_func avp_func
)
845 cred
->avp_func
= avp_func
;
849 * gnutls_ia_set_server_avp_ptr - Sets a pointer to be sent to TLS/IA callback
850 * @cred: is a #gnutls_ia_client_credentials_t structure.
851 * @ptr: is the pointer
853 * Sets the pointer that will be provided to the TLS/IA callback
854 * function as the first argument.
858 gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred
, void *ptr
)
864 * gnutls_ia_get_server_avp_ptr - Returns the pointer which is sent to TLS/IA callback
865 * @cred: is a #gnutls_ia_client_credentials_t structure.
867 * Returns the pointer that will be provided to the TLS/IA callback
868 * function as the first argument.
872 gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred
)
874 return cred
->avp_ptr
;
878 * gnutls_ia_enable - Indicate willingness for TLS/IA application phases
879 * @session: is a #gnutls_session_t structure.
880 * @allow_skip_on_resume: non-zero if local party allows to skip the
881 * TLS/IA application phases for a resumed session.
883 * Specify whether we must advertise support for the TLS/IA extension
884 * during the handshake.
886 * At the client side, we always advertise TLS/IA if gnutls_ia_enable
887 * was called before the handshake; at the server side, we also
888 * require that the client has advertised that it wants to run TLS/IA
889 * before including the advertisement, as required by the protocol.
891 * Similarly, at the client side we always advertise that we allow
892 * TLS/IA to be skipped for resumed sessions if @allow_skip_on_resume
893 * is non-zero; at the server side, we also require that the session
894 * is indeed resumable and that the client has also advertised that it
895 * allows TLS/IA to be skipped for resumed sessions.
897 * After the TLS handshake, call gnutls_ia_handshake_p() to find out
898 * whether both parties agreed to do a TLS/IA handshake, before
899 * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_*
903 gnutls_ia_enable (gnutls_session_t session
, int allow_skip_on_resume
)
905 session
->security_parameters
.extensions
.gnutls_ia_enable
= 1;
906 session
->security_parameters
.extensions
.gnutls_ia_allowskip
=
907 allow_skip_on_resume
;