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
, int subkey_used
, /* 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
)
126 info
->use_subkey
= subkey_used
;
128 memcpy (info
->subkey_id
, keyid
, GNUTLS_OPENPGP_KEYID_SIZE
);
136 for (j
= 0; j
< i
; j
++)
137 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
139 gnutls_free (info
->raw_certificate_list
);
140 info
->raw_certificate_list
= NULL
;
148 /* returns 0 if the algo_to-check exists in the pk_algos list,
152 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t
*
153 pk_algos
, int pk_algos_length
,
154 gnutls_pk_algorithm_t algo_to_check
)
157 for (i
= 0; i
< pk_algos_length
; i
++)
159 if (algo_to_check
== pk_algos
[i
])
168 /* Returns the issuer's Distinguished name in odn, of the certificate
172 _gnutls_cert_get_issuer_dn (gnutls_pcert_st
* cert
, gnutls_datum_t
* odn
)
178 if ((result
= asn1_create_element
179 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn
)) != ASN1_SUCCESS
)
182 return _gnutls_asn2err (result
);
185 result
= asn1_der_decoding (&dn
, cert
->cert
.data
, cert
->cert
.size
, NULL
);
186 if (result
!= ASN1_SUCCESS
)
188 /* couldn't decode DER */
190 asn1_delete_structure (&dn
);
191 return _gnutls_asn2err (result
);
194 result
= asn1_der_decoding_startEnd (dn
, cert
->cert
.data
, cert
->cert
.size
,
195 "tbsCertificate.issuer", &start
, &end
);
197 if (result
!= ASN1_SUCCESS
)
199 /* couldn't decode DER */
201 asn1_delete_structure (&dn
);
202 return _gnutls_asn2err (result
);
204 asn1_delete_structure (&dn
);
206 len
= end
- start
+ 1;
209 odn
->data
= &cert
->cert
.data
[start
];
215 /* Locates the most appropriate x509 certificate using the
216 * given DN. If indx == -1 then no certificate was found.
218 * That is to guess which certificate to use, based on the
219 * CAs and sign algorithms supported by the peer server.
222 _find_x509_cert (const gnutls_certificate_credentials_t cred
,
223 uint8_t * _data
, size_t _data_size
,
224 const gnutls_pk_algorithm_t
* pk_algos
,
225 int pk_algos_length
, int *indx
)
228 gnutls_datum_t odn
= { NULL
, 0 };
229 uint8_t *data
= _data
;
230 ssize_t data_size
= _data_size
;
236 /* If peer doesn't send any issuers and we have a single certificate
237 * then send that one.
239 if (data_size
== 0 && cred
->ncerts
== 1)
247 DECR_LENGTH_RET (data_size
, 2, 0);
248 size
= _gnutls_read_uint16 (data
);
249 DECR_LENGTH_RET (data_size
, size
, 0);
252 for (i
= 0; i
< cred
->ncerts
; i
++)
254 for (j
= 0; j
< cred
->certs
[i
].cert_list_length
; j
++)
257 _gnutls_cert_get_issuer_dn (&cred
->certs
[i
].cert_list
[j
],
264 if (odn
.size
!= size
)
267 /* If the DN matches and
268 * the *_SIGN algorithm matches
269 * the cert is our cert!
272 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
275 if ((memcmp (odn
.data
, data
, size
) == 0) &&
276 (_gnutls_check_pk_algo_in_list
277 (pk_algos
, pk_algos_length
, cert_pk
) == 0))
290 /* move to next record */
299 #ifdef ENABLE_OPENPGP
300 /* Locates the most appropriate openpgp cert
303 _find_openpgp_cert (const gnutls_certificate_credentials_t cred
,
304 gnutls_pk_algorithm_t
* pk_algos
,
305 int pk_algos_length
, int *indx
)
311 for (i
= 0; i
< cred
->ncerts
; i
++)
313 for (j
= 0; j
< cred
->certs
[i
].cert_list_length
; j
++)
316 /* If the *_SIGN algorithm matches
317 * the cert is our cert!
319 if ((_gnutls_check_pk_algo_in_list
320 (pk_algos
, pk_algos_length
,
321 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
323 && (cred
->certs
[i
].cert_list
[0].type
== GNUTLS_CRT_OPENPGP
))
337 /* Returns the number of issuers in the server's
338 * certificate request packet.
341 get_issuers_num (gnutls_session_t session
, uint8_t * data
, ssize_t data_size
)
343 int issuers_dn_len
= 0, result
;
346 /* Count the number of the given issuers;
347 * This is used to allocate the issuers_dn without
351 if (data_size
== 0 || data
== NULL
)
357 /* This works like DECR_LEN()
359 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
360 DECR_LENGTH_COM (data_size
, 2, goto error
);
361 size
= _gnutls_read_uint16 (data
);
363 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
364 DECR_LENGTH_COM (data_size
, size
, goto error
);
380 return issuers_dn_len
;
386 /* Returns the issuers in the server's certificate request
390 get_issuers (gnutls_session_t session
,
391 gnutls_datum_t
* issuers_dn
, int issuers_len
,
392 uint8_t * data
, size_t data_size
)
397 if (gnutls_certificate_type_get (session
) != GNUTLS_CRT_X509
)
400 /* put the requested DNs to req_dn, only in case
401 * of X509 certificates.
406 for (i
= 0; i
< issuers_len
; i
++)
408 /* The checks here for the buffer boundaries
409 * are not needed since the buffer has been
414 size
= _gnutls_read_uint16 (data
);
418 issuers_dn
[i
].data
= data
;
419 issuers_dn
[i
].size
= size
;
429 st_to_st2 (gnutls_retr2_st
* st2
, gnutls_retr_st
* st
)
431 st2
->cert_type
= st
->type
;
432 if (st
->type
== GNUTLS_CRT_OPENPGP
)
434 st2
->key_type
= GNUTLS_PRIVKEY_OPENPGP
;
438 st2
->key_type
= GNUTLS_PRIVKEY_X509
;
440 st2
->ncerts
= st
->ncerts
;
441 st2
->deinit_all
= st
->deinit_all
;
443 switch (st2
->cert_type
)
445 case GNUTLS_CRT_OPENPGP
:
446 st2
->cert
.pgp
= st
->cert
.pgp
;
447 st2
->key
.pgp
= st
->key
.pgp
;
449 case GNUTLS_CRT_X509
:
450 st2
->cert
.x509
= st
->cert
.x509
;
451 st2
->key
.x509
= st
->key
.x509
;
459 /* Calls the client get callback.
462 call_get_cert_callback (gnutls_session_t session
,
463 const gnutls_datum_t
* issuers_dn
,
464 int issuers_dn_length
,
465 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
468 gnutls_pcert_st
*local_certs
= NULL
;
469 gnutls_privkey_t local_key
= NULL
;
470 int ret
= GNUTLS_E_INTERNAL_ERROR
;
471 gnutls_certificate_type_t type
= gnutls_certificate_type_get (session
);
472 gnutls_certificate_credentials_t cred
;
474 gnutls_pcert_st
*pcert
= NULL
;
475 unsigned int pcert_length
= 0;
477 cred
= (gnutls_certificate_credentials_t
)
478 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
482 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
485 memset (&st2
, 0, sizeof (st2
));
487 if (cred
->get_cert_callback2
)
489 /* we avoid all allocations and transformations */
490 ret
= cred
->get_cert_callback2 (session
, issuers_dn
, issuers_dn_length
,
491 pk_algos
, pk_algos_length
,
492 &pcert
, &pcert_length
, &local_key
);
494 return gnutls_assert_val (GNUTLS_E_USER_ERROR
);
496 if (pcert_length
> 0 && type
!= pcert
[0].type
)
497 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST
);
499 if (pcert_length
== 0)
504 _gnutls_selected_certs_set (session
, pcert
, pcert_length
, local_key
, 0);
509 else if (cred
->get_cert_callback
)
511 ret
= cred
->get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
512 pk_algos
, pk_algos_length
, &st2
);
516 { /* compatibility mode */
518 memset (&st
, 0, sizeof (st
));
519 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
521 if (cred
->server_get_cert_callback
== NULL
)
524 return GNUTLS_E_INTERNAL_ERROR
;
526 ret
= cred
->server_get_cert_callback (session
, &st
);
528 st_to_st2 (&st2
, &st
);
533 if (cred
->client_get_cert_callback
== NULL
)
536 return GNUTLS_E_INTERNAL_ERROR
;
538 ret
= cred
->client_get_cert_callback (session
,
539 issuers_dn
, issuers_dn_length
,
540 pk_algos
, pk_algos_length
,
543 st_to_st2 (&st2
, &st
);
550 return GNUTLS_E_USER_ERROR
;
554 return 0; /* no certificate was selected */
556 if (type
!= st2
.cert_type
)
559 ret
= GNUTLS_E_INVALID_REQUEST
;
564 if (type
== GNUTLS_CRT_X509
)
566 local_certs
= alloc_and_load_x509_certs (st2
.cert
.x509
, st2
.ncerts
);
573 ret
= GNUTLS_E_INVALID_REQUEST
;
576 #ifdef ENABLE_OPENPGP
578 local_certs
= alloc_and_load_pgp_certs (st2
.cert
.pgp
);
581 ret
= GNUTLS_E_UNIMPLEMENTED_FEATURE
;
586 if (local_certs
== NULL
)
589 ret
= GNUTLS_E_MEMORY_ERROR
;
593 switch (st2
.key_type
)
595 case GNUTLS_PRIVKEY_OPENPGP
:
596 #ifdef ENABLE_OPENPGP
597 if (st2
.key
.pgp
!= NULL
)
599 local_key
= alloc_and_load_pgp_key (st2
.key
.pgp
, st2
.deinit_all
);
600 if (local_key
== NULL
)
603 ret
= GNUTLS_E_INTERNAL_ERROR
;
609 case GNUTLS_PRIVKEY_PKCS11
:
611 if (st2
.key
.pkcs11
!= NULL
)
614 alloc_and_load_pkcs11_key (st2
.key
.pkcs11
, st2
.deinit_all
);
615 if (local_key
== NULL
)
618 ret
= GNUTLS_E_INTERNAL_ERROR
;
624 case GNUTLS_PRIVKEY_X509
:
625 if (st2
.key
.x509
!= NULL
)
627 local_key
= alloc_and_load_x509_key (st2
.key
.x509
, st2
.deinit_all
);
628 if (local_key
== NULL
)
631 ret
= GNUTLS_E_INTERNAL_ERROR
;
638 ret
= GNUTLS_E_INVALID_REQUEST
;
642 _gnutls_selected_certs_set (session
, local_certs
,
643 (local_certs
!= NULL
) ? st2
.ncerts
: 0,
650 if (st2
.cert_type
== GNUTLS_CRT_X509
)
654 for (i
= 0; i
< st2
.ncerts
; i
++)
656 gnutls_x509_crt_deinit (st2
.cert
.x509
[i
]);
658 gnutls_free(st2
.cert
.x509
);
663 #ifdef ENABLE_OPENPGP
666 gnutls_openpgp_crt_deinit (st2
.cert
.pgp
);
673 if (local_key
!= NULL
)
674 gnutls_privkey_deinit (local_key
);
680 /* Finds the appropriate certificate depending on the cA Distinguished name
681 * advertized by the server. If none matches then returns 0 and -1 as index.
682 * In case of an error a negative error code, is returned.
684 * 20020128: added ability to select a certificate depending on the SIGN
685 * algorithm (only in automatic mode).
688 _select_client_cert (gnutls_session_t session
,
689 uint8_t * _data
, size_t _data_size
,
690 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
694 gnutls_certificate_credentials_t cred
;
695 uint8_t *data
= _data
;
696 ssize_t data_size
= _data_size
;
697 int issuers_dn_length
;
698 gnutls_datum_t
*issuers_dn
= NULL
;
700 cred
= (gnutls_certificate_credentials_t
)
701 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
705 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
708 if (cred
->client_get_cert_callback
!= NULL
709 || cred
->get_cert_callback
!= NULL
|| cred
->get_cert_callback2
!= NULL
)
712 /* use a callback to get certificate
714 if (session
->security_parameters
.cert_type
!= GNUTLS_CRT_X509
)
715 issuers_dn_length
= 0;
718 issuers_dn_length
= get_issuers_num (session
, data
, data_size
);
719 if (issuers_dn_length
< 0)
722 return issuers_dn_length
;
725 if (issuers_dn_length
> 0)
728 gnutls_malloc (sizeof (gnutls_datum_t
) * issuers_dn_length
);
729 if (issuers_dn
== NULL
)
732 return GNUTLS_E_MEMORY_ERROR
;
736 get_issuers (session
, issuers_dn
, issuers_dn_length
,
747 call_get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
748 pk_algos
, pk_algos_length
);
754 /* If we have no callbacks, try to guess.
758 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
)
760 _find_x509_cert (cred
, _data
, _data_size
,
761 pk_algos
, pk_algos_length
, &indx
);
762 #ifdef ENABLE_OPENPGP
763 else if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
)
764 result
= _find_openpgp_cert (cred
, pk_algos
, pk_algos_length
, &indx
);
775 _gnutls_selected_certs_set (session
,
776 &cred
->certs
[indx
].cert_list
[0],
777 cred
->certs
[indx
].cert_list_length
,
778 cred
->pkey
[indx
], 0);
782 _gnutls_selected_certs_set (session
, NULL
, 0, NULL
, 0);
789 gnutls_free (issuers_dn
);
794 /* Generate client certificate
798 _gnutls_gen_x509_crt (gnutls_session_t session
, gnutls_buffer_st
* data
)
801 gnutls_pcert_st
*apr_cert_list
;
802 gnutls_privkey_t apr_pkey
;
803 int apr_cert_list_length
;
805 /* find the appropriate certificate
808 _gnutls_get_selected_cert (session
, &apr_cert_list
,
809 &apr_cert_list_length
, &apr_pkey
)) < 0)
816 for (i
= 0; i
< apr_cert_list_length
; i
++)
818 ret
+= apr_cert_list
[i
].cert
.size
+ 3;
823 /* if no certificates were found then send:
824 * 0B 00 00 03 00 00 00 // Certificate with no certs
826 * 0B 00 00 00 // empty certificate handshake
828 * ( the above is the whole handshake message, not
829 * the one produced here )
832 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
834 return gnutls_assert_val (ret
);
836 for (i
= 0; i
< apr_cert_list_length
; i
++)
839 _gnutls_buffer_append_data_prefix (data
, 24,
840 apr_cert_list
[i
].cert
.data
,
841 apr_cert_list
[i
].cert
.size
);
843 return gnutls_assert_val (ret
);
849 enum PGPKeyDescriptorType
850 { PGP_KEY_FINGERPRINT
, PGP_KEY
, PGP_KEY_SUBKEY
, PGP_KEY_FINGERPRINT_SUBKEY
};
852 #ifdef ENABLE_OPENPGP
854 _gnutls_gen_openpgp_certificate (gnutls_session_t session
,
855 gnutls_buffer_st
* data
)
858 gnutls_pcert_st
*apr_cert_list
;
859 gnutls_privkey_t apr_pkey
;
860 int apr_cert_list_length
;
864 unsigned int use_subkey
= 0;
866 /* find the appropriate certificate */
868 _gnutls_get_selected_cert (session
, &apr_cert_list
,
869 &apr_cert_list_length
, &apr_pkey
)) < 0)
879 if (apr_cert_list_length
> 0)
881 fpr_size
= sizeof (fpr
);
883 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
884 &fpr_size
, &use_subkey
);
886 return gnutls_assert_val (ret
);
889 ret
+= 1 + fpr_size
; /* for the keyid */
891 ret
+= apr_cert_list
[0].cert
.size
;
894 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
896 return gnutls_assert_val (ret
);
899 if (apr_cert_list_length
> 0)
903 type
= PGP_KEY_SUBKEY
;
905 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
907 return gnutls_assert_val (ret
);
909 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
911 return gnutls_assert_val (ret
);
916 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
918 return gnutls_assert_val (ret
);
922 _gnutls_buffer_append_data_prefix (data
, 24,
923 apr_cert_list
[0].cert
.data
,
924 apr_cert_list
[0].cert
.size
);
926 return gnutls_assert_val (ret
);
928 else /* empty - no certificate */
932 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
934 return gnutls_assert_val (ret
);
936 ret
= _gnutls_buffer_append_prefix (data
, 24, 0);
938 return gnutls_assert_val (ret
);
945 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session
,
946 gnutls_buffer_st
* data
)
948 int ret
, packet_size
;
949 uint8_t type
, fpr
[20];
951 gnutls_pcert_st
*apr_cert_list
;
952 gnutls_privkey_t apr_pkey
;
953 int apr_cert_list_length
;
954 unsigned int use_subkey
= 0;
956 /* find the appropriate certificate */
958 _gnutls_get_selected_cert (session
, &apr_cert_list
,
959 &apr_cert_list_length
, &apr_pkey
)) < 0)
965 fpr_size
= sizeof (fpr
);
967 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
968 &fpr_size
, &use_subkey
);
970 return gnutls_assert_val (ret
);
975 packet_size
+= 1 + fpr_size
; /* for the keyid */
977 /* Only v4 fingerprints are sent
979 if (apr_cert_list_length
> 0)
980 packet_size
+= 20 + 1;
981 else /* empty certificate case */
982 return _gnutls_gen_openpgp_certificate (session
, data
);
984 ret
= _gnutls_buffer_append_prefix (data
, 24, packet_size
- 3);
986 return gnutls_assert_val (ret
);
990 type
= PGP_KEY_FINGERPRINT_SUBKEY
;
991 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
993 return gnutls_assert_val (ret
);
995 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
997 return gnutls_assert_val (ret
);
1001 type
= PGP_KEY_FINGERPRINT
; /* key fingerprint */
1002 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
1004 return gnutls_assert_val (ret
);
1007 fpr_size
= sizeof (fpr
);
1009 _gnutls_openpgp_fingerprint (&apr_cert_list
[0].cert
, fpr
,
1016 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
1018 return gnutls_assert_val (ret
);
1020 return data
->length
;
1026 _gnutls_gen_cert_client_certificate (gnutls_session_t session
,
1027 gnutls_buffer_st
* data
)
1029 switch (session
->security_parameters
.cert_type
)
1031 #ifdef ENABLE_OPENPGP
1032 case GNUTLS_CRT_OPENPGP
:
1033 if (_gnutls_openpgp_send_fingerprint (session
) == 0)
1034 return _gnutls_gen_openpgp_certificate (session
, data
);
1036 return _gnutls_gen_openpgp_certificate_fpr (session
, data
);
1038 case GNUTLS_CRT_X509
:
1039 return _gnutls_gen_x509_crt (session
, data
);
1043 return GNUTLS_E_INTERNAL_ERROR
;
1048 _gnutls_gen_cert_server_certificate (gnutls_session_t session
,
1049 gnutls_buffer_st
* data
)
1051 switch (session
->security_parameters
.cert_type
)
1053 #ifdef ENABLE_OPENPGP
1054 case GNUTLS_CRT_OPENPGP
:
1055 return _gnutls_gen_openpgp_certificate (session
, data
);
1057 case GNUTLS_CRT_X509
:
1058 return _gnutls_gen_x509_crt (session
, data
);
1061 return GNUTLS_E_INTERNAL_ERROR
;
1065 /* Process server certificate
1068 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1070 _gnutls_proc_x509_server_certificate (gnutls_session_t session
,
1071 uint8_t * data
, size_t data_size
)
1075 cert_auth_info_t info
;
1076 gnutls_certificate_credentials_t cred
;
1077 ssize_t dsize
= data_size
;
1079 gnutls_pcert_st
*peer_certificate_list
;
1080 size_t peer_certificate_list_size
= 0, j
, x
;
1083 cred
= (gnutls_certificate_credentials_t
)
1084 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1088 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1093 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1094 sizeof (cert_auth_info_st
), 1)) < 0)
1100 info
= _gnutls_get_auth_info (session
);
1102 if (data
== NULL
|| data_size
== 0)
1105 /* no certificate was sent */
1106 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1109 DECR_LEN (dsize
, 3);
1110 size
= _gnutls_read_uint24 (p
);
1113 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1114 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1116 if (size
== 0 || size
== 3)
1119 /* no certificate was sent */
1120 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1126 DECR_LEN (dsize
, 3);
1127 len
= _gnutls_read_uint24 (p
);
1129 DECR_LEN (dsize
, len
);
1130 peer_certificate_list_size
++;
1135 if (peer_certificate_list_size
== 0)
1138 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1141 /* Ok we now allocate the memory to hold the
1145 peer_certificate_list
=
1147 sizeof (gnutls_pcert_st
) * (peer_certificate_list_size
));
1148 if (peer_certificate_list
== NULL
)
1151 return GNUTLS_E_MEMORY_ERROR
;
1156 /* Now we start parsing the list (again).
1157 * We don't use DECR_LEN since the list has
1158 * been parsed before.
1161 for (j
= 0; j
< peer_certificate_list_size
; j
++)
1163 len
= _gnutls_read_uint24 (p
);
1170 gnutls_pcert_import_x509_raw (&peer_certificate_list
1171 [j
], &tmp
, GNUTLS_X509_FMT_DER
, 0);
1175 peer_certificate_list_size
= j
;
1184 _gnutls_copy_certificate_auth_info (info
,
1185 peer_certificate_list
,
1186 peer_certificate_list_size
, 0,
1194 _gnutls_check_key_usage (&peer_certificate_list
[0],
1195 gnutls_kx_get (session
))) < 0)
1205 gnutls_free (peer_certificate_list
);
1210 #ifdef ENABLE_OPENPGP
1212 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session
,
1213 uint8_t * data
, size_t data_size
)
1217 cert_auth_info_t info
;
1218 gnutls_certificate_credentials_t cred
;
1219 ssize_t dsize
= data_size
;
1221 gnutls_pcert_st
*peer_certificate_list
= NULL
;
1222 int peer_certificate_list_size
= 0;
1223 gnutls_datum_t tmp
, akey
= { NULL
, 0 };
1224 uint8_t subkey_id
[GNUTLS_OPENPGP_KEYID_SIZE
];
1225 unsigned int subkey_id_set
= 0;
1227 cred
= (gnutls_certificate_credentials_t
)
1228 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1232 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1236 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1237 sizeof (cert_auth_info_st
), 1)) < 0)
1243 info
= _gnutls_get_auth_info (session
);
1245 if (data
== NULL
|| data_size
== 0)
1248 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1251 DECR_LEN (dsize
, 3);
1252 size
= _gnutls_read_uint24 (p
);
1258 /* no certificate was sent */
1259 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1262 /* Read PGPKeyDescriptor */
1263 DECR_LEN (dsize
, 1);
1267 /* Try to read the keyid if present */
1268 if (key_type
== PGP_KEY_FINGERPRINT_SUBKEY
|| key_type
== PGP_KEY_SUBKEY
)
1271 if (*p
!= GNUTLS_OPENPGP_KEYID_SIZE
)
1274 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1277 DECR_LEN (dsize
, 1);
1280 DECR_LEN (dsize
, GNUTLS_OPENPGP_KEYID_SIZE
);
1281 memcpy (subkey_id
, p
, GNUTLS_OPENPGP_KEYID_SIZE
);
1282 p
+= GNUTLS_OPENPGP_KEYID_SIZE
;
1288 /* read the actual key or fingerprint */
1289 if (key_type
== PGP_KEY_FINGERPRINT
1290 || key_type
== PGP_KEY_FINGERPRINT_SUBKEY
)
1291 { /* the fingerprint */
1293 DECR_LEN (dsize
, 1);
1294 len
= (uint8_t) * p
;
1300 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED
;
1303 DECR_LEN (dsize
, 20);
1305 /* request the actual key from our database, or
1306 * a key server or anything.
1309 _gnutls_openpgp_request_key (session
, &akey
, cred
, p
, 20)) < 0)
1315 peer_certificate_list_size
++;
1318 else if (key_type
== PGP_KEY
|| key_type
== PGP_KEY_SUBKEY
)
1319 { /* the whole key */
1321 /* Read the actual certificate */
1322 DECR_LEN (dsize
, 3);
1323 len
= _gnutls_read_uint24 (p
);
1329 /* no certificate was sent */
1330 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1333 DECR_LEN (dsize
, len
);
1334 peer_certificate_list_size
++;
1343 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1346 /* ok we now have the peer's key in tmp datum
1349 if (peer_certificate_list_size
== 0)
1352 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1355 peer_certificate_list
=
1357 sizeof (gnutls_pcert_st
) * (peer_certificate_list_size
));
1358 if (peer_certificate_list
== NULL
)
1361 ret
= GNUTLS_E_MEMORY_ERROR
;
1366 gnutls_pcert_import_openpgp_raw (&peer_certificate_list
[0],
1368 GNUTLS_OPENPGP_FMT_RAW
,
1369 (subkey_id_set
!= 0) ? subkey_id
: NULL
,
1378 _gnutls_copy_certificate_auth_info (info
,
1379 peer_certificate_list
,
1380 peer_certificate_list_size
,
1383 0) ? subkey_id
: NULL
);
1391 _gnutls_check_key_usage (&peer_certificate_list
[0],
1392 gnutls_kx_get (session
))) < 0)
1402 _gnutls_free_datum (&akey
);
1404 gnutls_free (peer_certificate_list
);
1411 _gnutls_proc_certificate (gnutls_session_t session
,
1412 uint8_t * data
, size_t data_size
)
1415 gnutls_certificate_credentials_t cred
;
1418 (gnutls_certificate_credentials_t
) _gnutls_get_cred (session
->key
,
1419 GNUTLS_CRD_CERTIFICATE
,
1424 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1427 switch (session
->security_parameters
.cert_type
)
1429 #ifdef ENABLE_OPENPGP
1430 case GNUTLS_CRT_OPENPGP
:
1431 ret
= _gnutls_proc_openpgp_server_certificate (session
,
1435 case GNUTLS_CRT_X509
:
1436 ret
= _gnutls_proc_x509_server_certificate (session
, data
, data_size
);
1440 return GNUTLS_E_INTERNAL_ERROR
;
1443 if (ret
== 0 && cred
->verify_callback
!= NULL
)
1445 ret
= cred
->verify_callback (session
);
1447 ret
= GNUTLS_E_CERTIFICATE_ERROR
;
1454 /* Checks if we support the given signature algorithm
1455 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1459 _gnutls_check_supported_sign_algo (CertificateSigType algo
)
1464 return GNUTLS_PK_RSA
;
1466 return GNUTLS_PK_DSA
;
1468 return GNUTLS_PK_EC
;
1475 _gnutls_proc_cert_cert_req (gnutls_session_t session
, uint8_t * data
,
1480 gnutls_certificate_credentials_t cred
;
1483 gnutls_pk_algorithm_t pk_algos
[MAX_CLIENT_SIGN_ALGOS
];
1484 int pk_algos_length
;
1485 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1487 cred
= (gnutls_certificate_credentials_t
)
1488 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1492 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1496 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1497 sizeof (cert_auth_info_st
), 0)) < 0)
1506 DECR_LEN (dsize
, 1);
1509 /* check if the sign algorithm is supported.
1511 pk_algos_length
= 0;
1512 for (i
= 0; i
< size
; i
++, p
++)
1514 DECR_LEN (dsize
, 1);
1515 if ((ret
= _gnutls_check_supported_sign_algo (*p
)) > 0)
1517 if (pk_algos_length
< MAX_CLIENT_SIGN_ALGOS
)
1519 pk_algos
[pk_algos_length
++] = ret
;
1524 if (pk_algos_length
== 0)
1527 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1530 if (_gnutls_version_has_selectable_sighash (ver
))
1532 /* read supported hashes */
1534 DECR_LEN (dsize
, 2);
1535 hash_num
= _gnutls_read_uint16 (p
);
1537 DECR_LEN (dsize
, hash_num
);
1539 ret
= _gnutls_sign_algorithm_parse_data (session
, p
, hash_num
);
1549 /* read the certificate authorities */
1550 DECR_LEN (dsize
, 2);
1551 size
= _gnutls_read_uint16 (p
);
1554 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
1558 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1561 DECR_LEN (dsize
, size
);
1563 /* now we ask the user to tell which one
1567 _select_client_cert (session
, p
, size
, pk_algos
, pk_algos_length
)) < 0)
1573 /* We should reply with a certificate message,
1574 * even if we have no certificate to send.
1576 session
->key
->certificate_requested
= 1;
1582 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session
,
1583 gnutls_buffer_st
* data
)
1586 gnutls_pcert_st
*apr_cert_list
;
1587 gnutls_privkey_t apr_pkey
;
1588 int apr_cert_list_length
;
1589 gnutls_datum_t signature
= { NULL
, 0 };
1591 gnutls_sign_algorithm_t sign_algo
;
1592 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1594 /* find the appropriate certificate */
1596 _gnutls_get_selected_cert (session
, &apr_cert_list
,
1597 &apr_cert_list_length
, &apr_pkey
)) < 0)
1603 if (apr_cert_list_length
> 0)
1606 _gnutls_handshake_sign_cert_vrfy (session
,
1608 apr_pkey
, &signature
)) < 0)
1620 total_data
= signature
.size
+ 2;
1622 /* add hash and signature algorithms */
1623 if (_gnutls_version_has_selectable_sighash (ver
))
1628 if (_gnutls_version_has_selectable_sighash (ver
))
1630 const sign_algorithm_st
*aid
;
1632 /* error checking is not needed here since we have used those algorithms */
1633 aid
= _gnutls_sign_to_tls_aid (sign_algo
);
1635 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM
);
1637 p
[0] = aid
->hash_algorithm
;
1638 p
[1] = aid
->sign_algorithm
;
1639 ret
= _gnutls_buffer_append_data (data
, p
, 2);
1648 _gnutls_buffer_append_data_prefix (data
, 16, signature
.data
,
1659 _gnutls_free_datum (&signature
);
1664 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session
,
1665 uint8_t * data
, size_t data_size
)
1668 ssize_t dsize
= data_size
;
1669 uint8_t *pdata
= data
;
1671 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
1672 gnutls_pcert_st peer_cert
;
1673 gnutls_sign_algorithm_t sign_algo
= GNUTLS_SIGN_UNKNOWN
;
1674 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1676 if (info
== NULL
|| info
->ncerts
== 0)
1679 /* we need this in order to get peer's certificate */
1680 return GNUTLS_E_INTERNAL_ERROR
;
1683 if (_gnutls_version_has_selectable_sighash (ver
))
1685 sign_algorithm_st aid
;
1687 DECR_LEN (dsize
, 2);
1688 aid
.hash_algorithm
= pdata
[0];
1689 aid
.sign_algorithm
= pdata
[1];
1691 sign_algo
= _gnutls_tls_aid_to_sign (&aid
);
1692 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
1695 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1700 ret
= _gnutls_session_sign_algo_enabled (session
, sign_algo
);
1704 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1707 DECR_LEN (dsize
, 2);
1708 size
= _gnutls_read_uint16 (pdata
);
1711 DECR_LEN (dsize
, size
);
1716 ret
= _gnutls_get_auth_info_pcert (&peer_cert
,
1717 session
->security_parameters
.cert_type
,
1727 _gnutls_handshake_verify_cert_vrfy (session
, &peer_cert
, &sig
,
1731 gnutls_pcert_deinit (&peer_cert
);
1734 gnutls_pcert_deinit (&peer_cert
);
1740 _gnutls_gen_cert_server_cert_req (gnutls_session_t session
,
1741 gnutls_buffer_st
* data
)
1743 gnutls_certificate_credentials_t cred
;
1745 uint8_t tmp_data
[CERTTYPE_SIZE
];
1746 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1748 /* Now we need to generate the RDN sequence. This is
1749 * already in the CERTIFICATE_CRED structure, to improve
1753 cred
= (gnutls_certificate_credentials_t
)
1754 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1758 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1761 size
= CERTTYPE_SIZE
+ 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1764 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1765 session
->internals
.ignore_rdn_sequence
== 0)
1766 size
+= cred
->x509_rdn_sequence
.size
;
1768 if (_gnutls_version_has_selectable_sighash (ver
))
1769 /* Need two bytes to announce the number of supported hash
1770 functions (see below). */
1771 size
+= MAX_SIGN_ALGO_SIZE
;
1773 tmp_data
[0] = CERTTYPE_SIZE
- 1;
1774 tmp_data
[1] = RSA_SIGN
;
1775 tmp_data
[2] = DSA_SIGN
;
1776 tmp_data
[3] = ECDSA_SIGN
; /* only these for now */
1778 ret
= _gnutls_buffer_append_data (data
, tmp_data
, CERTTYPE_SIZE
);
1780 return gnutls_assert_val (ret
);
1782 if (_gnutls_version_has_selectable_sighash (ver
))
1784 uint8_t p
[MAX_SIGN_ALGO_SIZE
];
1787 _gnutls_sign_algorithm_write_params (session
, p
, MAX_SIGN_ALGO_SIZE
);
1794 /* recalculate size */
1795 size
-= MAX_SIGN_ALGO_SIZE
+ ret
;
1797 ret
= _gnutls_buffer_append_data (data
, p
, ret
);
1799 return gnutls_assert_val (ret
);
1802 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1803 session
->internals
.ignore_rdn_sequence
== 0)
1806 _gnutls_buffer_append_data_prefix (data
, 16,
1807 cred
->x509_rdn_sequence
.data
,
1808 cred
->x509_rdn_sequence
.size
);
1810 return gnutls_assert_val (ret
);
1814 ret
= _gnutls_buffer_append_prefix (data
, 16, 0);
1816 return gnutls_assert_val (ret
);
1819 return data
->length
;
1823 /* This function will return the appropriate certificate to use.
1824 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1825 * The return value is a negative error code on error.
1827 * It is normal to return 0 with no certificates in client side.
1831 _gnutls_get_selected_cert (gnutls_session_t session
,
1832 gnutls_pcert_st
** apr_cert_list
,
1833 int *apr_cert_list_length
,
1834 gnutls_privkey_t
* apr_pkey
)
1836 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
1839 /* select_client_cert() has been called before.
1842 *apr_cert_list
= session
->internals
.selected_cert_list
;
1843 *apr_pkey
= session
->internals
.selected_key
;
1844 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1846 if (*apr_cert_list_length
== 0 || *apr_cert_list
== NULL
)
1849 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1857 /* we have already decided which certificate
1860 *apr_cert_list
= session
->internals
.selected_cert_list
;
1861 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1862 *apr_pkey
= session
->internals
.selected_key
;
1869 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1872 static gnutls_pcert_st
*
1873 alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
, unsigned ncerts
)
1875 gnutls_pcert_st
*local_certs
;
1882 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
) * ncerts
);
1883 if (local_certs
== NULL
)
1889 for (i
= 0; i
< ncerts
; i
++)
1891 ret
= gnutls_pcert_import_x509 (&local_certs
[i
], certs
[i
], 0);
1899 for (j
= 0; j
< i
; j
++)
1901 gnutls_pcert_deinit (&local_certs
[j
]);
1903 gnutls_free (local_certs
);
1910 /* converts the given x509 key to gnutls_privkey* and allocates
1913 static gnutls_privkey_t
1914 alloc_and_load_x509_key (gnutls_x509_privkey_t key
, int deinit
)
1916 gnutls_privkey_t local_key
;
1922 ret
= gnutls_privkey_init (&local_key
);
1930 gnutls_privkey_import_x509 (local_key
, key
,
1931 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
:
1936 gnutls_privkey_deinit (local_key
);
1943 /* converts the given pgp certificate to gnutls_cert* and allocates
1946 #ifdef ENABLE_OPENPGP
1947 static gnutls_pcert_st
*
1948 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
)
1950 gnutls_pcert_st
*local_certs
;
1956 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
));
1957 if (local_certs
== NULL
)
1963 ret
= gnutls_pcert_import_openpgp (local_certs
, cert
, 0);
1973 gnutls_pcert_deinit (local_certs
);
1974 gnutls_free (local_certs
);
1981 /* converts the given raw key to gnutls_privkey* and allocates
1984 static gnutls_privkey_t
1985 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key
, int deinit
)
1987 gnutls_privkey_t local_key
;
1993 ret
= gnutls_privkey_init (&local_key
);
2001 gnutls_privkey_import_openpgp (local_key
, key
,
2002 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2007 gnutls_privkey_deinit (local_key
);
2015 #ifdef ENABLE_PKCS11
2017 /* converts the given raw key to gnutls_privkey* and allocates
2020 static gnutls_privkey_t
2021 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key
, int deinit
)
2023 gnutls_privkey_t local_key
;
2029 ret
= gnutls_privkey_init (&local_key
);
2037 gnutls_privkey_import_pkcs11 (local_key
, key
,
2038 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2043 gnutls_privkey_deinit (local_key
);
2053 _gnutls_selected_certs_deinit (gnutls_session_t session
)
2055 if (session
->internals
.selected_need_free
!= 0)
2059 for (i
= 0; i
< session
->internals
.selected_cert_list_length
; i
++)
2061 gnutls_pcert_deinit (&session
->internals
.selected_cert_list
[i
]);
2063 gnutls_free (session
->internals
.selected_cert_list
);
2064 session
->internals
.selected_cert_list
= NULL
;
2065 session
->internals
.selected_cert_list_length
= 0;
2067 gnutls_privkey_deinit(session
->internals
.selected_key
);
2068 session
->internals
.selected_key
= NULL
;
2075 _gnutls_selected_certs_set (gnutls_session_t session
,
2076 gnutls_pcert_st
* certs
, int ncerts
,
2077 gnutls_privkey_t key
, int need_free
)
2079 _gnutls_selected_certs_deinit (session
);
2081 session
->internals
.selected_cert_list
= certs
;
2082 session
->internals
.selected_cert_list_length
= ncerts
;
2083 session
->internals
.selected_key
= key
;
2084 session
->internals
.selected_need_free
= need_free
;
2088 static void get_server_name(gnutls_session_t session
, uint8_t* name
, size_t max_name_size
)
2095 for (i
=0; !(ret
<0);i
++)
2097 max_name
= max_name_size
;
2098 ret
= gnutls_server_name_get (session
, name
, &max_name
, &type
, i
);
2099 if (ret
>= 0 && type
== GNUTLS_NAME_DNS
)
2108 /* finds the most appropriate certificate in the cert list.
2109 * The 'appropriate' is defined by the user.
2111 * requested_algo holds the parameters required by the peer (RSA, DSA
2114 * Returns 0 on success and a negative error code on error. The
2115 * selected certificate will be in session->internals.selected_*.
2119 _gnutls_server_select_cert (gnutls_session_t session
,
2120 gnutls_pk_algorithm_t
* pk_algos
,
2121 size_t pk_algos_size
)
2125 gnutls_certificate_credentials_t cred
;
2126 char server_name
[MAX_CN
];
2128 cred
= (gnutls_certificate_credentials_t
)
2129 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
2133 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2136 /* If the callback which retrieves certificate has been set,
2139 if (cred
->server_get_cert_callback
|| cred
->get_cert_callback
2140 || cred
->get_cert_callback2
)
2142 ret
= call_get_cert_callback (session
, NULL
, 0, NULL
, 0);
2144 return gnutls_assert_val (ret
);
2150 get_server_name(session
, (unsigned char*)server_name
, sizeof(server_name
));
2152 idx
= -1; /* default is use no certificate */
2154 /* find certificates that match the requested server_name
2157 if (server_name
[0] != 0)
2159 for (i
= 0; i
< cred
->ncerts
; i
++)
2161 if (cred
->certs
[i
].names
!= NULL
&& _gnutls_str_array_match(cred
->certs
[i
].names
, server_name
) != 0)
2163 /* if requested algorithms are also compatible select it */
2164 gnutls_pk_algorithm pk
=
2165 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2168 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name
,
2169 gnutls_certificate_type_get_name (session
->security_parameters
.cert_type
),
2170 session
->security_parameters
.cert_type
);
2172 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2174 for (j
= 0; j
< pk_algos_size
; j
++)
2175 if (pk_algos
[j
] == pk
)
2185 for (j
= 0; j
< pk_algos_size
; j
++)
2187 _gnutls_handshake_log
2188 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2189 session
, gnutls_pk_get_name (pk_algos
[j
]), pk_algos
[j
],
2190 gnutls_certificate_type_get_name (session
->security_parameters
.
2192 session
->security_parameters
.cert_type
);
2194 for (i
= 0; i
< cred
->ncerts
; i
++)
2196 gnutls_pk_algorithm pk
=
2197 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2199 /* find one compatible certificate
2201 _gnutls_handshake_log
2202 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2203 session
, i
, gnutls_pk_get_name (pk
), pk
,
2204 gnutls_certificate_type_get_name (cred
->certs
[i
].cert_list
[0].type
),
2205 cred
->certs
[i
].cert_list
[0].type
);
2207 if (pk_algos
[j
] == pk
)
2209 /* if cert type matches
2212 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2222 /* store the certificate pointer for future use, in the handshake.
2223 * (This will allow not calling this callback again.)
2228 _gnutls_selected_certs_set (session
,
2229 &cred
->certs
[idx
].cert_list
[0],
2230 cred
->certs
[idx
].cert_list_length
,
2231 cred
->pkey
[idx
], 0);
2236 /* Certificate does not support REQUESTED_ALGO. */
2237 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2243 /* Frees the rsa_info_st structure.
2246 _gnutls_free_rsa_info (rsa_info_st
* rsa
)
2248 _gnutls_free_datum (&rsa
->modulus
);
2249 _gnutls_free_datum (&rsa
->exponent
);