Imported Upstream version 3.3.5
[platform/upstream/gnutls.git] / lib / gnutls_state.c
1 /*
2  * Copyright (C) 2002-2013 Free Software Foundation, Inc.
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of GnuTLS.
7  *
8  * The GnuTLS is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library 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  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>
20  *
21  */
22
23 /* Functions to manipulate the session (gnutls_int.h), and some other stuff
24  * are included here. The file's name is traditionally gnutls_state even if the
25  * state has been renamed to session.
26  */
27
28 #include <gnutls_int.h>
29 #include <gnutls_errors.h>
30 #include <gnutls_auth.h>
31 #include <gnutls_num.h>
32 #include <gnutls_datum.h>
33 #include <gnutls_db.h>
34 #include <gnutls_record.h>
35 #include <gnutls_handshake.h>
36 #include <gnutls_dh.h>
37 #include <gnutls_buffers.h>
38 #include <gnutls_mbuffers.h>
39 #include <gnutls_state.h>
40 #include <gnutls_constate.h>
41 #include <auth/cert.h>
42 #include <auth/anon.h>
43 #include <auth/psk.h>
44 #include <algorithms.h>
45 #include <gnutls_extensions.h>
46 #include <system.h>
47 #include <random.h>
48 #include <fips.h>
49 #include <gnutls/dtls.h>
50
51 /* These should really be static, but src/tests.c calls them.  Make
52    them public functions?  */
53 void
54 _gnutls_rsa_pms_set_version(gnutls_session_t session,
55                             unsigned char major, unsigned char minor);
56
57 void
58 _gnutls_session_cert_type_set(gnutls_session_t session,
59                               gnutls_certificate_type_t ct)
60 {
61         _gnutls_handshake_log
62             ("HSK[%p]: Selected certificate type %s (%d)\n", session,
63              gnutls_certificate_type_get_name(ct), ct);
64         session->security_parameters.cert_type = ct;
65 }
66
67 void
68 _gnutls_session_ecc_curve_set(gnutls_session_t session,
69                               gnutls_ecc_curve_t c)
70 {
71         _gnutls_handshake_log("HSK[%p]: Selected ECC curve %s (%d)\n",
72                               session, gnutls_ecc_curve_get_name(c), c);
73         session->security_parameters.ecc_curve = c;
74 }
75
76 /**
77  * gnutls_cipher_get:
78  * @session: is a #gnutls_session_t structure.
79  *
80  * Get currently used cipher.
81  *
82  * Returns: the currently used cipher, a #gnutls_cipher_algorithm_t
83  *   type.
84  **/
85 gnutls_cipher_algorithm_t gnutls_cipher_get(gnutls_session_t session)
86 {
87         record_parameters_st *record_params;
88         int ret;
89
90         ret =
91             _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
92         if (ret < 0)
93                 return gnutls_assert_val(GNUTLS_CIPHER_NULL);
94
95         return record_params->cipher->id;
96 }
97
98 /**
99  * gnutls_certificate_type_get:
100  * @session: is a #gnutls_session_t structure.
101  *
102  * The certificate type is by default X.509, unless it is negotiated
103  * as a TLS extension.
104  *
105  * Returns: the currently used #gnutls_certificate_type_t certificate
106  *   type.
107  **/
108 gnutls_certificate_type_t
109 gnutls_certificate_type_get(gnutls_session_t session)
110 {
111         return session->security_parameters.cert_type;
112 }
113
114 /**
115  * gnutls_kx_get:
116  * @session: is a #gnutls_session_t structure.
117  *
118  * Get currently used key exchange algorithm.
119  *
120  * Returns: the key exchange algorithm used in the last handshake, a
121  *   #gnutls_kx_algorithm_t value.
122  **/
123 gnutls_kx_algorithm_t gnutls_kx_get(gnutls_session_t session)
124 {
125         return session->security_parameters.kx_algorithm;
126 }
127
128 /**
129  * gnutls_mac_get:
130  * @session: is a #gnutls_session_t structure.
131  *
132  * Get currently used MAC algorithm.
133  *
134  * Returns: the currently used mac algorithm, a
135  *   #gnutls_mac_algorithm_t value.
136  **/
137 gnutls_mac_algorithm_t gnutls_mac_get(gnutls_session_t session)
138 {
139         record_parameters_st *record_params;
140         int ret;
141
142         ret =
143             _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
144         if (ret < 0)
145                 return gnutls_assert_val(GNUTLS_MAC_NULL);
146
147         return record_params->mac->id;
148 }
149
150 /**
151  * gnutls_compression_get:
152  * @session: is a #gnutls_session_t structure.
153  *
154  * Get currently used compression algorithm.
155  *
156  * Returns: the currently used compression method, a
157  *   #gnutls_compression_method_t value.
158  **/
159 gnutls_compression_method_t
160 gnutls_compression_get(gnutls_session_t session)
161 {
162         record_parameters_st *record_params;
163         int ret;
164
165         ret =
166             _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
167         if (ret < 0)
168                 return gnutls_assert_val(GNUTLS_COMP_NULL);
169
170         return record_params->compression_algorithm;
171 }
172
173 /* Check if the given certificate type is supported.
174  * This means that it is enabled by the priority functions,
175  * and a matching certificate exists.
176  */
177 int
178 _gnutls_session_cert_type_supported(gnutls_session_t session,
179                                     gnutls_certificate_type_t cert_type)
180 {
181         unsigned i;
182         unsigned cert_found = 0;
183         gnutls_certificate_credentials_t cred;
184
185         if (session->security_parameters.entity == GNUTLS_SERVER) {
186                 cred = (gnutls_certificate_credentials_t)
187                     _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
188
189                 if (cred == NULL)
190                         return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
191
192                 if (cred->server_get_cert_callback == NULL
193                     && cred->get_cert_callback == NULL) {
194                         for (i = 0; i < cred->ncerts; i++) {
195                                 if (cred->certs[i].cert_list[0].type ==
196                                     cert_type) {
197                                         cert_found = 1;
198                                         break;
199                                 }
200                         }
201
202                         if (cert_found == 0)
203                                 /* no certificate is of that type.
204                                  */
205                                 return
206                                     GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
207                 }
208         }
209
210         if (session->internals.priorities.cert_type.algorithms == 0
211             && cert_type == DEFAULT_CERT_TYPE)
212                 return 0;
213
214         for (i = 0; i < session->internals.priorities.cert_type.algorithms;
215              i++) {
216                 if (session->internals.priorities.cert_type.priority[i] ==
217                     cert_type) {
218                         return 0;       /* ok */
219                 }
220         }
221
222         return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
223 }
224
225
226 /* this function deinitializes all the internal parameters stored
227  * in a session struct.
228  */
229 inline static void deinit_internal_params(gnutls_session_t session)
230 {
231 #if defined(ENABLE_DHE) || defined(ENABLE_ANON)
232         if (session->internals.params.free_dh_params)
233                 gnutls_dh_params_deinit(session->internals.params.
234                                         dh_params);
235 #endif
236
237         _gnutls_handshake_hash_buffers_clear(session);
238
239         memset(&session->internals.params, 0,
240                sizeof(session->internals.params));
241 }
242
243 /* This function will clear all the variables in internals
244  * structure within the session, which depend on the current handshake.
245  * This is used to allow further handshakes.
246  */
247 static void _gnutls_handshake_internal_state_init(gnutls_session_t session)
248 {
249         session->internals.extensions_sent_size = 0;
250
251         /* by default no selected certificate */
252         session->internals.adv_version_major = 0;
253         session->internals.adv_version_minor = 0;
254         session->internals.direction = 0;
255
256         /* use out of band data for the last
257          * handshake messages received.
258          */
259         session->internals.last_handshake_in = -1;
260         session->internals.last_handshake_out = -1;
261
262         session->internals.resumable = RESUME_TRUE;
263
264         session->internals.dtls.hsk_read_seq = 0;
265         session->internals.dtls.hsk_write_seq = 0;
266 }
267
268 void _gnutls_handshake_internal_state_clear(gnutls_session_t session)
269 {
270         _gnutls_handshake_internal_state_init(session);
271
272         deinit_internal_params(session);
273
274         _gnutls_epoch_gc(session);
275
276         session->internals.handshake_endtime = 0;
277 }
278
279 /**
280  * gnutls_init:
281  * @session: is a pointer to a #gnutls_session_t structure.
282  * @flags: indicate if this session is to be used for server or client.
283  *
284  * This function initializes the current session to null. Every
285  * session must be initialized before use, so internal structures can
286  * be allocated.  This function allocates structures which can only
287  * be free'd by calling gnutls_deinit().  Returns %GNUTLS_E_SUCCESS (0) on success.
288  *
289  * @flags can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER. For a DTLS
290  * entity, the flags %GNUTLS_DATAGRAM and  %GNUTLS_NONBLOCK are
291  * also available. The latter flag will enable a non-blocking
292  * operation of the DTLS timers. 
293  *
294  * The flag %GNUTLS_NO_REPLAY_PROTECTION will disable any 
295  * replay protection in DTLS mode. That must only used when 
296  * replay protection is achieved using other means.
297  *
298  * Note that since version 3.1.2 this function enables some common
299  * TLS extensions such as session tickets and OCSP certificate status
300  * request in client side by default. To prevent that use the %GNUTLS_NO_EXTENSIONS
301  * flag.
302  *
303  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
304  **/
305 int gnutls_init(gnutls_session_t * session, unsigned int flags)
306 {
307         int ret;
308         record_parameters_st *epoch;
309         
310         FAIL_IF_LIB_ERROR;
311
312         *session = gnutls_calloc(1, sizeof(struct gnutls_session_int));
313         if (*session == NULL)
314                 return GNUTLS_E_MEMORY_ERROR;
315
316         ret = _gnutls_epoch_alloc(*session, 0, &epoch);
317         if (ret < 0) {
318                 gnutls_assert();
319                 return GNUTLS_E_MEMORY_ERROR;
320         }
321
322         /* Set all NULL algos on epoch 0 */
323         _gnutls_epoch_set_null_algos(*session, epoch);
324
325         (*session)->security_parameters.epoch_next = 1;
326
327         (*session)->security_parameters.entity =
328             (flags & GNUTLS_SERVER ? GNUTLS_SERVER : GNUTLS_CLIENT);
329
330         /* the default certificate type for TLS */
331         (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
332
333         /* Initialize buffers */
334         _gnutls_buffer_init(&(*session)->internals.handshake_hash_buffer);
335         _gnutls_buffer_init(&(*session)->internals.hb_remote_data);
336         _gnutls_buffer_init(&(*session)->internals.hb_local_data);
337         _gnutls_buffer_init(&(*session)->internals.record_presend_buffer);
338
339         _mbuffer_head_init(&(*session)->internals.record_buffer);
340         _mbuffer_head_init(&(*session)->internals.record_send_buffer);
341         _mbuffer_head_init(&(*session)->internals.record_recv_buffer);
342
343         _mbuffer_head_init(&(*session)->internals.handshake_send_buffer);
344         _gnutls_handshake_recv_buffer_init(*session);
345
346         (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME;        /* one hour default */
347
348         gnutls_handshake_set_max_packet_length((*session),
349                                                MAX_HANDSHAKE_PACKET_SIZE);
350
351         /* set the socket pointers to -1;
352          */
353         (*session)->internals.transport_recv_ptr =
354             (gnutls_transport_ptr_t) - 1;
355         (*session)->internals.transport_send_ptr =
356             (gnutls_transport_ptr_t) - 1;
357
358         /* set the default maximum record size for TLS
359          */
360         (*session)->security_parameters.max_record_recv_size =
361             DEFAULT_MAX_RECORD_SIZE;
362         (*session)->security_parameters.max_record_send_size =
363             DEFAULT_MAX_RECORD_SIZE;
364
365         /* everything else not initialized here is initialized
366          * as NULL or 0. This is why calloc is used.
367          */
368
369         _gnutls_handshake_internal_state_init(*session);
370
371         /* emulate old gnutls behavior for old applications that do not use the priority_*
372          * functions.
373          */
374         (*session)->internals.priorities.sr = SR_PARTIAL;
375
376 #ifdef HAVE_WRITEV
377         gnutls_transport_set_vec_push_function(*session, system_writev);
378 #else
379         gnutls_transport_set_push_function(*session, system_write);
380 #endif
381         gnutls_transport_set_pull_function(*session, system_read);
382         gnutls_transport_set_errno_function(*session, system_errno);
383         gnutls_transport_set_pull_timeout_function(*session,
384                                                    system_recv_timeout);
385
386         (*session)->internals.hb_retrans_timeout_ms = 1000;
387         (*session)->internals.hb_total_timeout_ms = 60000;
388
389         if (flags & GNUTLS_DATAGRAM) {
390                 (*session)->internals.dtls.mtu = DTLS_DEFAULT_MTU;
391                 (*session)->internals.transport = GNUTLS_DGRAM;
392
393                 (*session)->internals.dtls.retrans_timeout_ms = 1000;
394                 (*session)->internals.dtls.total_timeout_ms = 60000;
395         } else
396                 (*session)->internals.transport = GNUTLS_STREAM;
397
398         if (flags & GNUTLS_NONBLOCK)
399                 (*session)->internals.dtls.blocking = 0;
400         else
401                 (*session)->internals.dtls.blocking = 1;
402
403         /* Enable useful extensions */
404         if ((flags & GNUTLS_CLIENT) && !(flags & GNUTLS_NO_EXTENSIONS)) {
405 #ifdef ENABLE_SESSION_TICKETS
406                 gnutls_session_ticket_enable_client(*session);
407 #endif
408 #ifdef ENABLE_OCSP
409                 gnutls_ocsp_status_request_enable_client(*session, NULL, 0,
410                                                          NULL);
411 #endif
412         }
413
414         if (flags & GNUTLS_NO_REPLAY_PROTECTION)
415                 (*session)->internals.no_replay_protection = 1;
416
417         return 0;
418 }
419
420 /* returns RESUME_FALSE or RESUME_TRUE.
421  */
422 int _gnutls_session_is_resumable(gnutls_session_t session)
423 {
424         return session->internals.resumable;
425 }
426
427
428 /**
429  * gnutls_deinit:
430  * @session: is a #gnutls_session_t structure.
431  *
432  * This function clears all buffers associated with the @session.
433  * This function will also remove session data from the session
434  * database if the session was terminated abnormally.
435  **/
436 void gnutls_deinit(gnutls_session_t session)
437 {
438         unsigned int i;
439
440         if (session == NULL)
441                 return;
442
443         _gnutls_rnd_refresh();
444
445         /* remove auth info firstly */
446         _gnutls_free_auth_info(session);
447
448         _gnutls_handshake_internal_state_clear(session);
449         _gnutls_handshake_io_buffer_clear(session);
450         _gnutls_ext_free_session_data(session);
451
452         for (i = 0; i < MAX_EPOCH_INDEX; i++)
453                 if (session->record_parameters[i] != NULL) {
454                         _gnutls_epoch_free(session,
455                                            session->record_parameters[i]);
456                         session->record_parameters[i] = NULL;
457                 }
458
459         _gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
460         _gnutls_buffer_clear(&session->internals.hb_remote_data);
461         _gnutls_buffer_clear(&session->internals.hb_local_data);
462         _gnutls_buffer_clear(&session->internals.record_presend_buffer);
463
464         _mbuffer_head_clear(&session->internals.record_buffer);
465         _mbuffer_head_clear(&session->internals.record_recv_buffer);
466         _mbuffer_head_clear(&session->internals.record_send_buffer);
467
468         gnutls_credentials_clear(session);
469         _gnutls_selected_certs_deinit(session);
470
471         gnutls_pk_params_release(&session->key.ecdh_params);
472         gnutls_pk_params_release(&session->key.dh_params);
473         zrelease_temp_mpi_key(&session->key.ecdh_x);
474         zrelease_temp_mpi_key(&session->key.ecdh_y);
475
476         zrelease_temp_mpi_key(&session->key.client_Y);
477
478         zrelease_temp_mpi_key(&session->key.srp_p);
479         zrelease_temp_mpi_key(&session->key.srp_g);
480         zrelease_temp_mpi_key(&session->key.srp_key);
481
482         zrelease_temp_mpi_key(&session->key.u);
483         zrelease_temp_mpi_key(&session->key.a);
484         zrelease_temp_mpi_key(&session->key.x);
485         zrelease_temp_mpi_key(&session->key.A);
486         zrelease_temp_mpi_key(&session->key.B);
487         zrelease_temp_mpi_key(&session->key.b);
488
489         /* RSA */
490         zrelease_temp_mpi_key(&session->key.rsa[0]);
491         zrelease_temp_mpi_key(&session->key.rsa[1]);
492
493         _gnutls_free_temp_key_datum(&session->key.key);
494
495         gnutls_free(session);
496 }
497
498 /* Returns the minimum prime bits that are acceptable.
499  */
500 int _gnutls_dh_set_peer_public(gnutls_session_t session, bigint_t public)
501 {
502         dh_info_st *dh;
503         int ret;
504
505         switch (gnutls_auth_get_type(session)) {
506         case GNUTLS_CRD_ANON:
507                 {
508                         anon_auth_info_t info;
509                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
510                         if (info == NULL)
511                                 return GNUTLS_E_INTERNAL_ERROR;
512
513                         dh = &info->dh;
514                         break;
515                 }
516         case GNUTLS_CRD_PSK:
517                 {
518                         psk_auth_info_t info;
519                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
520                         if (info == NULL)
521                                 return GNUTLS_E_INTERNAL_ERROR;
522
523                         dh = &info->dh;
524                         break;
525                 }
526         case GNUTLS_CRD_CERTIFICATE:
527                 {
528                         cert_auth_info_t info;
529
530                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
531                         if (info == NULL)
532                                 return GNUTLS_E_INTERNAL_ERROR;
533
534                         dh = &info->dh;
535                         break;
536                 }
537         default:
538                 gnutls_assert();
539                 return GNUTLS_E_INTERNAL_ERROR;
540         }
541
542         if (dh->public_key.data)
543                 _gnutls_free_datum(&dh->public_key);
544
545         ret = _gnutls_mpi_dprint_lz(public, &dh->public_key);
546         if (ret < 0) {
547                 gnutls_assert();
548                 return ret;
549         }
550
551         return 0;
552 }
553
554 int _gnutls_dh_set_secret_bits(gnutls_session_t session, unsigned bits)
555 {
556         switch (gnutls_auth_get_type(session)) {
557         case GNUTLS_CRD_ANON:
558                 {
559                         anon_auth_info_t info;
560                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
561                         if (info == NULL)
562                                 return GNUTLS_E_INTERNAL_ERROR;
563                         info->dh.secret_bits = bits;
564                         break;
565                 }
566         case GNUTLS_CRD_PSK:
567                 {
568                         psk_auth_info_t info;
569                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
570                         if (info == NULL)
571                                 return GNUTLS_E_INTERNAL_ERROR;
572                         info->dh.secret_bits = bits;
573                         break;
574                 }
575         case GNUTLS_CRD_CERTIFICATE:
576                 {
577                         cert_auth_info_t info;
578
579                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
580                         if (info == NULL)
581                                 return GNUTLS_E_INTERNAL_ERROR;
582
583                         info->dh.secret_bits = bits;
584                         break;
585         default:
586                         gnutls_assert();
587                         return GNUTLS_E_INTERNAL_ERROR;
588                 }
589         }
590
591         return 0;
592 }
593
594 /* Sets the prime and the generator in the auth info structure.
595  */
596 int
597 _gnutls_dh_set_group(gnutls_session_t session, bigint_t gen,
598                      bigint_t prime)
599 {
600         dh_info_st *dh;
601         int ret;
602
603         switch (gnutls_auth_get_type(session)) {
604         case GNUTLS_CRD_ANON:
605                 {
606                         anon_auth_info_t info;
607                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
608                         if (info == NULL)
609                                 return GNUTLS_E_INTERNAL_ERROR;
610
611                         dh = &info->dh;
612                         break;
613                 }
614         case GNUTLS_CRD_PSK:
615                 {
616                         psk_auth_info_t info;
617                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
618                         if (info == NULL)
619                                 return GNUTLS_E_INTERNAL_ERROR;
620
621                         dh = &info->dh;
622                         break;
623                 }
624         case GNUTLS_CRD_CERTIFICATE:
625                 {
626                         cert_auth_info_t info;
627
628                         info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
629                         if (info == NULL)
630                                 return GNUTLS_E_INTERNAL_ERROR;
631
632                         dh = &info->dh;
633                         break;
634                 }
635         default:
636                 gnutls_assert();
637                 return GNUTLS_E_INTERNAL_ERROR;
638         }
639
640         if (dh->prime.data)
641                 _gnutls_free_datum(&dh->prime);
642
643         if (dh->generator.data)
644                 _gnutls_free_datum(&dh->generator);
645
646         /* prime
647          */
648         ret = _gnutls_mpi_dprint_lz(prime, &dh->prime);
649         if (ret < 0) {
650                 gnutls_assert();
651                 return ret;
652         }
653
654         /* generator
655          */
656         ret = _gnutls_mpi_dprint_lz(gen, &dh->generator);
657         if (ret < 0) {
658                 gnutls_assert();
659                 _gnutls_free_datum(&dh->prime);
660                 return ret;
661         }
662
663         return 0;
664 }
665
666 #ifdef ENABLE_OPENPGP
667 /**
668  * gnutls_openpgp_send_cert:
669  * @session: is a pointer to a #gnutls_session_t structure.
670  * @status: is one of GNUTLS_OPENPGP_CERT, or GNUTLS_OPENPGP_CERT_FINGERPRINT
671  *
672  * This function will order gnutls to send the key fingerprint
673  * instead of the key in the initial handshake procedure. This should
674  * be used with care and only when there is indication or knowledge
675  * that the server can obtain the client's key.
676  **/
677 void
678 gnutls_openpgp_send_cert(gnutls_session_t session,
679                          gnutls_openpgp_crt_status_t status)
680 {
681         session->internals.pgp_fingerprint = status;
682 }
683 #endif
684
685 /**
686  * gnutls_certificate_send_x509_rdn_sequence:
687  * @session: is a pointer to a #gnutls_session_t structure.
688  * @status: is 0 or 1
689  *
690  * If status is non zero, this function will order gnutls not to send
691  * the rdnSequence in the certificate request message. That is the
692  * server will not advertise its trusted CAs to the peer. If status
693  * is zero then the default behaviour will take effect, which is to
694  * advertise the server's trusted CAs.
695  *
696  * This function has no effect in clients, and in authentication
697  * methods other than certificate with X.509 certificates.
698  **/
699 void
700 gnutls_certificate_send_x509_rdn_sequence(gnutls_session_t session,
701                                           int status)
702 {
703         session->internals.ignore_rdn_sequence = status;
704 }
705
706 #ifdef ENABLE_OPENPGP
707 int _gnutls_openpgp_send_fingerprint(gnutls_session_t session)
708 {
709         return session->internals.pgp_fingerprint;
710 }
711 #endif
712
713 /*-
714  * _gnutls_record_set_default_version - Used to set the default version for the first record packet
715  * @session: is a #gnutls_session_t structure.
716  * @major: is a tls major version
717  * @minor: is a tls minor version
718  *
719  * This function sets the default version that we will use in the first
720  * record packet (client hello). This function is only useful to people
721  * that know TLS internals and want to debug other implementations.
722  -*/
723 void
724 _gnutls_record_set_default_version(gnutls_session_t session,
725                                    unsigned char major,
726                                    unsigned char minor)
727 {
728         session->internals.default_record_version[0] = major;
729         session->internals.default_record_version[1] = minor;
730 }
731
732 /**
733  * gnutls_handshake_set_private_extensions:
734  * @session: is a #gnutls_session_t structure.
735  * @allow: is an integer (0 or 1)
736  *
737  * This function will enable or disable the use of private cipher
738  * suites (the ones that start with 0xFF).  By default or if @allow
739  * is 0 then these cipher suites will not be advertised nor used.
740  *
741  * Currently GnuTLS does not include such cipher-suites or
742  * compression algorithms.
743  *
744  * Enabling the private ciphersuites when talking to other than
745  * gnutls servers and clients may cause interoperability problems.
746  **/
747 void
748 gnutls_handshake_set_private_extensions(gnutls_session_t session,
749                                         int allow)
750 {
751         session->internals.enable_private = allow;
752 }
753
754 inline static int
755 _gnutls_cal_PRF_A(const mac_entry_st * me,
756                   const void *secret, int secret_size,
757                   const void *seed, int seed_size, void *result)
758 {
759         int ret;
760
761         ret =
762             _gnutls_mac_fast(me->id, secret, secret_size, seed, seed_size,
763                              result);
764         if (ret < 0)
765                 return gnutls_assert_val(ret);
766
767         return 0;
768 }
769
770 #define MAX_SEED_SIZE 200
771
772 /* Produces "total_bytes" bytes using the hash algorithm specified.
773  * (used in the PRF function)
774  */
775 static int
776 P_hash(gnutls_mac_algorithm_t algorithm,
777        const uint8_t * secret, int secret_size,
778        const uint8_t * seed, int seed_size, int total_bytes, uint8_t * ret)
779 {
780
781         mac_hd_st td2;
782         int i, times, how, blocksize, A_size;
783         uint8_t final[MAX_HASH_SIZE], Atmp[MAX_SEED_SIZE];
784         int output_bytes, result;
785         const mac_entry_st *me = mac_to_entry(algorithm);
786
787         blocksize = _gnutls_mac_get_algo_len(me);
788
789         if (seed_size > MAX_SEED_SIZE || total_bytes <= 0 || blocksize == 0) {
790                 gnutls_assert();
791                 return GNUTLS_E_INTERNAL_ERROR;
792         }
793
794         output_bytes = 0;
795         do {
796                 output_bytes += blocksize;
797         }
798         while (output_bytes < total_bytes);
799
800         /* calculate A(0) */
801
802         memcpy(Atmp, seed, seed_size);
803         A_size = seed_size;
804
805         times = output_bytes / blocksize;
806
807         for (i = 0; i < times; i++) {
808                 result = _gnutls_mac_init(&td2, me, secret, secret_size);
809                 if (result < 0) {
810                         gnutls_assert();
811                         return result;
812                 }
813
814                 /* here we calculate A(i+1) */
815                 if ((result =
816                      _gnutls_cal_PRF_A(me, secret, secret_size, Atmp,
817                                        A_size, Atmp)) < 0) {
818                         gnutls_assert();
819                         _gnutls_mac_deinit(&td2, final);
820                         return result;
821                 }
822
823                 A_size = blocksize;
824
825                 _gnutls_mac(&td2, Atmp, A_size);
826                 _gnutls_mac(&td2, seed, seed_size);
827                 _gnutls_mac_deinit(&td2, final);
828
829                 if ((1 + i) * blocksize < total_bytes) {
830                         how = blocksize;
831                 } else {
832                         how = total_bytes - (i) * blocksize;
833                 }
834
835                 if (how > 0) {
836                         memcpy(&ret[i * blocksize], final, how);
837                 }
838         }
839
840         return 0;
841 }
842
843 #define MAX_PRF_BYTES 200
844
845 /* The PRF function expands a given secret 
846  * needed by the TLS specification. ret must have a least total_bytes
847  * available.
848  */
849 int
850 _gnutls_PRF(gnutls_session_t session,
851             const uint8_t * secret, unsigned int secret_size,
852             const char *label, int label_size, const uint8_t * seed,
853             int seed_size, int total_bytes, void *ret)
854 {
855         int l_s, s_seed_size;
856         const uint8_t *s1, *s2;
857         uint8_t s_seed[MAX_SEED_SIZE];
858         uint8_t o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES];
859         int result;
860         const version_entry_st *ver = get_version(session);
861
862         if (total_bytes > MAX_PRF_BYTES) {
863                 gnutls_assert();
864                 return GNUTLS_E_INTERNAL_ERROR;
865         }
866         /* label+seed = s_seed */
867         s_seed_size = seed_size + label_size;
868
869         if (s_seed_size > MAX_SEED_SIZE) {
870                 gnutls_assert();
871                 return GNUTLS_E_INTERNAL_ERROR;
872         }
873
874         memcpy(s_seed, label, label_size);
875         memcpy(&s_seed[label_size], seed, seed_size);
876
877         if (_gnutls_version_has_selectable_prf(ver)) {
878                 result =
879                     P_hash(_gnutls_cipher_suite_get_prf
880                            (session->security_parameters.cipher_suite),
881                            secret, secret_size, s_seed, s_seed_size,
882                            total_bytes, ret);
883                 if (result < 0) {
884                         gnutls_assert();
885                         return result;
886                 }
887         } else {
888                 l_s = secret_size / 2;
889
890                 s1 = &secret[0];
891                 s2 = &secret[l_s];
892
893                 if (secret_size % 2 != 0) {
894                         l_s++;
895                 }
896
897                 result =
898                     P_hash(GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
899                            total_bytes, o1);
900                 if (result < 0) {
901                         gnutls_assert();
902                         return result;
903                 }
904
905                 result =
906                     P_hash(GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
907                            total_bytes, o2);
908                 if (result < 0) {
909                         gnutls_assert();
910                         return result;
911                 }
912
913                 memxor(o1, o2, total_bytes);
914
915                 memcpy(ret, o1, total_bytes);
916         }
917
918         return 0;               /* ok */
919
920 }
921
922 /**
923  * gnutls_prf_raw:
924  * @session: is a #gnutls_session_t structure.
925  * @label_size: length of the @label variable.
926  * @label: label used in PRF computation, typically a short string.
927  * @seed_size: length of the @seed variable.
928  * @seed: optional extra data to seed the PRF with.
929  * @outsize: size of pre-allocated output buffer to hold the output.
930  * @out: pre-allocated buffer to hold the generated data.
931  *
932  * Apply the TLS Pseudo-Random-Function (PRF) on the master secret
933  * and the provided data.
934  *
935  * The @label variable usually contains a string denoting the purpose
936  * for the generated data.  The @seed usually contains data such as the
937  * client and server random, perhaps together with some additional
938  * data that is added to guarantee uniqueness of the output for a
939  * particular purpose.
940  *
941  * Because the output is not guaranteed to be unique for a particular
942  * session unless @seed includes the client random and server random
943  * fields (the PRF would output the same data on another connection
944  * resumed from the first one), it is not recommended to use this
945  * function directly.  The gnutls_prf() function seeds the PRF with the
946  * client and server random fields directly, and is recommended if you
947  * want to generate pseudo random data unique for each session.
948  *
949  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
950  **/
951 int
952 gnutls_prf_raw(gnutls_session_t session,
953                size_t label_size,
954                const char *label,
955                size_t seed_size, const char *seed, size_t outsize,
956                char *out)
957 {
958         int ret;
959
960         ret = _gnutls_PRF(session,
961                           session->security_parameters.master_secret,
962                           GNUTLS_MASTER_SIZE,
963                           label,
964                           label_size, (uint8_t *) seed, seed_size, outsize,
965                           out);
966
967         return ret;
968 }
969
970 /**
971  * gnutls_prf:
972  * @session: is a #gnutls_session_t structure.
973  * @label_size: length of the @label variable.
974  * @label: label used in PRF computation, typically a short string.
975  * @server_random_first: non-0 if server random field should be first in seed
976  * @extra_size: length of the @extra variable.
977  * @extra: optional extra data to seed the PRF with.
978  * @outsize: size of pre-allocated output buffer to hold the output.
979  * @out: pre-allocated buffer to hold the generated data.
980  *
981  * Applies the TLS Pseudo-Random-Function (PRF) on the master secret
982  * and the provided data, seeded with the client and server random fields,
983  * as specified in RFC5705.
984  *
985  * The @label variable usually contains a string denoting the purpose
986  * for the generated data.  The @server_random_first indicates whether
987  * the client random field or the server random field should be first
988  * in the seed.  Non-0 indicates that the server random field is first,
989  * 0 that the client random field is first.
990  *
991  * The @extra variable can be used to add more data to the seed, after
992  * the random variables.  It can be used to make sure the
993  * generated output is strongly connected to some additional data
994  * (e.g., a string used in user authentication).
995  *
996  * The output is placed in @out, which must be pre-allocated.
997  *
998  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
999  **/
1000 int
1001 gnutls_prf(gnutls_session_t session,
1002            size_t label_size,
1003            const char *label,
1004            int server_random_first,
1005            size_t extra_size, const char *extra, size_t outsize, char *out)
1006 {
1007         int ret;
1008         uint8_t *seed;
1009         size_t seedsize = 2 * GNUTLS_RANDOM_SIZE + extra_size;
1010
1011         seed = gnutls_malloc(seedsize);
1012         if (!seed) {
1013                 gnutls_assert();
1014                 return GNUTLS_E_MEMORY_ERROR;
1015         }
1016
1017         memcpy(seed, server_random_first ?
1018                session->security_parameters.server_random :
1019                session->security_parameters.client_random,
1020                GNUTLS_RANDOM_SIZE);
1021         memcpy(seed + GNUTLS_RANDOM_SIZE,
1022                server_random_first ? session->security_parameters.
1023                client_random : session->security_parameters.server_random,
1024                GNUTLS_RANDOM_SIZE);
1025
1026         memcpy(seed + 2 * GNUTLS_RANDOM_SIZE, extra, extra_size);
1027
1028         ret =
1029             _gnutls_PRF(session,
1030                         session->security_parameters.master_secret,
1031                         GNUTLS_MASTER_SIZE, label, label_size, seed,
1032                         seedsize, outsize, out);
1033
1034         gnutls_free(seed);
1035
1036         return ret;
1037 }
1038
1039 /**
1040  * gnutls_session_is_resumed:
1041  * @session: is a #gnutls_session_t structure.
1042  *
1043  * Check whether session is resumed or not.
1044  *
1045  * Returns: non zero if this session is resumed, or a zero if this is
1046  *   a new session.
1047  **/
1048 int gnutls_session_is_resumed(gnutls_session_t session)
1049 {
1050         if (session->security_parameters.entity == GNUTLS_CLIENT) {
1051                 if (session->security_parameters.session_id_size > 0 &&
1052                     session->security_parameters.session_id_size ==
1053                     session->internals.resumed_security_parameters.
1054                     session_id_size
1055                     && memcmp(session->security_parameters.session_id,
1056                               session->
1057                               internals.resumed_security_parameters.
1058                               session_id,
1059                               session->security_parameters.
1060                               session_id_size) == 0)
1061                         return 1;
1062         } else {
1063                 if (session->internals.resumed != RESUME_FALSE)
1064                         return 1;
1065         }
1066
1067         return 0;
1068 }
1069
1070 /**
1071  * gnutls_session_resumption_requested:
1072  * @session: is a #gnutls_session_t structure.
1073  *
1074  * Check whether the client has asked for session resumption.
1075  * This function is valid only on server side.
1076  *
1077  * Returns: non zero if session resumption was asked, or a zero if not.
1078  **/
1079 int gnutls_session_resumption_requested(gnutls_session_t session)
1080 {
1081         if (session->security_parameters.entity == GNUTLS_CLIENT) {
1082                 return 0;
1083         } else {
1084                 return session->internals.resumption_requested;
1085         }
1086 }
1087
1088 /*-
1089  * _gnutls_session_is_psk - Used to check whether this session uses PSK kx
1090  * @session: is a #gnutls_session_t structure.
1091  *
1092  * This function will return non zero if this session uses a PSK key
1093  * exchange algorithm.
1094  -*/
1095 int _gnutls_session_is_psk(gnutls_session_t session)
1096 {
1097         gnutls_kx_algorithm_t kx;
1098
1099         kx = _gnutls_cipher_suite_get_kx_algo(session->security_parameters.
1100                                               cipher_suite);
1101         if (kx == GNUTLS_KX_PSK || kx == GNUTLS_KX_DHE_PSK
1102             || kx == GNUTLS_KX_RSA_PSK)
1103                 return 1;
1104
1105         return 0;
1106 }
1107
1108 /*-
1109  * _gnutls_session_is_ecc - Used to check whether this session uses ECC kx
1110  * @session: is a #gnutls_session_t structure.
1111  *
1112  * This function will return non zero if this session uses an elliptic
1113  * curves key exchange exchange algorithm.
1114  -*/
1115 int _gnutls_session_is_ecc(gnutls_session_t session)
1116 {
1117         gnutls_kx_algorithm_t kx;
1118
1119         /* We get the key exchange algorithm through the ciphersuite because
1120          * the negotiated key exchange might not have been set yet.
1121          */
1122         kx = _gnutls_cipher_suite_get_kx_algo(session->security_parameters.
1123                                               cipher_suite);
1124
1125         return _gnutls_kx_is_ecc(kx);
1126 }
1127
1128 /**
1129  * gnutls_session_get_ptr:
1130  * @session: is a #gnutls_session_t structure.
1131  *
1132  * Get user pointer for session.  Useful in callbacks.  This is the
1133  *   pointer set with gnutls_session_set_ptr().
1134  *
1135  * Returns: the user given pointer from the session structure, or
1136  *   %NULL if it was never set.
1137  **/
1138 void *gnutls_session_get_ptr(gnutls_session_t session)
1139 {
1140         return session->internals.user_ptr;
1141 }
1142
1143 /**
1144  * gnutls_session_set_ptr:
1145  * @session: is a #gnutls_session_t structure.
1146  * @ptr: is the user pointer
1147  *
1148  * This function will set (associate) the user given pointer @ptr to
1149  * the session structure.  This pointer can be accessed with
1150  * gnutls_session_get_ptr().
1151  **/
1152 void gnutls_session_set_ptr(gnutls_session_t session, void *ptr)
1153 {
1154         session->internals.user_ptr = ptr;
1155 }
1156
1157
1158 /**
1159  * gnutls_record_get_direction:
1160  * @session: is a #gnutls_session_t structure.
1161  *
1162  * This function provides information about the internals of the
1163  * record protocol and is only useful if a prior gnutls function call
1164  * (e.g.  gnutls_handshake()) was interrupted for some reason, that
1165  * is, if a function returned %GNUTLS_E_INTERRUPTED or
1166  * %GNUTLS_E_AGAIN.  In such a case, you might want to call select()
1167  * or poll() before calling the interrupted gnutls function again.  To
1168  * tell you whether a file descriptor should be selected for either
1169  * reading or writing, gnutls_record_get_direction() returns 0 if the
1170  * interrupted function was trying to read data, and 1 if it was
1171  * trying to write data.
1172  *
1173  * Returns: 0 if trying to read data, 1 if trying to write data.
1174  **/
1175 int gnutls_record_get_direction(gnutls_session_t session)
1176 {
1177         return session->internals.direction;
1178 }
1179
1180 /*-
1181  * _gnutls_rsa_pms_set_version - Sets a version to be used at the RSA PMS
1182  * @session: is a #gnutls_session_t structure.
1183  * @major: is the major version to use
1184  * @minor: is the minor version to use
1185  *
1186  * This function will set the given version number to be used at the
1187  * RSA PMS secret. This is only useful to clients, which want to
1188  * test server's capabilities.
1189  -*/
1190 void
1191 _gnutls_rsa_pms_set_version(gnutls_session_t session,
1192                             unsigned char major, unsigned char minor)
1193 {
1194         session->internals.rsa_pms_version[0] = major;
1195         session->internals.rsa_pms_version[1] = minor;
1196 }
1197
1198 /**
1199  * gnutls_handshake_set_post_client_hello_function:
1200  * @session: is a #gnutls_session_t structure.
1201  * @func: is the function to be called
1202  *
1203  * This function will set a callback to be called after the client
1204  * hello has been received (callback valid in server side only). This
1205  * allows the server to adjust settings based on received extensions.
1206  *
1207  * Those settings could be ciphersuites, requesting certificate, or
1208  * anything else except for version negotiation (this is done before
1209  * the hello message is parsed).
1210  *
1211  * This callback must return 0 on success or a gnutls error code to
1212  * terminate the handshake.
1213  *
1214  * Since GnuTLS 3.3.5 the callback is
1215  * allowed to return %GNUTLS_E_AGAIN or %GNUTLS_E_INTERRUPTED to
1216  * put the handshake on hold. In that case gnutls_handshake()
1217  * will return %GNUTLS_E_INTERRUPTED and can be resumed when needed.
1218  *
1219  * Warning: You should not use this function to terminate the
1220  * handshake based on client input unless you know what you are
1221  * doing. Before the handshake is finished there is no way to know if
1222  * there is a man-in-the-middle attack being performed.
1223  **/
1224 void
1225 gnutls_handshake_set_post_client_hello_function(gnutls_session_t session,
1226                                                 gnutls_handshake_post_client_hello_func
1227                                                 func)
1228 {
1229         session->internals.user_hello_func = func;
1230 }
1231
1232
1233 /**
1234  * gnutls_session_enable_compatibility_mode:
1235  * @session: is a #gnutls_session_t structure.
1236  *
1237  * This function can be used to disable certain (security) features in
1238  * TLS in order to maintain maximum compatibility with buggy
1239  * clients. Because several trade-offs with security are enabled,
1240  * if required they will be reported through the audit subsystem.
1241  *
1242  * Normally only servers that require maximum compatibility with
1243  * everything out there, need to call this function.
1244  *
1245  * Note that this function must be called after any call to gnutls_priority
1246  * functions.
1247  **/
1248 void gnutls_session_enable_compatibility_mode(gnutls_session_t session)
1249 {
1250         ENABLE_COMPAT(&session->internals.priorities);
1251 }
1252
1253 /**
1254  * gnutls_session_channel_binding:
1255  * @session: is a #gnutls_session_t structure.
1256  * @cbtype: an #gnutls_channel_binding_t enumeration type
1257  * @cb: output buffer array with data
1258  *
1259  * Extract given channel binding data of the @cbtype (e.g.,
1260  * %GNUTLS_CB_TLS_UNIQUE) type.
1261  *
1262  * Returns: %GNUTLS_E_SUCCESS on success,
1263  * %GNUTLS_E_UNIMPLEMENTED_FEATURE if the @cbtype is unsupported,
1264  * %GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE if the data is not
1265  * currently available, or an error code.
1266  *
1267  * Since: 2.12.0
1268  **/
1269 int
1270 gnutls_session_channel_binding(gnutls_session_t session,
1271                                gnutls_channel_binding_t cbtype,
1272                                gnutls_datum_t * cb)
1273 {
1274         if (cbtype != GNUTLS_CB_TLS_UNIQUE)
1275                 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1276
1277         if (!session->internals.initial_negotiation_completed)
1278                 return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
1279
1280         cb->size = session->internals.cb_tls_unique_len;
1281         cb->data = gnutls_malloc(cb->size);
1282         if (cb->data == NULL)
1283                 return GNUTLS_E_MEMORY_ERROR;
1284
1285         memcpy(cb->data, session->internals.cb_tls_unique, cb->size);
1286
1287         return 0;
1288 }
1289
1290 /**
1291  * gnutls_ecc_curve_get:
1292  * @session: is a #gnutls_session_t structure.
1293  *
1294  * Returns the currently used elliptic curve. Only valid
1295  * when using an elliptic curve ciphersuite.
1296  *
1297  * Returns: the currently used curve, a #gnutls_ecc_curve_t
1298  *   type.
1299  *
1300  * Since: 3.0
1301  **/
1302 gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session)
1303 {
1304         return _gnutls_session_ecc_curve_get(session);
1305 }
1306
1307 /**
1308  * gnutls_protocol_get_version:
1309  * @session: is a #gnutls_session_t structure.
1310  *
1311  * Get TLS version, a #gnutls_protocol_t value.
1312  *
1313  * Returns: The version of the currently used protocol.
1314  **/
1315 gnutls_protocol_t gnutls_protocol_get_version(gnutls_session_t session)
1316 {
1317         return get_num_version(session);
1318 }
1319
1320 /**
1321  * gnutls_session_get_random:
1322  * @session: is a #gnutls_session_t structure.
1323  * @client: the client part of the random
1324  * @server: the server part of the random
1325  *
1326  * This function returns pointers to the client and server
1327  * random fields used in the TLS handshake. The pointers are
1328  * not to be modified or deallocated.
1329  *
1330  * If a client random value has not yet been established, the output
1331  * will be garbage.
1332  *
1333  * Since: 3.0
1334  **/
1335 void
1336 gnutls_session_get_random(gnutls_session_t session,
1337                           gnutls_datum_t * client, gnutls_datum_t * server)
1338 {
1339         if (client) {
1340                 client->data = session->security_parameters.client_random;
1341                 client->size =
1342                     sizeof(session->security_parameters.client_random);
1343         }
1344
1345         if (server) {
1346                 server->data = session->security_parameters.server_random;
1347                 server->size =
1348                     sizeof(session->security_parameters.server_random);
1349         }
1350 }
1351
1352 unsigned int timespec_sub_ms(struct timespec *a, struct timespec *b)
1353 {
1354         return (a->tv_sec * 1000 + a->tv_nsec / (1000 * 1000) -
1355                 (b->tv_sec * 1000 + b->tv_nsec / (1000 * 1000)));
1356 }
1357
1358 /**
1359  * gnutls_handshake_set_random:
1360  * @session: is a #gnutls_session_t structure.
1361  * @random: a random value of 32-bytes
1362  *
1363  * This function will explicitly set the server or client hello 
1364  * random value in the subsequent TLS handshake. The random value 
1365  * should be a 32-byte value.
1366  *
1367  * Note that this function should not normally be used as gnutls
1368  * will select automatically a random value for the handshake.
1369  *
1370  * This function should not be used when resuming a session.
1371  *
1372  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1373  *
1374  * Since 3.1.9
1375  **/
1376 int
1377 gnutls_handshake_set_random(gnutls_session_t session,
1378                             const gnutls_datum_t * random)
1379 {
1380         if (random->size != GNUTLS_RANDOM_SIZE)
1381                 return GNUTLS_E_INVALID_REQUEST;
1382
1383         session->internals.sc_random_set = 1;
1384         if (session->security_parameters.entity == GNUTLS_CLIENT)
1385                 memcpy(session->internals.resumed_security_parameters.
1386                        client_random, random->data, random->size);
1387         else
1388                 memcpy(session->internals.resumed_security_parameters.
1389                        server_random, random->data, random->size);
1390
1391         return 0;
1392 }
1393
1394 /**
1395  * gnutls_handshake_set_hook_function:
1396  * @session: is a #gnutls_session_t structure
1397  * @htype: the %gnutls_handshake_description_t of the message to hook at
1398  * @post: %GNUTLS_HOOK_* depending on when the hook function should be called
1399  * @func: is the function to be called
1400  *
1401  * This function will set a callback to be called after or before the specified
1402  * handshake message has been received or generated. This is a
1403  * generalization of gnutls_handshake_set_post_client_hello_function().
1404  *
1405  * To call the hook function prior to the message being sent/generated use
1406  * %GNUTLS_HOOK_PRE as @post parameter, %GNUTLS_HOOK_POST to call
1407  * after, and %GNUTLS_HOOK_BOTH for both cases.
1408  *
1409  * This callback must return 0 on success or a gnutls error code to
1410  * terminate the handshake.
1411  *
1412  * Note to hook at all handshake messages use an @htype of %GNUTLS_HANDSHAKE_ANY.
1413  *
1414  * Warning: You should not use this function to terminate the
1415  * handshake based on client input unless you know what you are
1416  * doing. Before the handshake is finished there is no way to know if
1417  * there is a man-in-the-middle attack being performed.
1418  **/
1419 void
1420 gnutls_handshake_set_hook_function(gnutls_session_t session,
1421                                    unsigned int htype,
1422                                    int post,
1423                                    gnutls_handshake_hook_func func)
1424 {
1425         session->internals.h_hook = func;
1426         session->internals.h_type = htype;
1427         session->internals.h_post = post;
1428 }