2 * Copyright (C) 2005, 2006, 2008, 2009 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"
27 #include <gnutls/extra.h>
29 #define CHECKSUM_SIZE 12
31 struct gnutls_ia_client_credentials_st
33 gnutls_ia_avp_func avp_func
;
37 struct gnutls_ia_server_credentials_st
39 gnutls_ia_avp_func avp_func
;
43 static const char server_finished_label
[] = "server phase finished";
44 static const char client_finished_label
[] = "client phase finished";
45 static const char inner_permutation_label
[] = "inner secret permutation";
46 static const char challenge_label
[] = "inner application challenge";
49 * The TLS/IA packet is the InnerApplication token, described as
50 * follows in draft-funk-tls-inner-application-extension-01.txt:
53 * application_payload(0), intermediate_phase_finished(1),
54 * final_phase_finished(2), (255)
55 * } InnerApplicationType;
58 * InnerApplicationType msg_type;
60 * select (InnerApplicationType) {
61 * case application_payload: ApplicationPayload;
62 * case intermediate_phase_finished: IntermediatePhaseFinished;
63 * case final_phase_finished: FinalPhaseFinished;
69 /* Send TLS/IA data. If data==NULL && sizeofdata==NULL, then the last
70 send was interrupted for some reason, and then we try to send it
71 again. Returns the number of bytes sent, or an error code. If
72 this return E_AGAIN and E_INTERRUPTED, call this function again
73 with data==NULL&&sizeofdata=0NULL until it returns successfully. */
75 _gnutls_send_inner_application (gnutls_session_t session
,
76 gnutls_ia_apptype_t msg_type
,
77 const char *data
, size_t sizeofdata
)
85 plen
= sizeofdata
+ 4;
86 p
= gnutls_malloc (plen
);
90 return GNUTLS_E_MEMORY_ERROR
;
93 *(unsigned char *) p
= (unsigned char) (msg_type
& 0xFF);
94 _gnutls_write_uint24 (sizeofdata
, p
+ 1);
95 memcpy (p
+ 4, data
, sizeofdata
);
98 len
= _gnutls_send_int (session
, GNUTLS_INNER_APPLICATION
, -1, p
, plen
);
106 /* Receive TLS/IA data. Store received TLS/IA message type in
107 *MSG_TYPE, and the data in DATA of max SIZEOFDATA size. Return the
108 number of bytes read, or an error code. */
110 _gnutls_recv_inner_application (gnutls_session_t session
,
111 gnutls_ia_apptype_t
* msg_type
,
112 opaque
* data
, size_t sizeofdata
)
118 len
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1, pkt
, 4);
122 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
126 len24
= _gnutls_read_uint24 (&pkt
[1]);
128 if (*msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
&& len24
!= CHECKSUM_SIZE
)
131 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
134 if (sizeofdata
< len24
)
136 /* XXX push back pkt to IA buffer? */
138 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
143 uint32_t tmplen
= len24
;
145 len24
= _gnutls_recv_int (session
, GNUTLS_INNER_APPLICATION
, -1,
151 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
158 /* Apply the TLS PRF using the TLS/IA inner secret as keying material,
159 where the seed is the client random concatenated with the server
160 random concatenated EXTRA of EXTRA_SIZE length (which can be NULL/0
161 respectively). LABEL and LABEL_SIZE is used as the label. The
162 result is placed in pre-allocated OUT of OUTSIZE length. */
164 _gnutls_ia_prf (gnutls_session_t session
,
168 const char *extra
, size_t outsize
, opaque
* out
)
172 size_t seedsize
= 2 * GNUTLS_RANDOM_SIZE
+ extra_size
;
174 seed
= gnutls_malloc (seedsize
);
178 return GNUTLS_E_MEMORY_ERROR
;
181 memcpy (seed
, session
->security_parameters
.server_random
,
183 memcpy (seed
+ GNUTLS_RANDOM_SIZE
,
184 session
->security_parameters
.client_random
, GNUTLS_RANDOM_SIZE
);
185 memcpy (seed
+ 2 * GNUTLS_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
,
268 * gnutls_ia_endphase_send:
269 * @session: is a #gnutls_session_t structure.
270 * @final_p: Set iff this should signal the final phase.
272 * Send a TLS/IA end phase message.
274 * In the client, this should only be used to acknowledge an end phase
275 * message sent by the server.
277 * In the server, this can be called instead of gnutls_ia_send() if
278 * the server wishes to end an application phase.
280 * Return value: Return 0 on success, or an error code.
283 gnutls_ia_endphase_send (gnutls_session_t session
, int final_p
)
285 opaque local_checksum
[CHECKSUM_SIZE
];
286 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
287 const char *label
= client
? client_finished_label
: server_finished_label
;
288 int size_of_label
= client
? sizeof (client_finished_label
) :
289 sizeof (server_finished_label
);
293 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
294 GNUTLS_MASTER_SIZE
, label
, size_of_label
- 1,
295 /* XXX specification unclear on seed. */
296 "", 0, CHECKSUM_SIZE
, local_checksum
);
300 len
= _gnutls_send_inner_application
302 final_p
? GNUTLS_IA_FINAL_PHASE_FINISHED
:
303 GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
, local_checksum
, CHECKSUM_SIZE
);
305 /* XXX Instead of calling this function over and over...?
306 * while (len == GNUTLS_E_AGAIN || len == GNUTLS_E_INTERRUPTED)
307 * len = _gnutls_io_write_flush(session);
320 * gnutls_ia_verify_endphase:
321 * @session: is a #gnutls_session_t structure.
322 * @checksum: 12-byte checksum data, received from gnutls_ia_recv().
324 * Verify TLS/IA end phase checksum data. If verification fails, the
325 * %GNUTLS_A_INNER_APPLICATION_VERIFICATION alert is sent to the other
328 * This function is called when gnutls_ia_recv() return
329 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
330 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED.
332 * Return value: Return 0 on successful verification, or an error
333 * code. If the checksum verification of the end phase message fails,
334 * %GNUTLS_E_IA_VERIFY_FAILED is returned.
337 gnutls_ia_verify_endphase (gnutls_session_t session
, const char *checksum
)
339 char local_checksum
[CHECKSUM_SIZE
];
340 int client
= session
->security_parameters
.entity
== GNUTLS_CLIENT
;
341 const char *label
= client
? server_finished_label
: client_finished_label
;
342 int size_of_label
= client
? sizeof (server_finished_label
) :
343 sizeof (client_finished_label
);
346 ret
= _gnutls_PRF (session
, session
->security_parameters
.inner_secret
,
348 label
, size_of_label
- 1,
349 "", 0, CHECKSUM_SIZE
, local_checksum
);
356 if (memcmp (local_checksum
, checksum
, CHECKSUM_SIZE
) != 0)
358 ret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
359 GNUTLS_A_INNER_APPLICATION_VERIFICATION
);
366 return GNUTLS_E_IA_VERIFY_FAILED
;
373 * gnutls_ia_send: Send peer the specified TLS/IA data.
374 * @session: is a #gnutls_session_t structure.
375 * @data: contains the data to send
376 * @sizeofdata: is the length of the data
378 * Send TLS/IA application payload data. This function has the
379 * similar semantics with send(). The only difference is that it
380 * accepts a GnuTLS session, and uses different error codes.
382 * The TLS/IA protocol is synchronous, so you cannot send more than
383 * one packet at a time. The client always send the first packet.
385 * To finish an application phase in the server, use
386 * gnutls_ia_endphase_send(). The client cannot end an application
387 * phase unilaterally; rather, a client is required to respond with an
388 * endphase of its own if gnutls_ia_recv indicates that the server has
391 * If the EINTR is returned by the internal push function (the default
392 * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
393 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must call
394 * this function again, with the same parameters; alternatively you
395 * could provide a %NULL pointer for data, and 0 for size.
397 * Returns: The number of bytes sent, or a negative error code.
400 gnutls_ia_send (gnutls_session_t session
, const char *data
, size_t sizeofdata
)
404 len
= _gnutls_send_inner_application (session
,
405 GNUTLS_IA_APPLICATION_PAYLOAD
,
412 * gnutls_ia_recv - read data from the TLS/IA protocol
413 * @session: is a #gnutls_session_t structure.
414 * @data: the buffer that the data will be read into, must hold >= 12 bytes.
415 * @sizeofdata: the number of requested bytes, must be >= 12.
417 * Receive TLS/IA data. This function has the similar semantics with
418 * recv(). The only difference is that it accepts a GnuTLS session,
419 * and uses different error codes.
421 * If the server attempt to finish an application phase, this function
422 * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
423 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke
424 * gnutls_ia_verify_endphase(), and if it runs the client side, also
425 * send an endphase message of its own using gnutls_ia_endphase_send.
427 * If EINTR is returned by the internal push function (the default is
428 * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If
429 * GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call
430 * this function again, with the same parameters; alternatively you
431 * could provide a NULL pointer for data, and 0 for size.
433 * Returns: The number of bytes received. A negative error code is
434 * returned in case of an error. The
435 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED and
436 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED errors are returned when an
437 * application phase finished message has been sent by the server.
440 gnutls_ia_recv (gnutls_session_t session
, char *data
, size_t sizeofdata
)
442 gnutls_ia_apptype_t msg_type
= 0;
445 len
= _gnutls_recv_inner_application (session
, &msg_type
, data
, sizeofdata
);
447 if (msg_type
== GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED
)
448 return GNUTLS_E_WARNING_IA_IPHF_RECEIVED
;
449 else if (msg_type
== GNUTLS_IA_FINAL_PHASE_FINISHED
)
450 return GNUTLS_E_WARNING_IA_FPHF_RECEIVED
;
455 /* XXX rewrite the following two functions as state machines, to
456 handle EAGAIN/EINTERRUPTED? just add more problems to callers,
460 _gnutls_ia_client_handshake (gnutls_session_t session
)
464 char tmp
[1024]; /* XXX */
467 const struct gnutls_ia_client_credentials_st
*cred
=
468 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
471 return GNUTLS_E_INTERNAL_ERROR
;
478 ret
= cred
->avp_func (session
, cred
->avp_ptr
,
479 buf
, buflen
, &avp
, &avplen
);
483 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
484 GNUTLS_A_INNER_APPLICATION_FAILURE
);
490 len
= gnutls_ia_send (session
, avp
, avplen
);
495 len
= gnutls_ia_recv (session
, tmp
, sizeof (tmp
));
496 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
497 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
499 ret
= gnutls_ia_verify_endphase (session
, tmp
);
503 ret
= gnutls_ia_endphase_send
504 (session
, len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
);
509 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
515 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
529 _gnutls_ia_server_handshake (gnutls_session_t session
)
531 gnutls_ia_apptype_t msg_type
;
535 const struct gnutls_ia_server_credentials_st
*cred
=
536 _gnutls_get_cred (session
->key
, GNUTLS_CRD_IA
, NULL
);
539 return GNUTLS_E_INTERNAL_ERROR
;
546 len
= gnutls_ia_recv (session
, buf
, sizeof (buf
));
547 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
||
548 len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
550 ret
= gnutls_ia_verify_endphase (session
, buf
);
555 if (len
== GNUTLS_E_WARNING_IA_IPHF_RECEIVED
)
557 else if (len
== GNUTLS_E_WARNING_IA_FPHF_RECEIVED
)
566 ret
= cred
->avp_func (session
, cred
->avp_ptr
, buf
, len
, &avp
, &avplen
);
570 tmpret
= gnutls_alert_send (session
, GNUTLS_AL_FATAL
,
571 GNUTLS_A_INNER_APPLICATION_FAILURE
);
579 if (msg_type
!= GNUTLS_IA_APPLICATION_PAYLOAD
)
581 ret
= gnutls_ia_endphase_send (session
, msg_type
==
582 GNUTLS_IA_FINAL_PHASE_FINISHED
);
588 len
= gnutls_ia_send (session
, avp
, avplen
);
600 * gnutls_ia_handshake_p:
601 * @session: is a #gnutls_session_t structure.
603 * Predicate to be used after gnutls_handshake() to decide whether to
604 * invoke gnutls_ia_handshake(). Usable by both clients and servers.
606 * Return value: non-zero if TLS/IA handshake is expected, zero
610 gnutls_ia_handshake_p (gnutls_session_t session
)
612 tls_ext_st
*ext
= &session
->security_parameters
.extensions
;
614 /* Either local side or peer doesn't do TLS/IA: don't do IA */
616 if (!ext
->gnutls_ia_enable
|| !ext
->gnutls_ia_peer_enable
)
619 /* Not resuming or we don't allow skipping on resumption locally: do IA */
621 if (!ext
->gnutls_ia_allowskip
|| !gnutls_session_is_resumed (session
))
624 /* If we're resuming and we and the peer both allow skipping on resumption:
627 return !ext
->gnutls_ia_peer_allowskip
;
632 * gnutls_ia_handshake:
633 * @session: is a #gnutls_session_t structure.
635 * Perform a TLS/IA handshake. This should be called after
636 * gnutls_handshake() iff gnutls_ia_handshake_p().
638 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
639 * otherwise an error code is returned.
642 gnutls_ia_handshake (gnutls_session_t session
)
646 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
647 ret
= _gnutls_ia_client_handshake (session
);
649 ret
= _gnutls_ia_server_handshake (session
);
655 * gnutls_ia_allocate_client_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
656 * @sc: is a pointer to a #gnutls_ia_server_credentials_t structure.
658 * This structure is complex enough to manipulate directly thus this
659 * helper function is provided in order to allocate it.
661 * Adding this credential to a session will enable TLS/IA, and will
662 * require an Application Phase after the TLS handshake (if the server
663 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
666 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
667 * an error code is returned.
670 gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t
* sc
)
672 *sc
= gnutls_calloc (1, sizeof (**sc
));
675 return GNUTLS_E_MEMORY_ERROR
;
681 * gnutls_ia_free_client_credentials - Used to free an allocated #gnutls_ia_client_credentials_t structure
682 * @sc: is a #gnutls_ia_client_credentials_t structure.
684 * This structure is complex enough to manipulate directly thus this
685 * helper function is provided in order to free (deallocate) it.
689 gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc
)
695 * gnutls_ia_set_client_avp_function - Used to set a AVP callback
696 * @cred: is a #gnutls_ia_client_credentials_t structure.
697 * @avp_func: is the callback function
699 * Set the TLS/IA AVP callback handler used for the session.
701 * The AVP callback is called to process AVPs received from the
702 * server, and to get a new AVP to send to the server.
704 * The callback's function form is:
705 * int (*avp_func) (gnutls_session_t session, void *ptr,
706 * const char *last, size_t lastlen,
707 * char **next, size_t *nextlen);
709 * The @session parameter is the #gnutls_session_t structure
710 * corresponding to the current session. The @ptr parameter is the
711 * application hook pointer, set through
712 * gnutls_ia_set_client_avp_ptr(). The AVP received from the server
713 * is present in @last of @lastlen size, which will be %NULL on the
714 * first invocation. The newly allocated output AVP to send to the
715 * server should be placed in *@next of *@nextlen size.
717 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
718 * generated session keys with the TLS/IA inner secret.
720 * Return 0 (%GNUTLS_IA_APPLICATION_PAYLOAD) on success, or a negative
721 * error code to abort the TLS/IA handshake.
723 * Note that the callback must use allocate the @next parameter using
724 * gnutls_malloc(), because it is released via gnutls_free() by the
725 * TLS/IA handshake function.
729 gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred
,
730 gnutls_ia_avp_func avp_func
)
732 cred
->avp_func
= avp_func
;
736 * gnutls_ia_set_client_avp_ptr - Sets a pointer to be sent to TLS/IA callback
737 * @cred: is a #gnutls_ia_client_credentials_t structure.
738 * @ptr: is the pointer
740 * Sets the pointer that will be provided to the TLS/IA callback
741 * function as the first argument.
744 gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred
, void *ptr
)
750 * gnutls_ia_get_client_avp_ptr - Returns the pointer which is sent to TLS/IA callback
751 * @cred: is a #gnutls_ia_client_credentials_t structure.
753 * Returns the pointer that will be provided to the TLS/IA callback
754 * function as the first argument.
756 * Returns: The client callback data pointer.
759 gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t cred
)
761 return cred
->avp_ptr
;
765 * gnutls_ia_allocate_server_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
766 * @sc: is a pointer to a #gnutls_ia_server_credentials_t structure.
768 * This structure is complex enough to manipulate directly thus this
769 * helper function is provided in order to allocate it.
771 * Adding this credential to a session will enable TLS/IA, and will
772 * require an Application Phase after the TLS handshake (if the client
773 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
776 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
777 * an error code is returned.
780 gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t
* sc
)
782 *sc
= gnutls_calloc (1, sizeof (**sc
));
785 return GNUTLS_E_MEMORY_ERROR
;
791 * gnutls_ia_free_server_credentials - Used to free an allocated #gnutls_ia_server_credentials_t structure
792 * @sc: is a #gnutls_ia_server_credentials_t structure.
794 * This structure is complex enough to manipulate directly thus this
795 * helper function is provided in order to free (deallocate) it.
799 gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc
)
805 * gnutls_ia_set_server_credentials_function - Used to set a AVP callback
806 * @cred: is a #gnutls_ia_server_credentials_t structure.
807 * @func: is the callback function
809 * Set the TLS/IA AVP callback handler used for the session.
811 * The callback's function form is:
812 * int (*avp_func) (gnutls_session_t session, void *ptr,
813 * const char *last, size_t lastlen,
814 * char **next, size_t *nextlen);
816 * The @session parameter is the #gnutls_session_t structure
817 * corresponding to the current session. The @ptr parameter is the
818 * application hook pointer, set through
819 * gnutls_ia_set_server_avp_ptr(). The AVP received from the client
820 * is present in @last of @lastlen size. The newly allocated output
821 * AVP to send to the client should be placed in *@next of *@nextlen
824 * The AVP callback is called to process incoming AVPs from the
825 * client, and to get a new AVP to send to the client. It can also be
826 * used to instruct the TLS/IA handshake to do go into the
827 * Intermediate or Final phases. It return a negative error code, or
828 * a #gnutls_ia_apptype_t message type.
830 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
831 * generated session keys with the TLS/IA inner secret.
833 * Specifically, return %GNUTLS_IA_APPLICATION_PAYLOAD (0) to send
834 * another AVP to the client, return
835 * %GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED (1) to indicate that an
836 * IntermediatePhaseFinished message should be sent, and return
837 * %GNUTLS_IA_FINAL_PHASE_FINISHED (2) to indicate that an
838 * FinalPhaseFinished message should be sent. In the last two cases,
839 * the contents of the @next and @nextlen parameter is not used.
841 * Note that the callback must use allocate the @next parameter using
842 * gnutls_malloc(), because it is released via gnutls_free() by the
843 * TLS/IA handshake function.
846 gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred
,
847 gnutls_ia_avp_func avp_func
)
849 cred
->avp_func
= avp_func
;
853 * gnutls_ia_set_server_avp_ptr - Sets a pointer to be sent to TLS/IA callback
854 * @cred: is a #gnutls_ia_client_credentials_t structure.
855 * @ptr: is the pointer
857 * Sets the pointer that will be provided to the TLS/IA callback
858 * function as the first argument.
861 gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred
, void *ptr
)
867 * gnutls_ia_get_server_avp_ptr - Returns the pointer which is sent to TLS/IA callback
868 * @cred: is a #gnutls_ia_client_credentials_t structure.
870 * Returns the pointer that will be provided to the TLS/IA callback
871 * function as the first argument.
873 * Returns: The server callback data pointer.
876 gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred
)
878 return cred
->avp_ptr
;
882 * gnutls_ia_enable - Indicate willingness for TLS/IA application phases
883 * @session: is a #gnutls_session_t structure.
884 * @allow_skip_on_resume: non-zero if local party allows to skip the
885 * TLS/IA application phases for a resumed session.
887 * Specify whether we must advertise support for the TLS/IA extension
888 * during the handshake.
890 * At the client side, we always advertise TLS/IA if gnutls_ia_enable
891 * was called before the handshake; at the server side, we also
892 * require that the client has advertised that it wants to run TLS/IA
893 * before including the advertisement, as required by the protocol.
895 * Similarly, at the client side we always advertise that we allow
896 * TLS/IA to be skipped for resumed sessions if @allow_skip_on_resume
897 * is non-zero; at the server side, we also require that the session
898 * is indeed resumable and that the client has also advertised that it
899 * allows TLS/IA to be skipped for resumed sessions.
901 * After the TLS handshake, call gnutls_ia_handshake_p() to find out
902 * whether both parties agreed to do a TLS/IA handshake, before
903 * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_*
907 gnutls_ia_enable (gnutls_session_t session
, int allow_skip_on_resume
)
909 session
->security_parameters
.extensions
.gnutls_ia_enable
= 1;
910 session
->security_parameters
.extensions
.gnutls_ia_allowskip
=
911 allow_skip_on_resume
;