2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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 3 of
11 * the License, or (at your option) any later version.
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.
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/>
23 /* The certificate authentication functions which are needed in the handshake,
24 * and are common to RSA and DHE key exchange, are in this file.
27 #include <gnutls_int.h>
28 #include "gnutls_auth.h"
29 #include "gnutls_errors.h"
30 #include <auth/cert.h>
31 #include "gnutls_dh.h"
32 #include "gnutls_num.h"
34 #include "gnutls_datum.h"
35 #include "ext/signature.h"
36 #include <gnutls_pk.h>
37 #include <algorithms.h>
38 #include <gnutls_global.h>
39 #include <gnutls_record.h>
40 #include <gnutls_sig.h>
41 #include <gnutls_state.h>
42 #include <gnutls_pk.h>
43 #include <gnutls_x509.h>
44 #include <gnutls/abstract.h>
48 #include "openpgp/gnutls_openpgp.h"
50 static gnutls_privkey_t
alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
52 static gnutls_pcert_st
*alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
);
56 static gnutls_pcert_st
*alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
,
58 static gnutls_privkey_t
alloc_and_load_x509_key (gnutls_x509_privkey_t key
,
62 static gnutls_privkey_t
alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t
66 #define MAX_CLIENT_SIGN_ALGOS 3
67 #define CERTTYPE_SIZE (MAX_CLIENT_SIGN_ALGOS+1)
68 typedef enum CertificateSigType
69 { RSA_SIGN
= 1, DSA_SIGN
= 2, ECDSA_SIGN
= 64
72 /* Copies data from a internal certificate struct (gnutls_pcert_st) to
73 * exported certificate struct (cert_auth_info_t)
76 _gnutls_copy_certificate_auth_info (cert_auth_info_t info
, gnutls_pcert_st
* certs
, size_t ncerts
, /* openpgp only */
79 /* Copy peer's information to auth_info_t
84 if (info
->raw_certificate_list
!= NULL
)
86 for (j
= 0; j
< info
->ncerts
; j
++)
87 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
88 gnutls_free (info
->raw_certificate_list
);
93 info
->raw_certificate_list
= NULL
;
98 info
->raw_certificate_list
=
99 gnutls_calloc (ncerts
, sizeof (gnutls_datum_t
));
100 if (info
->raw_certificate_list
== NULL
)
103 return GNUTLS_E_MEMORY_ERROR
;
106 for (i
= 0; i
< ncerts
; i
++)
108 if (certs
[i
].cert
.size
> 0)
111 _gnutls_set_datum (&info
->raw_certificate_list
[i
],
112 certs
[i
].cert
.data
, certs
[i
].cert
.size
);
120 info
->ncerts
= ncerts
;
121 info
->cert_type
= certs
[0].type
;
123 #ifdef ENABLE_OPENPGP
124 if (certs
[0].type
== GNUTLS_CRT_OPENPGP
)
127 memcpy (info
->subkey_id
, keyid
, GNUTLS_OPENPGP_KEYID_SIZE
);
135 for (j
= 0; j
< i
; j
++)
136 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
138 gnutls_free (info
->raw_certificate_list
);
139 info
->raw_certificate_list
= NULL
;
147 /* returns 0 if the algo_to-check exists in the pk_algos list,
151 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t
*
152 pk_algos
, int pk_algos_length
,
153 gnutls_pk_algorithm_t algo_to_check
)
156 for (i
= 0; i
< pk_algos_length
; i
++)
158 if (algo_to_check
== pk_algos
[i
])
167 /* Returns the issuer's Distinguished name in odn, of the certificate
171 _gnutls_cert_get_issuer_dn (gnutls_pcert_st
* cert
, gnutls_datum_t
* odn
)
177 if ((result
= asn1_create_element
178 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn
)) != ASN1_SUCCESS
)
181 return _gnutls_asn2err (result
);
184 result
= asn1_der_decoding (&dn
, cert
->cert
.data
, cert
->cert
.size
, NULL
);
185 if (result
!= ASN1_SUCCESS
)
187 /* couldn't decode DER */
189 asn1_delete_structure (&dn
);
190 return _gnutls_asn2err (result
);
193 result
= asn1_der_decoding_startEnd (dn
, cert
->cert
.data
, cert
->cert
.size
,
194 "tbsCertificate.issuer", &start
, &end
);
196 if (result
!= ASN1_SUCCESS
)
198 /* couldn't decode DER */
200 asn1_delete_structure (&dn
);
201 return _gnutls_asn2err (result
);
203 asn1_delete_structure (&dn
);
205 len
= end
- start
+ 1;
208 odn
->data
= &cert
->cert
.data
[start
];
214 /* Locates the most appropriate x509 certificate using the
215 * given DN. If indx == -1 then no certificate was found.
217 * That is to guess which certificate to use, based on the
218 * CAs and sign algorithms supported by the peer server.
221 _find_x509_cert (const gnutls_certificate_credentials_t cred
,
222 uint8_t * _data
, size_t _data_size
,
223 const gnutls_pk_algorithm_t
* pk_algos
,
224 int pk_algos_length
, int *indx
)
227 gnutls_datum_t odn
= { NULL
, 0 };
228 uint8_t *data
= _data
;
229 ssize_t data_size
= _data_size
;
235 /* If peer doesn't send any issuers and we have a single certificate
236 * then send that one.
238 if (data_size
== 0 && cred
->ncerts
== 1)
246 DECR_LENGTH_RET (data_size
, 2, 0);
247 size
= _gnutls_read_uint16 (data
);
248 DECR_LENGTH_RET (data_size
, size
, 0);
251 for (i
= 0; i
< cred
->ncerts
; i
++)
253 for (j
= 0; j
< cred
->certs
[i
].cert_list_length
; j
++)
256 _gnutls_cert_get_issuer_dn (&cred
->certs
[i
].cert_list
[j
],
263 if (odn
.size
!= size
)
266 /* If the DN matches and
267 * the *_SIGN algorithm matches
268 * the cert is our cert!
271 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
274 if ((memcmp (odn
.data
, data
, size
) == 0) &&
275 (_gnutls_check_pk_algo_in_list
276 (pk_algos
, pk_algos_length
, cert_pk
) == 0))
289 /* move to next record */
298 #ifdef ENABLE_OPENPGP
299 /* Locates the most appropriate openpgp cert
302 _find_openpgp_cert (const gnutls_certificate_credentials_t cred
,
303 gnutls_pk_algorithm_t
* pk_algos
,
304 int pk_algos_length
, int *indx
)
310 for (i
= 0; i
< cred
->ncerts
; i
++)
312 for (j
= 0; j
< cred
->certs
[i
].cert_list_length
; j
++)
315 /* If the *_SIGN algorithm matches
316 * the cert is our cert!
318 if ((_gnutls_check_pk_algo_in_list
319 (pk_algos
, pk_algos_length
,
320 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
322 && (cred
->certs
[i
].cert_list
[0].type
== GNUTLS_CRT_OPENPGP
))
336 /* Returns the number of issuers in the server's
337 * certificate request packet.
340 get_issuers_num (gnutls_session_t session
, uint8_t * data
, ssize_t data_size
)
342 int issuers_dn_len
= 0, result
;
345 /* Count the number of the given issuers;
346 * This is used to allocate the issuers_dn without
350 if (data_size
== 0 || data
== NULL
)
356 /* This works like DECR_LEN()
358 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
359 DECR_LENGTH_COM (data_size
, 2, goto error
);
360 size
= _gnutls_read_uint16 (data
);
362 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
363 DECR_LENGTH_COM (data_size
, size
, goto error
);
379 return issuers_dn_len
;
385 /* Returns the issuers in the server's certificate request
389 get_issuers (gnutls_session_t session
,
390 gnutls_datum_t
* issuers_dn
, int issuers_len
,
391 uint8_t * data
, size_t data_size
)
396 if (gnutls_certificate_type_get (session
) != GNUTLS_CRT_X509
)
399 /* put the requested DNs to req_dn, only in case
400 * of X509 certificates.
405 for (i
= 0; i
< issuers_len
; i
++)
407 /* The checks here for the buffer boundaries
408 * are not needed since the buffer has been
413 size
= _gnutls_read_uint16 (data
);
417 issuers_dn
[i
].data
= data
;
418 issuers_dn
[i
].size
= size
;
428 st_to_st2 (gnutls_retr2_st
* st2
, gnutls_retr_st
* st
)
430 st2
->cert_type
= st
->type
;
431 if (st
->type
== GNUTLS_CRT_OPENPGP
)
433 st2
->key_type
= GNUTLS_PRIVKEY_OPENPGP
;
437 st2
->key_type
= GNUTLS_PRIVKEY_X509
;
439 st2
->ncerts
= st
->ncerts
;
440 st2
->deinit_all
= st
->deinit_all
;
442 switch (st2
->cert_type
)
444 case GNUTLS_CRT_OPENPGP
:
445 st2
->cert
.pgp
= st
->cert
.pgp
;
446 st2
->key
.pgp
= st
->key
.pgp
;
448 case GNUTLS_CRT_X509
:
449 st2
->cert
.x509
= st
->cert
.x509
;
450 st2
->key
.x509
= st
->key
.x509
;
458 /* Calls the client get callback.
461 call_get_cert_callback (gnutls_session_t session
,
462 const gnutls_datum_t
* issuers_dn
,
463 int issuers_dn_length
,
464 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
467 gnutls_pcert_st
*local_certs
= NULL
;
468 gnutls_privkey_t local_key
= NULL
;
469 int ret
= GNUTLS_E_INTERNAL_ERROR
;
470 gnutls_certificate_type_t type
= gnutls_certificate_type_get (session
);
471 gnutls_certificate_credentials_t cred
;
473 gnutls_pcert_st
*pcert
= NULL
;
474 unsigned int pcert_length
= 0;
476 cred
= (gnutls_certificate_credentials_t
)
477 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
481 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
484 memset (&st2
, 0, sizeof (st2
));
486 if (cred
->get_cert_callback2
)
488 /* we avoid all allocations and transformations */
489 ret
= cred
->get_cert_callback2 (session
, issuers_dn
, issuers_dn_length
,
490 pk_algos
, pk_algos_length
,
491 &pcert
, &pcert_length
, &local_key
);
493 return gnutls_assert_val (GNUTLS_E_USER_ERROR
);
495 if (pcert_length
> 0 && type
!= pcert
[0].type
)
496 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST
);
498 if (pcert_length
== 0)
503 _gnutls_selected_certs_set (session
, pcert
, pcert_length
, local_key
, 0);
508 else if (cred
->get_cert_callback
)
510 ret
= cred
->get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
511 pk_algos
, pk_algos_length
, &st2
);
515 { /* compatibility mode */
517 memset (&st
, 0, sizeof (st
));
518 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
520 if (cred
->server_get_cert_callback
== NULL
)
523 return GNUTLS_E_INTERNAL_ERROR
;
525 ret
= cred
->server_get_cert_callback (session
, &st
);
527 st_to_st2 (&st2
, &st
);
532 if (cred
->client_get_cert_callback
== NULL
)
535 return GNUTLS_E_INTERNAL_ERROR
;
537 ret
= cred
->client_get_cert_callback (session
,
538 issuers_dn
, issuers_dn_length
,
539 pk_algos
, pk_algos_length
,
542 st_to_st2 (&st2
, &st
);
549 return GNUTLS_E_USER_ERROR
;
553 return 0; /* no certificate was selected */
555 if (type
!= st2
.cert_type
)
558 ret
= GNUTLS_E_INVALID_REQUEST
;
563 if (type
== GNUTLS_CRT_X509
)
565 local_certs
= alloc_and_load_x509_certs (st2
.cert
.x509
, st2
.ncerts
);
572 ret
= GNUTLS_E_INVALID_REQUEST
;
575 #ifdef ENABLE_OPENPGP
577 local_certs
= alloc_and_load_pgp_certs (st2
.cert
.pgp
);
580 ret
= GNUTLS_E_UNIMPLEMENTED_FEATURE
;
585 if (local_certs
== NULL
)
588 ret
= GNUTLS_E_MEMORY_ERROR
;
592 switch (st2
.key_type
)
594 case GNUTLS_PRIVKEY_OPENPGP
:
595 #ifdef ENABLE_OPENPGP
596 if (st2
.key
.pgp
!= NULL
)
598 local_key
= alloc_and_load_pgp_key (st2
.key
.pgp
, st2
.deinit_all
);
599 if (local_key
== NULL
)
602 ret
= GNUTLS_E_INTERNAL_ERROR
;
608 case GNUTLS_PRIVKEY_PKCS11
:
610 if (st2
.key
.pkcs11
!= NULL
)
613 alloc_and_load_pkcs11_key (st2
.key
.pkcs11
, st2
.deinit_all
);
614 if (local_key
== NULL
)
617 ret
= GNUTLS_E_INTERNAL_ERROR
;
623 case GNUTLS_PRIVKEY_X509
:
624 if (st2
.key
.x509
!= NULL
)
626 local_key
= alloc_and_load_x509_key (st2
.key
.x509
, st2
.deinit_all
);
627 if (local_key
== NULL
)
630 ret
= GNUTLS_E_INTERNAL_ERROR
;
637 ret
= GNUTLS_E_INVALID_REQUEST
;
641 _gnutls_selected_certs_set (session
, local_certs
,
642 (local_certs
!= NULL
) ? st2
.ncerts
: 0,
649 if (st2
.cert_type
== GNUTLS_CRT_X509
)
653 for (i
= 0; i
< st2
.ncerts
; i
++)
655 gnutls_x509_crt_deinit (st2
.cert
.x509
[i
]);
657 gnutls_free(st2
.cert
.x509
);
662 #ifdef ENABLE_OPENPGP
665 gnutls_openpgp_crt_deinit (st2
.cert
.pgp
);
672 if (local_key
!= NULL
)
673 gnutls_privkey_deinit (local_key
);
679 /* Finds the appropriate certificate depending on the cA Distinguished name
680 * advertized by the server. If none matches then returns 0 and -1 as index.
681 * In case of an error a negative error code, is returned.
683 * 20020128: added ability to select a certificate depending on the SIGN
684 * algorithm (only in automatic mode).
687 _select_client_cert (gnutls_session_t session
,
688 uint8_t * _data
, size_t _data_size
,
689 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
693 gnutls_certificate_credentials_t cred
;
694 uint8_t *data
= _data
;
695 ssize_t data_size
= _data_size
;
696 int issuers_dn_length
;
697 gnutls_datum_t
*issuers_dn
= NULL
;
699 cred
= (gnutls_certificate_credentials_t
)
700 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
704 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
707 if (cred
->client_get_cert_callback
!= NULL
708 || cred
->get_cert_callback
!= NULL
|| cred
->get_cert_callback2
!= NULL
)
711 /* use a callback to get certificate
713 if (session
->security_parameters
.cert_type
!= GNUTLS_CRT_X509
)
714 issuers_dn_length
= 0;
717 issuers_dn_length
= get_issuers_num (session
, data
, data_size
);
718 if (issuers_dn_length
< 0)
721 return issuers_dn_length
;
724 if (issuers_dn_length
> 0)
727 gnutls_malloc (sizeof (gnutls_datum_t
) * issuers_dn_length
);
728 if (issuers_dn
== NULL
)
731 return GNUTLS_E_MEMORY_ERROR
;
735 get_issuers (session
, issuers_dn
, issuers_dn_length
,
746 call_get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
747 pk_algos
, pk_algos_length
);
753 /* If we have no callbacks, try to guess.
757 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
)
759 _find_x509_cert (cred
, _data
, _data_size
,
760 pk_algos
, pk_algos_length
, &indx
);
761 #ifdef ENABLE_OPENPGP
762 else if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
)
763 result
= _find_openpgp_cert (cred
, pk_algos
, pk_algos_length
, &indx
);
774 _gnutls_selected_certs_set (session
,
775 &cred
->certs
[indx
].cert_list
[0],
776 cred
->certs
[indx
].cert_list_length
,
777 cred
->pkey
[indx
], 0);
781 _gnutls_selected_certs_set (session
, NULL
, 0, NULL
, 0);
788 gnutls_free (issuers_dn
);
793 /* Generate certificate message
796 _gnutls_gen_x509_crt (gnutls_session_t session
, gnutls_buffer_st
* data
)
799 gnutls_pcert_st
*apr_cert_list
;
800 gnutls_privkey_t apr_pkey
;
801 int apr_cert_list_length
;
803 /* find the appropriate certificate
806 _gnutls_get_selected_cert (session
, &apr_cert_list
,
807 &apr_cert_list_length
, &apr_pkey
)) < 0)
814 for (i
= 0; i
< apr_cert_list_length
; i
++)
816 ret
+= apr_cert_list
[i
].cert
.size
+ 3;
821 /* if no certificates were found then send:
822 * 0B 00 00 03 00 00 00 // Certificate with no certs
824 * 0B 00 00 00 // empty certificate handshake
826 * ( the above is the whole handshake message, not
827 * the one produced here )
830 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
832 return gnutls_assert_val (ret
);
834 for (i
= 0; i
< apr_cert_list_length
; i
++)
837 _gnutls_buffer_append_data_prefix (data
, 24,
838 apr_cert_list
[i
].cert
.data
,
839 apr_cert_list
[i
].cert
.size
);
841 return gnutls_assert_val (ret
);
847 enum PGPKeyDescriptorType
848 { PGP_EMPTY_KEY
=1, PGP_KEY_SUBKEY
, PGP_KEY_FINGERPRINT_SUBKEY
};
850 #ifdef ENABLE_OPENPGP
852 _gnutls_gen_openpgp_certificate (gnutls_session_t session
,
853 gnutls_buffer_st
* data
)
856 gnutls_pcert_st
*apr_cert_list
;
857 gnutls_privkey_t apr_pkey
;
858 int apr_cert_list_length
;
862 char buf
[2*GNUTLS_OPENPGP_KEYID_SIZE
+1];
865 /* find the appropriate certificate */
867 _gnutls_get_selected_cert (session
, &apr_cert_list
,
868 &apr_cert_list_length
, &apr_pkey
)) < 0)
876 if (apr_cert_list_length
> 0)
878 fpr_size
= sizeof (fpr
);
880 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
883 return gnutls_assert_val (ret
);
885 ret
+= 1 + fpr_size
; /* for the keyid */
886 _gnutls_handshake_log("Sending PGP key ID %s (%s)\n", _gnutls_bin2hex(fpr
, GNUTLS_OPENPGP_KEYID_SIZE
, buf
, sizeof(buf
), NULL
),
887 subkey
?"subkey":"master");
889 ret
+= apr_cert_list
[0].cert
.size
;
892 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
894 return gnutls_assert_val (ret
);
897 if (apr_cert_list_length
> 0)
899 type
= PGP_KEY_SUBKEY
;
901 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
903 return gnutls_assert_val (ret
);
905 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
907 return gnutls_assert_val (ret
);
910 _gnutls_buffer_append_data_prefix (data
, 24,
911 apr_cert_list
[0].cert
.data
,
912 apr_cert_list
[0].cert
.size
);
914 return gnutls_assert_val (ret
);
916 else /* empty - no certificate */
918 type
= PGP_EMPTY_KEY
;
920 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
922 return gnutls_assert_val (ret
);
924 ret
= _gnutls_buffer_append_prefix (data
, 24, 0);
926 return gnutls_assert_val (ret
);
933 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session
,
934 gnutls_buffer_st
* data
)
936 int ret
, packet_size
;
937 uint8_t type
, fpr
[20];
939 gnutls_pcert_st
*apr_cert_list
;
940 gnutls_privkey_t apr_pkey
;
941 int apr_cert_list_length
;
943 /* find the appropriate certificate */
945 _gnutls_get_selected_cert (session
, &apr_cert_list
,
946 &apr_cert_list_length
, &apr_pkey
)) < 0)
952 fpr_size
= sizeof (fpr
);
954 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
957 return gnutls_assert_val (ret
);
960 packet_size
+= 1 + fpr_size
; /* for the keyid */
962 /* Only v4 fingerprints are sent
964 if (apr_cert_list_length
> 0)
965 packet_size
+= 20 + 1;
966 else /* empty certificate case */
967 return _gnutls_gen_openpgp_certificate (session
, data
);
969 ret
= _gnutls_buffer_append_prefix (data
, 24, packet_size
- 3);
971 return gnutls_assert_val (ret
);
973 type
= PGP_KEY_FINGERPRINT_SUBKEY
;
974 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
976 return gnutls_assert_val (ret
);
978 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
980 return gnutls_assert_val (ret
);
988 _gnutls_gen_cert_client_crt (gnutls_session_t session
,
989 gnutls_buffer_st
* data
)
991 switch (session
->security_parameters
.cert_type
)
993 #ifdef ENABLE_OPENPGP
994 case GNUTLS_CRT_OPENPGP
:
995 if (_gnutls_openpgp_send_fingerprint (session
) == 0)
996 return _gnutls_gen_openpgp_certificate (session
, data
);
998 return _gnutls_gen_openpgp_certificate_fpr (session
, data
);
1000 case GNUTLS_CRT_X509
:
1001 return _gnutls_gen_x509_crt (session
, data
);
1005 return GNUTLS_E_INTERNAL_ERROR
;
1010 _gnutls_gen_cert_server_crt (gnutls_session_t session
,
1011 gnutls_buffer_st
* data
)
1013 switch (session
->security_parameters
.cert_type
)
1015 #ifdef ENABLE_OPENPGP
1016 case GNUTLS_CRT_OPENPGP
:
1017 return _gnutls_gen_openpgp_certificate (session
, data
);
1019 case GNUTLS_CRT_X509
:
1020 return _gnutls_gen_x509_crt (session
, data
);
1023 return GNUTLS_E_INTERNAL_ERROR
;
1027 /* Process server certificate
1030 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1032 _gnutls_proc_x509_server_crt (gnutls_session_t session
,
1033 uint8_t * data
, size_t data_size
)
1037 cert_auth_info_t info
;
1038 gnutls_certificate_credentials_t cred
;
1039 ssize_t dsize
= data_size
;
1041 gnutls_pcert_st
*peer_certificate_list
;
1042 size_t peer_certificate_list_size
= 0, j
, x
;
1045 cred
= (gnutls_certificate_credentials_t
)
1046 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1050 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1055 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1056 sizeof (cert_auth_info_st
), 1)) < 0)
1062 info
= _gnutls_get_auth_info (session
);
1064 if (data
== NULL
|| data_size
== 0)
1067 /* no certificate was sent */
1068 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1071 DECR_LEN (dsize
, 3);
1072 size
= _gnutls_read_uint24 (p
);
1075 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1076 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1078 if (size
== 0 || size
== 3)
1081 /* no certificate was sent */
1082 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1088 DECR_LEN (dsize
, 3);
1089 len
= _gnutls_read_uint24 (p
);
1091 DECR_LEN (dsize
, len
);
1092 peer_certificate_list_size
++;
1097 if (peer_certificate_list_size
== 0)
1100 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1103 /* Ok we now allocate the memory to hold the
1107 peer_certificate_list
=
1109 sizeof (gnutls_pcert_st
) * (peer_certificate_list_size
));
1110 if (peer_certificate_list
== NULL
)
1113 return GNUTLS_E_MEMORY_ERROR
;
1118 /* Now we start parsing the list (again).
1119 * We don't use DECR_LEN since the list has
1120 * been parsed before.
1123 for (j
= 0; j
< peer_certificate_list_size
; j
++)
1125 len
= _gnutls_read_uint24 (p
);
1132 gnutls_pcert_import_x509_raw (&peer_certificate_list
1133 [j
], &tmp
, GNUTLS_X509_FMT_DER
, 0);
1137 peer_certificate_list_size
= j
;
1146 _gnutls_copy_certificate_auth_info (info
,
1147 peer_certificate_list
,
1148 peer_certificate_list_size
,
1156 _gnutls_check_key_usage (&peer_certificate_list
[0],
1157 gnutls_kx_get (session
))) < 0)
1167 gnutls_free (peer_certificate_list
);
1172 #ifdef ENABLE_OPENPGP
1174 _gnutls_proc_openpgp_server_crt (gnutls_session_t session
,
1175 uint8_t * data
, size_t data_size
)
1179 cert_auth_info_t info
;
1180 gnutls_certificate_credentials_t cred
;
1181 ssize_t dsize
= data_size
;
1183 gnutls_pcert_st
*peer_certificate_list
= NULL
;
1184 gnutls_datum_t tmp
, akey
= { NULL
, 0 };
1185 unsigned int compat
= 0;
1186 uint8_t subkey_id
[GNUTLS_OPENPGP_KEYID_SIZE
];
1188 cred
= (gnutls_certificate_credentials_t
)
1189 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1193 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1197 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1198 sizeof (cert_auth_info_st
), 1)) < 0)
1204 info
= _gnutls_get_auth_info (session
);
1206 if (data
== NULL
|| data_size
== 0)
1209 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1212 DECR_LEN (dsize
, 3);
1213 size
= _gnutls_read_uint24 (p
);
1219 /* no certificate was sent */
1220 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1223 /* Read PGPKeyDescriptor */
1224 DECR_LEN (dsize
, 1);
1228 /* Try to read the keyid if present */
1229 if (key_type
== PGP_KEY_FINGERPRINT_SUBKEY
|| key_type
== PGP_KEY_SUBKEY
)
1232 if (*p
!= GNUTLS_OPENPGP_KEYID_SIZE
)
1235 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1238 DECR_LEN (dsize
, 1);
1241 DECR_LEN (dsize
, GNUTLS_OPENPGP_KEYID_SIZE
);
1242 memcpy (subkey_id
, p
, GNUTLS_OPENPGP_KEYID_SIZE
);
1243 p
+= GNUTLS_OPENPGP_KEYID_SIZE
;
1246 if (key_type
== PGP_KEY_FINGERPRINT_SUBKEY
)
1248 DECR_LEN (dsize
, 1);
1249 len
= (uint8_t) * p
;
1255 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED
;
1258 DECR_LEN (dsize
, 20);
1260 /* request the actual key from our database, or
1261 * a key server or anything.
1264 _gnutls_openpgp_request_key (session
, &akey
, cred
, p
, 20)) < 0)
1271 else if (key_type
== PGP_KEY_SUBKEY
)
1272 { /* the whole key */
1274 /* Read the actual certificate */
1275 DECR_LEN (dsize
, 3);
1276 len
= _gnutls_read_uint24 (p
);
1282 /* no certificate was sent */
1283 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH
);
1286 DECR_LEN (dsize
, len
);
1292 else if (key_type
== PGP_EMPTY_KEY
)
1293 { /* the whole key */
1295 /* Read the actual certificate */
1296 DECR_LEN (dsize
, 3);
1297 len
= _gnutls_read_uint24 (p
);
1300 if (len
== 0) /* PGP_EMPTY_KEY */
1301 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1302 /* Uncomment to remove compatibility with RFC5081.
1304 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);*/
1306 DECR_LEN (dsize
, len
);
1316 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1319 /* ok we now have the peer's key in tmp datum
1321 peer_certificate_list
=
1322 gnutls_calloc (1, sizeof (gnutls_pcert_st
));
1323 if (peer_certificate_list
== NULL
)
1326 ret
= GNUTLS_E_MEMORY_ERROR
;
1331 gnutls_pcert_import_openpgp_raw (&peer_certificate_list
[0],
1333 GNUTLS_OPENPGP_FMT_RAW
,
1334 (compat
==0)?subkey_id
:NULL
,
1344 size_t t
= sizeof(subkey_id
);
1345 gnutls_pubkey_get_openpgp_key_id(peer_certificate_list
[0].pubkey
, 0, subkey_id
, &t
, NULL
);
1349 _gnutls_copy_certificate_auth_info (info
,
1350 peer_certificate_list
,
1359 _gnutls_check_key_usage (&peer_certificate_list
[0],
1360 gnutls_kx_get (session
))) < 0)
1370 _gnutls_free_datum (&akey
);
1371 gnutls_pcert_deinit(&peer_certificate_list
[0]);
1372 gnutls_free (peer_certificate_list
);
1379 _gnutls_proc_crt (gnutls_session_t session
, uint8_t * data
, size_t data_size
)
1382 gnutls_certificate_credentials_t cred
;
1385 (gnutls_certificate_credentials_t
) _gnutls_get_cred (session
,
1386 GNUTLS_CRD_CERTIFICATE
,
1391 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1394 switch (session
->security_parameters
.cert_type
)
1396 #ifdef ENABLE_OPENPGP
1397 case GNUTLS_CRT_OPENPGP
:
1398 ret
= _gnutls_proc_openpgp_server_crt (session
,
1402 case GNUTLS_CRT_X509
:
1403 ret
= _gnutls_proc_x509_server_crt (session
, data
, data_size
);
1407 return GNUTLS_E_INTERNAL_ERROR
;
1414 /* Checks if we support the given signature algorithm
1415 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1419 _gnutls_check_supported_sign_algo (CertificateSigType algo
)
1424 return GNUTLS_PK_RSA
;
1426 return GNUTLS_PK_DSA
;
1428 return GNUTLS_PK_EC
;
1435 _gnutls_proc_cert_cert_req (gnutls_session_t session
, uint8_t * data
,
1440 gnutls_certificate_credentials_t cred
;
1443 gnutls_pk_algorithm_t pk_algos
[MAX_CLIENT_SIGN_ALGOS
];
1444 int pk_algos_length
;
1445 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1447 cred
= (gnutls_certificate_credentials_t
)
1448 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1452 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1456 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1457 sizeof (cert_auth_info_st
), 0)) < 0)
1466 DECR_LEN (dsize
, 1);
1469 /* check if the sign algorithm is supported.
1471 pk_algos_length
= 0;
1472 for (i
= 0; i
< size
; i
++, p
++)
1474 DECR_LEN (dsize
, 1);
1475 if ((ret
= _gnutls_check_supported_sign_algo (*p
)) > 0)
1477 if (pk_algos_length
< MAX_CLIENT_SIGN_ALGOS
)
1479 pk_algos
[pk_algos_length
++] = ret
;
1484 if (pk_algos_length
== 0)
1487 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1490 if (_gnutls_version_has_selectable_sighash (ver
))
1492 /* read supported hashes */
1494 DECR_LEN (dsize
, 2);
1495 hash_num
= _gnutls_read_uint16 (p
);
1497 DECR_LEN (dsize
, hash_num
);
1499 ret
= _gnutls_sign_algorithm_parse_data (session
, p
, hash_num
);
1509 /* read the certificate authorities */
1510 DECR_LEN (dsize
, 2);
1511 size
= _gnutls_read_uint16 (p
);
1514 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
1518 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1521 DECR_LEN (dsize
, size
);
1523 /* now we ask the user to tell which one
1527 _select_client_cert (session
, p
, size
, pk_algos
, pk_algos_length
)) < 0)
1533 /* We should reply with a certificate message,
1534 * even if we have no certificate to send.
1536 session
->key
.crt_requested
= 1;
1542 _gnutls_gen_cert_client_crt_vrfy (gnutls_session_t session
,
1543 gnutls_buffer_st
* data
)
1546 gnutls_pcert_st
*apr_cert_list
;
1547 gnutls_privkey_t apr_pkey
;
1548 int apr_cert_list_length
;
1549 gnutls_datum_t signature
= { NULL
, 0 };
1550 gnutls_sign_algorithm_t sign_algo
;
1551 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1553 /* find the appropriate certificate */
1555 _gnutls_get_selected_cert (session
, &apr_cert_list
,
1556 &apr_cert_list_length
, &apr_pkey
)) < 0)
1562 if (apr_cert_list_length
> 0)
1565 _gnutls_handshake_sign_crt_vrfy (session
,
1567 apr_pkey
, &signature
)) < 0)
1579 if (_gnutls_version_has_selectable_sighash (ver
))
1581 const sign_algorithm_st
*aid
;
1583 /* error checking is not needed here since we have used those algorithms */
1584 aid
= _gnutls_sign_to_tls_aid (sign_algo
);
1586 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM
);
1588 p
[0] = aid
->hash_algorithm
;
1589 p
[1] = aid
->sign_algorithm
;
1590 ret
= _gnutls_buffer_append_data (data
, p
, 2);
1599 _gnutls_buffer_append_data_prefix (data
, 16, signature
.data
,
1610 _gnutls_free_datum (&signature
);
1615 _gnutls_proc_cert_client_crt_vrfy (gnutls_session_t session
,
1616 uint8_t * data
, size_t data_size
)
1619 ssize_t dsize
= data_size
;
1620 uint8_t *pdata
= data
;
1622 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
1623 gnutls_pcert_st peer_cert
;
1624 gnutls_sign_algorithm_t sign_algo
= GNUTLS_SIGN_UNKNOWN
;
1625 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1627 if (info
== NULL
|| info
->ncerts
== 0)
1630 /* we need this in order to get peer's certificate */
1631 return GNUTLS_E_INTERNAL_ERROR
;
1634 if (_gnutls_version_has_selectable_sighash (ver
))
1636 sign_algorithm_st aid
;
1638 DECR_LEN (dsize
, 2);
1639 aid
.hash_algorithm
= pdata
[0];
1640 aid
.sign_algorithm
= pdata
[1];
1642 sign_algo
= _gnutls_tls_aid_to_sign (&aid
);
1643 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
1646 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1651 ret
= _gnutls_session_sign_algo_enabled (session
, sign_algo
);
1655 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1658 DECR_LEN (dsize
, 2);
1659 size
= _gnutls_read_uint16 (pdata
);
1662 DECR_LEN (dsize
, size
);
1667 ret
= _gnutls_get_auth_info_pcert (&peer_cert
,
1668 session
->security_parameters
.cert_type
,
1678 _gnutls_handshake_verify_crt_vrfy (session
, &peer_cert
, &sig
,
1682 gnutls_pcert_deinit (&peer_cert
);
1685 gnutls_pcert_deinit (&peer_cert
);
1691 _gnutls_gen_cert_server_cert_req (gnutls_session_t session
,
1692 gnutls_buffer_st
* data
)
1694 gnutls_certificate_credentials_t cred
;
1696 uint8_t tmp_data
[CERTTYPE_SIZE
];
1697 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1699 /* Now we need to generate the RDN sequence. This is
1700 * already in the CERTIFICATE_CRED structure, to improve
1704 cred
= (gnutls_certificate_credentials_t
)
1705 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1709 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1712 tmp_data
[0] = CERTTYPE_SIZE
- 1;
1713 tmp_data
[1] = RSA_SIGN
;
1714 tmp_data
[2] = DSA_SIGN
;
1715 tmp_data
[3] = ECDSA_SIGN
; /* only these for now */
1717 ret
= _gnutls_buffer_append_data (data
, tmp_data
, CERTTYPE_SIZE
);
1719 return gnutls_assert_val (ret
);
1721 if (_gnutls_version_has_selectable_sighash (ver
))
1723 uint8_t p
[MAX_SIGN_ALGO_SIZE
];
1726 _gnutls_sign_algorithm_write_params (session
, p
, MAX_SIGN_ALGO_SIZE
);
1733 ret
= _gnutls_buffer_append_data (data
, p
, ret
);
1735 return gnutls_assert_val (ret
);
1738 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1739 session
->internals
.ignore_rdn_sequence
== 0)
1742 _gnutls_buffer_append_data_prefix (data
, 16,
1743 cred
->x509_rdn_sequence
.data
,
1744 cred
->x509_rdn_sequence
.size
);
1746 return gnutls_assert_val (ret
);
1750 ret
= _gnutls_buffer_append_prefix (data
, 16, 0);
1752 return gnutls_assert_val (ret
);
1755 return data
->length
;
1759 /* This function will return the appropriate certificate to use.
1760 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1761 * The return value is a negative error code on error.
1763 * It is normal to return 0 with no certificates in client side.
1767 _gnutls_get_selected_cert (gnutls_session_t session
,
1768 gnutls_pcert_st
** apr_cert_list
,
1769 int *apr_cert_list_length
,
1770 gnutls_privkey_t
* apr_pkey
)
1772 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
1775 /* select_client_cert() has been called before.
1778 *apr_cert_list
= session
->internals
.selected_cert_list
;
1779 *apr_pkey
= session
->internals
.selected_key
;
1780 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1782 if (*apr_cert_list_length
== 0 || *apr_cert_list
== NULL
)
1785 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1793 /* we have already decided which certificate
1796 *apr_cert_list
= session
->internals
.selected_cert_list
;
1797 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1798 *apr_pkey
= session
->internals
.selected_key
;
1805 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1808 static gnutls_pcert_st
*
1809 alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
, unsigned ncerts
)
1811 gnutls_pcert_st
*local_certs
;
1818 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
) * ncerts
);
1819 if (local_certs
== NULL
)
1825 for (i
= 0; i
< ncerts
; i
++)
1827 ret
= gnutls_pcert_import_x509 (&local_certs
[i
], certs
[i
], 0);
1835 for (j
= 0; j
< i
; j
++)
1837 gnutls_pcert_deinit (&local_certs
[j
]);
1839 gnutls_free (local_certs
);
1846 /* converts the given x509 key to gnutls_privkey* and allocates
1849 static gnutls_privkey_t
1850 alloc_and_load_x509_key (gnutls_x509_privkey_t key
, int deinit
)
1852 gnutls_privkey_t local_key
;
1858 ret
= gnutls_privkey_init (&local_key
);
1866 gnutls_privkey_import_x509 (local_key
, key
,
1867 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
:
1872 gnutls_privkey_deinit (local_key
);
1879 /* converts the given pgp certificate to gnutls_cert* and allocates
1882 #ifdef ENABLE_OPENPGP
1883 static gnutls_pcert_st
*
1884 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
)
1886 gnutls_pcert_st
*local_certs
;
1892 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
));
1893 if (local_certs
== NULL
)
1899 ret
= gnutls_pcert_import_openpgp (local_certs
, cert
, 0);
1909 gnutls_pcert_deinit (local_certs
);
1910 gnutls_free (local_certs
);
1917 /* converts the given raw key to gnutls_privkey* and allocates
1920 static gnutls_privkey_t
1921 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key
, int deinit
)
1923 gnutls_privkey_t local_key
;
1929 ret
= gnutls_privkey_init (&local_key
);
1937 gnutls_privkey_import_openpgp (local_key
, key
,
1938 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1943 gnutls_privkey_deinit (local_key
);
1951 #ifdef ENABLE_PKCS11
1953 /* converts the given raw key to gnutls_privkey* and allocates
1956 static gnutls_privkey_t
1957 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key
, int deinit
)
1959 gnutls_privkey_t local_key
;
1965 ret
= gnutls_privkey_init (&local_key
);
1973 gnutls_privkey_import_pkcs11 (local_key
, key
,
1974 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
1979 gnutls_privkey_deinit (local_key
);
1989 _gnutls_selected_certs_deinit (gnutls_session_t session
)
1991 if (session
->internals
.selected_need_free
!= 0)
1995 for (i
= 0; i
< session
->internals
.selected_cert_list_length
; i
++)
1997 gnutls_pcert_deinit (&session
->internals
.selected_cert_list
[i
]);
1999 gnutls_free (session
->internals
.selected_cert_list
);
2000 session
->internals
.selected_cert_list
= NULL
;
2001 session
->internals
.selected_cert_list_length
= 0;
2003 gnutls_privkey_deinit(session
->internals
.selected_key
);
2004 session
->internals
.selected_key
= NULL
;
2011 _gnutls_selected_certs_set (gnutls_session_t session
,
2012 gnutls_pcert_st
* certs
, int ncerts
,
2013 gnutls_privkey_t key
, int need_free
)
2015 _gnutls_selected_certs_deinit (session
);
2017 session
->internals
.selected_cert_list
= certs
;
2018 session
->internals
.selected_cert_list_length
= ncerts
;
2019 session
->internals
.selected_key
= key
;
2020 session
->internals
.selected_need_free
= need_free
;
2024 static void get_server_name(gnutls_session_t session
, uint8_t* name
, size_t max_name_size
)
2031 for (i
=0; !(ret
<0);i
++)
2033 max_name
= max_name_size
;
2034 ret
= gnutls_server_name_get (session
, name
, &max_name
, &type
, i
);
2035 if (ret
>= 0 && type
== GNUTLS_NAME_DNS
)
2044 /* finds the most appropriate certificate in the cert list.
2045 * The 'appropriate' is defined by the user.
2047 * requested_algo holds the parameters required by the peer (RSA, DSA
2050 * Returns 0 on success and a negative error code on error. The
2051 * selected certificate will be in session->internals.selected_*.
2055 _gnutls_server_select_cert (gnutls_session_t session
,
2056 gnutls_pk_algorithm_t
* pk_algos
,
2057 size_t pk_algos_size
)
2061 gnutls_certificate_credentials_t cred
;
2062 char server_name
[MAX_CN
];
2064 cred
= (gnutls_certificate_credentials_t
)
2065 _gnutls_get_cred (session
, GNUTLS_CRD_CERTIFICATE
, NULL
);
2069 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2072 /* If the callback which retrieves certificate has been set,
2075 if (cred
->server_get_cert_callback
|| cred
->get_cert_callback
2076 || cred
->get_cert_callback2
)
2078 ret
= call_get_cert_callback (session
, NULL
, 0, NULL
, 0);
2080 return gnutls_assert_val (ret
);
2086 get_server_name(session
, (unsigned char*)server_name
, sizeof(server_name
));
2088 idx
= -1; /* default is use no certificate */
2090 /* find certificates that match the requested server_name
2093 if (server_name
[0] != 0)
2095 for (i
= 0; i
< cred
->ncerts
; i
++)
2097 if (cred
->certs
[i
].names
!= NULL
&& _gnutls_str_array_match(cred
->certs
[i
].names
, server_name
) != 0)
2099 /* if requested algorithms are also compatible select it */
2100 gnutls_pk_algorithm pk
=
2101 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2104 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name
,
2105 gnutls_certificate_type_get_name (session
->security_parameters
.cert_type
),
2106 session
->security_parameters
.cert_type
);
2108 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2110 for (j
= 0; j
< pk_algos_size
; j
++)
2111 if (pk_algos
[j
] == pk
)
2121 for (j
= 0; j
< pk_algos_size
; j
++)
2123 _gnutls_handshake_log
2124 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2125 session
, gnutls_pk_get_name (pk_algos
[j
]), pk_algos
[j
],
2126 gnutls_certificate_type_get_name (session
->security_parameters
.
2128 session
->security_parameters
.cert_type
);
2130 for (i
= 0; i
< cred
->ncerts
; i
++)
2132 gnutls_pk_algorithm pk
=
2133 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2135 /* find one compatible certificate
2137 _gnutls_handshake_log
2138 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2139 session
, i
, gnutls_pk_get_name (pk
), pk
,
2140 gnutls_certificate_type_get_name (cred
->certs
[i
].cert_list
[0].type
),
2141 cred
->certs
[i
].cert_list
[0].type
);
2143 if (pk_algos
[j
] == pk
)
2145 /* if cert type matches
2148 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2158 /* store the certificate pointer for future use, in the handshake.
2159 * (This will allow not calling this callback again.)
2164 _gnutls_selected_certs_set (session
,
2165 &cred
->certs
[idx
].cert_list
[0],
2166 cred
->certs
[idx
].cert_list_length
,
2167 cred
->pkey
[idx
], 0);
2172 /* Certificate does not support REQUESTED_ALGO. */
2173 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2179 /* Frees the rsa_info_st structure.
2182 _gnutls_free_rsa_info (rsa_info_st
* rsa
)
2184 _gnutls_free_datum (&rsa
->modulus
);
2185 _gnutls_free_datum (&rsa
->exponent
);