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 certificate message
797 _gnutls_gen_x509_crt (gnutls_session_t session
, gnutls_buffer_st
* data
)
800 gnutls_pcert_st
*apr_cert_list
;
801 gnutls_privkey_t apr_pkey
;
802 int apr_cert_list_length
;
804 /* find the appropriate certificate
807 _gnutls_get_selected_cert (session
, &apr_cert_list
,
808 &apr_cert_list_length
, &apr_pkey
)) < 0)
815 for (i
= 0; i
< apr_cert_list_length
; i
++)
817 ret
+= apr_cert_list
[i
].cert
.size
+ 3;
822 /* if no certificates were found then send:
823 * 0B 00 00 03 00 00 00 // Certificate with no certs
825 * 0B 00 00 00 // empty certificate handshake
827 * ( the above is the whole handshake message, not
828 * the one produced here )
831 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
833 return gnutls_assert_val (ret
);
835 for (i
= 0; i
< apr_cert_list_length
; i
++)
838 _gnutls_buffer_append_data_prefix (data
, 24,
839 apr_cert_list
[i
].cert
.data
,
840 apr_cert_list
[i
].cert
.size
);
842 return gnutls_assert_val (ret
);
848 enum PGPKeyDescriptorType
849 { PGP_KEY_FINGERPRINT
, PGP_KEY
, PGP_KEY_SUBKEY
, PGP_KEY_FINGERPRINT_SUBKEY
};
851 #ifdef ENABLE_OPENPGP
853 _gnutls_gen_openpgp_certificate (gnutls_session_t session
,
854 gnutls_buffer_st
* data
)
857 gnutls_pcert_st
*apr_cert_list
;
858 gnutls_privkey_t apr_pkey
;
859 int apr_cert_list_length
;
863 unsigned int use_subkey
= 0;
865 /* find the appropriate certificate */
867 _gnutls_get_selected_cert (session
, &apr_cert_list
,
868 &apr_cert_list_length
, &apr_pkey
)) < 0)
878 if (apr_cert_list_length
> 0)
880 fpr_size
= sizeof (fpr
);
882 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
883 &fpr_size
, &use_subkey
);
885 return gnutls_assert_val (ret
);
888 ret
+= 1 + fpr_size
; /* for the keyid */
890 ret
+= apr_cert_list
[0].cert
.size
;
893 ret
= _gnutls_buffer_append_prefix (data
, 24, ret
- 3);
895 return gnutls_assert_val (ret
);
898 if (apr_cert_list_length
> 0)
902 type
= PGP_KEY_SUBKEY
;
904 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
906 return gnutls_assert_val (ret
);
908 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
910 return gnutls_assert_val (ret
);
915 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
917 return gnutls_assert_val (ret
);
921 _gnutls_buffer_append_data_prefix (data
, 24,
922 apr_cert_list
[0].cert
.data
,
923 apr_cert_list
[0].cert
.size
);
925 return gnutls_assert_val (ret
);
927 else /* empty - no certificate */
931 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
933 return gnutls_assert_val (ret
);
935 ret
= _gnutls_buffer_append_prefix (data
, 24, 0);
937 return gnutls_assert_val (ret
);
944 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session
,
945 gnutls_buffer_st
* data
)
947 int ret
, packet_size
;
948 uint8_t type
, fpr
[20];
950 gnutls_pcert_st
*apr_cert_list
;
951 gnutls_privkey_t apr_pkey
;
952 int apr_cert_list_length
;
953 unsigned int use_subkey
= 0;
955 /* find the appropriate certificate */
957 _gnutls_get_selected_cert (session
, &apr_cert_list
,
958 &apr_cert_list_length
, &apr_pkey
)) < 0)
964 fpr_size
= sizeof (fpr
);
966 gnutls_pubkey_get_openpgp_key_id (apr_cert_list
[0].pubkey
, 0, fpr
,
967 &fpr_size
, &use_subkey
);
969 return gnutls_assert_val (ret
);
974 packet_size
+= 1 + fpr_size
; /* for the keyid */
976 /* Only v4 fingerprints are sent
978 if (apr_cert_list_length
> 0)
979 packet_size
+= 20 + 1;
980 else /* empty certificate case */
981 return _gnutls_gen_openpgp_certificate (session
, data
);
983 ret
= _gnutls_buffer_append_prefix (data
, 24, packet_size
- 3);
985 return gnutls_assert_val (ret
);
989 type
= PGP_KEY_FINGERPRINT_SUBKEY
;
990 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
992 return gnutls_assert_val (ret
);
994 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
996 return gnutls_assert_val (ret
);
1000 type
= PGP_KEY_FINGERPRINT
; /* key fingerprint */
1001 ret
= _gnutls_buffer_append_data (data
, &type
, 1);
1003 return gnutls_assert_val (ret
);
1006 fpr_size
= sizeof (fpr
);
1008 _gnutls_openpgp_fingerprint (&apr_cert_list
[0].cert
, fpr
,
1015 ret
= _gnutls_buffer_append_data_prefix (data
, 8, fpr
, fpr_size
);
1017 return gnutls_assert_val (ret
);
1019 return data
->length
;
1025 _gnutls_gen_cert_client_crt (gnutls_session_t session
,
1026 gnutls_buffer_st
* data
)
1028 switch (session
->security_parameters
.cert_type
)
1030 #ifdef ENABLE_OPENPGP
1031 case GNUTLS_CRT_OPENPGP
:
1032 if (_gnutls_openpgp_send_fingerprint (session
) == 0)
1033 return _gnutls_gen_openpgp_certificate (session
, data
);
1035 return _gnutls_gen_openpgp_certificate_fpr (session
, data
);
1037 case GNUTLS_CRT_X509
:
1038 return _gnutls_gen_x509_crt (session
, data
);
1042 return GNUTLS_E_INTERNAL_ERROR
;
1047 _gnutls_gen_cert_server_crt (gnutls_session_t session
,
1048 gnutls_buffer_st
* data
)
1050 switch (session
->security_parameters
.cert_type
)
1052 #ifdef ENABLE_OPENPGP
1053 case GNUTLS_CRT_OPENPGP
:
1054 return _gnutls_gen_openpgp_certificate (session
, data
);
1056 case GNUTLS_CRT_X509
:
1057 return _gnutls_gen_x509_crt (session
, data
);
1060 return GNUTLS_E_INTERNAL_ERROR
;
1064 /* Process server certificate
1067 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_pcert_deinit(&peer_certificate_list[x])
1069 _gnutls_proc_x509_server_crt (gnutls_session_t session
,
1070 uint8_t * data
, size_t data_size
)
1074 cert_auth_info_t info
;
1075 gnutls_certificate_credentials_t cred
;
1076 ssize_t dsize
= data_size
;
1078 gnutls_pcert_st
*peer_certificate_list
;
1079 size_t peer_certificate_list_size
= 0, j
, x
;
1082 cred
= (gnutls_certificate_credentials_t
)
1083 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1087 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1092 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1093 sizeof (cert_auth_info_st
), 1)) < 0)
1099 info
= _gnutls_get_auth_info (session
);
1101 if (data
== NULL
|| data_size
== 0)
1104 /* no certificate was sent */
1105 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1108 DECR_LEN (dsize
, 3);
1109 size
= _gnutls_read_uint24 (p
);
1112 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
1113 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
1115 if (size
== 0 || size
== 3)
1118 /* no certificate was sent */
1119 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1125 DECR_LEN (dsize
, 3);
1126 len
= _gnutls_read_uint24 (p
);
1128 DECR_LEN (dsize
, len
);
1129 peer_certificate_list_size
++;
1134 if (peer_certificate_list_size
== 0)
1137 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1140 /* Ok we now allocate the memory to hold the
1144 peer_certificate_list
=
1146 sizeof (gnutls_pcert_st
) * (peer_certificate_list_size
));
1147 if (peer_certificate_list
== NULL
)
1150 return GNUTLS_E_MEMORY_ERROR
;
1155 /* Now we start parsing the list (again).
1156 * We don't use DECR_LEN since the list has
1157 * been parsed before.
1160 for (j
= 0; j
< peer_certificate_list_size
; j
++)
1162 len
= _gnutls_read_uint24 (p
);
1169 gnutls_pcert_import_x509_raw (&peer_certificate_list
1170 [j
], &tmp
, GNUTLS_X509_FMT_DER
, 0);
1174 peer_certificate_list_size
= j
;
1183 _gnutls_copy_certificate_auth_info (info
,
1184 peer_certificate_list
,
1185 peer_certificate_list_size
, 0,
1193 _gnutls_check_key_usage (&peer_certificate_list
[0],
1194 gnutls_kx_get (session
))) < 0)
1204 gnutls_free (peer_certificate_list
);
1209 #ifdef ENABLE_OPENPGP
1211 _gnutls_proc_openpgp_server_crt (gnutls_session_t session
,
1212 uint8_t * data
, size_t data_size
)
1216 cert_auth_info_t info
;
1217 gnutls_certificate_credentials_t cred
;
1218 ssize_t dsize
= data_size
;
1220 gnutls_pcert_st
*peer_certificate_list
= NULL
;
1221 int peer_certificate_list_size
= 0;
1222 gnutls_datum_t tmp
, akey
= { NULL
, 0 };
1223 uint8_t subkey_id
[GNUTLS_OPENPGP_KEYID_SIZE
];
1224 unsigned int subkey_id_set
= 0;
1226 cred
= (gnutls_certificate_credentials_t
)
1227 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1231 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1235 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1236 sizeof (cert_auth_info_st
), 1)) < 0)
1242 info
= _gnutls_get_auth_info (session
);
1244 if (data
== NULL
|| data_size
== 0)
1247 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1250 DECR_LEN (dsize
, 3);
1251 size
= _gnutls_read_uint24 (p
);
1257 /* no certificate was sent */
1258 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1261 /* Read PGPKeyDescriptor */
1262 DECR_LEN (dsize
, 1);
1266 /* Try to read the keyid if present */
1267 if (key_type
== PGP_KEY_FINGERPRINT_SUBKEY
|| key_type
== PGP_KEY_SUBKEY
)
1270 if (*p
!= GNUTLS_OPENPGP_KEYID_SIZE
)
1273 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1276 DECR_LEN (dsize
, 1);
1279 DECR_LEN (dsize
, GNUTLS_OPENPGP_KEYID_SIZE
);
1280 memcpy (subkey_id
, p
, GNUTLS_OPENPGP_KEYID_SIZE
);
1281 p
+= GNUTLS_OPENPGP_KEYID_SIZE
;
1287 /* read the actual key or fingerprint */
1288 if (key_type
== PGP_KEY_FINGERPRINT
1289 || key_type
== PGP_KEY_FINGERPRINT_SUBKEY
)
1290 { /* the fingerprint */
1292 DECR_LEN (dsize
, 1);
1293 len
= (uint8_t) * p
;
1299 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED
;
1302 DECR_LEN (dsize
, 20);
1304 /* request the actual key from our database, or
1305 * a key server or anything.
1308 _gnutls_openpgp_request_key (session
, &akey
, cred
, p
, 20)) < 0)
1314 peer_certificate_list_size
++;
1317 else if (key_type
== PGP_KEY
|| key_type
== PGP_KEY_SUBKEY
)
1318 { /* the whole key */
1320 /* Read the actual certificate */
1321 DECR_LEN (dsize
, 3);
1322 len
= _gnutls_read_uint24 (p
);
1328 /* no certificate was sent */
1329 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1332 DECR_LEN (dsize
, len
);
1333 peer_certificate_list_size
++;
1342 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1345 /* ok we now have the peer's key in tmp datum
1348 if (peer_certificate_list_size
== 0)
1351 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1354 peer_certificate_list
=
1356 sizeof (gnutls_pcert_st
) * (peer_certificate_list_size
));
1357 if (peer_certificate_list
== NULL
)
1360 ret
= GNUTLS_E_MEMORY_ERROR
;
1365 gnutls_pcert_import_openpgp_raw (&peer_certificate_list
[0],
1367 GNUTLS_OPENPGP_FMT_RAW
,
1368 (subkey_id_set
!= 0) ? subkey_id
: NULL
,
1377 _gnutls_copy_certificate_auth_info (info
,
1378 peer_certificate_list
,
1379 peer_certificate_list_size
,
1382 0) ? subkey_id
: NULL
);
1390 _gnutls_check_key_usage (&peer_certificate_list
[0],
1391 gnutls_kx_get (session
))) < 0)
1401 _gnutls_free_datum (&akey
);
1403 gnutls_free (peer_certificate_list
);
1410 _gnutls_proc_crt (gnutls_session_t session
,
1411 uint8_t * data
, size_t data_size
)
1414 gnutls_certificate_credentials_t cred
;
1417 (gnutls_certificate_credentials_t
) _gnutls_get_cred (session
->key
,
1418 GNUTLS_CRD_CERTIFICATE
,
1423 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1426 switch (session
->security_parameters
.cert_type
)
1428 #ifdef ENABLE_OPENPGP
1429 case GNUTLS_CRT_OPENPGP
:
1430 ret
= _gnutls_proc_openpgp_server_crt (session
,
1434 case GNUTLS_CRT_X509
:
1435 ret
= _gnutls_proc_x509_server_crt (session
, data
, data_size
);
1439 return GNUTLS_E_INTERNAL_ERROR
;
1442 if (ret
== 0 && cred
->verify_callback
!= NULL
)
1444 ret
= cred
->verify_callback (session
);
1446 ret
= GNUTLS_E_CERTIFICATE_ERROR
;
1453 /* Checks if we support the given signature algorithm
1454 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1458 _gnutls_check_supported_sign_algo (CertificateSigType algo
)
1463 return GNUTLS_PK_RSA
;
1465 return GNUTLS_PK_DSA
;
1467 return GNUTLS_PK_EC
;
1474 _gnutls_proc_cert_cert_req (gnutls_session_t session
, uint8_t * data
,
1479 gnutls_certificate_credentials_t cred
;
1482 gnutls_pk_algorithm_t pk_algos
[MAX_CLIENT_SIGN_ALGOS
];
1483 int pk_algos_length
;
1484 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1486 cred
= (gnutls_certificate_credentials_t
)
1487 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1491 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1495 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1496 sizeof (cert_auth_info_st
), 0)) < 0)
1505 DECR_LEN (dsize
, 1);
1508 /* check if the sign algorithm is supported.
1510 pk_algos_length
= 0;
1511 for (i
= 0; i
< size
; i
++, p
++)
1513 DECR_LEN (dsize
, 1);
1514 if ((ret
= _gnutls_check_supported_sign_algo (*p
)) > 0)
1516 if (pk_algos_length
< MAX_CLIENT_SIGN_ALGOS
)
1518 pk_algos
[pk_algos_length
++] = ret
;
1523 if (pk_algos_length
== 0)
1526 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1529 if (_gnutls_version_has_selectable_sighash (ver
))
1531 /* read supported hashes */
1533 DECR_LEN (dsize
, 2);
1534 hash_num
= _gnutls_read_uint16 (p
);
1536 DECR_LEN (dsize
, hash_num
);
1538 ret
= _gnutls_sign_algorithm_parse_data (session
, p
, hash_num
);
1548 /* read the certificate authorities */
1549 DECR_LEN (dsize
, 2);
1550 size
= _gnutls_read_uint16 (p
);
1553 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
1557 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1560 DECR_LEN (dsize
, size
);
1562 /* now we ask the user to tell which one
1566 _select_client_cert (session
, p
, size
, pk_algos
, pk_algos_length
)) < 0)
1572 /* We should reply with a certificate message,
1573 * even if we have no certificate to send.
1575 session
->key
->crt_requested
= 1;
1581 _gnutls_gen_cert_client_crt_vrfy (gnutls_session_t session
,
1582 gnutls_buffer_st
* data
)
1585 gnutls_pcert_st
*apr_cert_list
;
1586 gnutls_privkey_t apr_pkey
;
1587 int apr_cert_list_length
;
1588 gnutls_datum_t signature
= { NULL
, 0 };
1590 gnutls_sign_algorithm_t sign_algo
;
1591 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1593 /* find the appropriate certificate */
1595 _gnutls_get_selected_cert (session
, &apr_cert_list
,
1596 &apr_cert_list_length
, &apr_pkey
)) < 0)
1602 if (apr_cert_list_length
> 0)
1605 _gnutls_handshake_sign_crt_vrfy (session
,
1607 apr_pkey
, &signature
)) < 0)
1619 total_data
= signature
.size
+ 2;
1621 /* add hash and signature algorithms */
1622 if (_gnutls_version_has_selectable_sighash (ver
))
1627 if (_gnutls_version_has_selectable_sighash (ver
))
1629 const sign_algorithm_st
*aid
;
1631 /* error checking is not needed here since we have used those algorithms */
1632 aid
= _gnutls_sign_to_tls_aid (sign_algo
);
1634 return gnutls_assert_val (GNUTLS_E_UNKNOWN_ALGORITHM
);
1636 p
[0] = aid
->hash_algorithm
;
1637 p
[1] = aid
->sign_algorithm
;
1638 ret
= _gnutls_buffer_append_data (data
, p
, 2);
1647 _gnutls_buffer_append_data_prefix (data
, 16, signature
.data
,
1658 _gnutls_free_datum (&signature
);
1663 _gnutls_proc_cert_client_crt_vrfy (gnutls_session_t session
,
1664 uint8_t * data
, size_t data_size
)
1667 ssize_t dsize
= data_size
;
1668 uint8_t *pdata
= data
;
1670 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
1671 gnutls_pcert_st peer_cert
;
1672 gnutls_sign_algorithm_t sign_algo
= GNUTLS_SIGN_UNKNOWN
;
1673 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1675 if (info
== NULL
|| info
->ncerts
== 0)
1678 /* we need this in order to get peer's certificate */
1679 return GNUTLS_E_INTERNAL_ERROR
;
1682 if (_gnutls_version_has_selectable_sighash (ver
))
1684 sign_algorithm_st aid
;
1686 DECR_LEN (dsize
, 2);
1687 aid
.hash_algorithm
= pdata
[0];
1688 aid
.sign_algorithm
= pdata
[1];
1690 sign_algo
= _gnutls_tls_aid_to_sign (&aid
);
1691 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
1694 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1699 ret
= _gnutls_session_sign_algo_enabled (session
, sign_algo
);
1703 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
1706 DECR_LEN (dsize
, 2);
1707 size
= _gnutls_read_uint16 (pdata
);
1710 DECR_LEN (dsize
, size
);
1715 ret
= _gnutls_get_auth_info_pcert (&peer_cert
,
1716 session
->security_parameters
.cert_type
,
1726 _gnutls_handshake_verify_crt_vrfy (session
, &peer_cert
, &sig
,
1730 gnutls_pcert_deinit (&peer_cert
);
1733 gnutls_pcert_deinit (&peer_cert
);
1739 _gnutls_gen_cert_server_cert_req (gnutls_session_t session
,
1740 gnutls_buffer_st
* data
)
1742 gnutls_certificate_credentials_t cred
;
1744 uint8_t tmp_data
[CERTTYPE_SIZE
];
1745 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1747 /* Now we need to generate the RDN sequence. This is
1748 * already in the CERTIFICATE_CRED structure, to improve
1752 cred
= (gnutls_certificate_credentials_t
)
1753 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1757 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1760 size
= CERTTYPE_SIZE
+ 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1763 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1764 session
->internals
.ignore_rdn_sequence
== 0)
1765 size
+= cred
->x509_rdn_sequence
.size
;
1767 if (_gnutls_version_has_selectable_sighash (ver
))
1768 /* Need two bytes to announce the number of supported hash
1769 functions (see below). */
1770 size
+= MAX_SIGN_ALGO_SIZE
;
1772 tmp_data
[0] = CERTTYPE_SIZE
- 1;
1773 tmp_data
[1] = RSA_SIGN
;
1774 tmp_data
[2] = DSA_SIGN
;
1775 tmp_data
[3] = ECDSA_SIGN
; /* only these for now */
1777 ret
= _gnutls_buffer_append_data (data
, tmp_data
, CERTTYPE_SIZE
);
1779 return gnutls_assert_val (ret
);
1781 if (_gnutls_version_has_selectable_sighash (ver
))
1783 uint8_t p
[MAX_SIGN_ALGO_SIZE
];
1786 _gnutls_sign_algorithm_write_params (session
, p
, MAX_SIGN_ALGO_SIZE
);
1793 /* recalculate size */
1794 size
-= MAX_SIGN_ALGO_SIZE
+ ret
;
1796 ret
= _gnutls_buffer_append_data (data
, p
, ret
);
1798 return gnutls_assert_val (ret
);
1801 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1802 session
->internals
.ignore_rdn_sequence
== 0)
1805 _gnutls_buffer_append_data_prefix (data
, 16,
1806 cred
->x509_rdn_sequence
.data
,
1807 cred
->x509_rdn_sequence
.size
);
1809 return gnutls_assert_val (ret
);
1813 ret
= _gnutls_buffer_append_prefix (data
, 16, 0);
1815 return gnutls_assert_val (ret
);
1818 return data
->length
;
1822 /* This function will return the appropriate certificate to use.
1823 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1824 * The return value is a negative error code on error.
1826 * It is normal to return 0 with no certificates in client side.
1830 _gnutls_get_selected_cert (gnutls_session_t session
,
1831 gnutls_pcert_st
** apr_cert_list
,
1832 int *apr_cert_list_length
,
1833 gnutls_privkey_t
* apr_pkey
)
1835 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
1838 /* select_client_cert() has been called before.
1841 *apr_cert_list
= session
->internals
.selected_cert_list
;
1842 *apr_pkey
= session
->internals
.selected_key
;
1843 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1845 if (*apr_cert_list_length
== 0 || *apr_cert_list
== NULL
)
1848 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1856 /* we have already decided which certificate
1859 *apr_cert_list
= session
->internals
.selected_cert_list
;
1860 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1861 *apr_pkey
= session
->internals
.selected_key
;
1868 /* converts the given x509 certificate list to gnutls_pcert_st* and allocates
1871 static gnutls_pcert_st
*
1872 alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
, unsigned ncerts
)
1874 gnutls_pcert_st
*local_certs
;
1881 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
) * ncerts
);
1882 if (local_certs
== NULL
)
1888 for (i
= 0; i
< ncerts
; i
++)
1890 ret
= gnutls_pcert_import_x509 (&local_certs
[i
], certs
[i
], 0);
1898 for (j
= 0; j
< i
; j
++)
1900 gnutls_pcert_deinit (&local_certs
[j
]);
1902 gnutls_free (local_certs
);
1909 /* converts the given x509 key to gnutls_privkey* and allocates
1912 static gnutls_privkey_t
1913 alloc_and_load_x509_key (gnutls_x509_privkey_t key
, int deinit
)
1915 gnutls_privkey_t local_key
;
1921 ret
= gnutls_privkey_init (&local_key
);
1929 gnutls_privkey_import_x509 (local_key
, key
,
1930 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
:
1935 gnutls_privkey_deinit (local_key
);
1942 /* converts the given pgp certificate to gnutls_cert* and allocates
1945 #ifdef ENABLE_OPENPGP
1946 static gnutls_pcert_st
*
1947 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
)
1949 gnutls_pcert_st
*local_certs
;
1955 local_certs
= gnutls_malloc (sizeof (gnutls_pcert_st
));
1956 if (local_certs
== NULL
)
1962 ret
= gnutls_pcert_import_openpgp (local_certs
, cert
, 0);
1972 gnutls_pcert_deinit (local_certs
);
1973 gnutls_free (local_certs
);
1980 /* converts the given raw key to gnutls_privkey* and allocates
1983 static gnutls_privkey_t
1984 alloc_and_load_pgp_key (gnutls_openpgp_privkey_t key
, int deinit
)
1986 gnutls_privkey_t local_key
;
1992 ret
= gnutls_privkey_init (&local_key
);
2000 gnutls_privkey_import_openpgp (local_key
, key
,
2001 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2006 gnutls_privkey_deinit (local_key
);
2014 #ifdef ENABLE_PKCS11
2016 /* converts the given raw key to gnutls_privkey* and allocates
2019 static gnutls_privkey_t
2020 alloc_and_load_pkcs11_key (gnutls_pkcs11_privkey_t key
, int deinit
)
2022 gnutls_privkey_t local_key
;
2028 ret
= gnutls_privkey_init (&local_key
);
2036 gnutls_privkey_import_pkcs11 (local_key
, key
,
2037 deinit
? GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
2042 gnutls_privkey_deinit (local_key
);
2052 _gnutls_selected_certs_deinit (gnutls_session_t session
)
2054 if (session
->internals
.selected_need_free
!= 0)
2058 for (i
= 0; i
< session
->internals
.selected_cert_list_length
; i
++)
2060 gnutls_pcert_deinit (&session
->internals
.selected_cert_list
[i
]);
2062 gnutls_free (session
->internals
.selected_cert_list
);
2063 session
->internals
.selected_cert_list
= NULL
;
2064 session
->internals
.selected_cert_list_length
= 0;
2066 gnutls_privkey_deinit(session
->internals
.selected_key
);
2067 session
->internals
.selected_key
= NULL
;
2074 _gnutls_selected_certs_set (gnutls_session_t session
,
2075 gnutls_pcert_st
* certs
, int ncerts
,
2076 gnutls_privkey_t key
, int need_free
)
2078 _gnutls_selected_certs_deinit (session
);
2080 session
->internals
.selected_cert_list
= certs
;
2081 session
->internals
.selected_cert_list_length
= ncerts
;
2082 session
->internals
.selected_key
= key
;
2083 session
->internals
.selected_need_free
= need_free
;
2087 static void get_server_name(gnutls_session_t session
, uint8_t* name
, size_t max_name_size
)
2094 for (i
=0; !(ret
<0);i
++)
2096 max_name
= max_name_size
;
2097 ret
= gnutls_server_name_get (session
, name
, &max_name
, &type
, i
);
2098 if (ret
>= 0 && type
== GNUTLS_NAME_DNS
)
2107 /* finds the most appropriate certificate in the cert list.
2108 * The 'appropriate' is defined by the user.
2110 * requested_algo holds the parameters required by the peer (RSA, DSA
2113 * Returns 0 on success and a negative error code on error. The
2114 * selected certificate will be in session->internals.selected_*.
2118 _gnutls_server_select_cert (gnutls_session_t session
,
2119 gnutls_pk_algorithm_t
* pk_algos
,
2120 size_t pk_algos_size
)
2124 gnutls_certificate_credentials_t cred
;
2125 char server_name
[MAX_CN
];
2127 cred
= (gnutls_certificate_credentials_t
)
2128 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
2132 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2135 /* If the callback which retrieves certificate has been set,
2138 if (cred
->server_get_cert_callback
|| cred
->get_cert_callback
2139 || cred
->get_cert_callback2
)
2141 ret
= call_get_cert_callback (session
, NULL
, 0, NULL
, 0);
2143 return gnutls_assert_val (ret
);
2149 get_server_name(session
, (unsigned char*)server_name
, sizeof(server_name
));
2151 idx
= -1; /* default is use no certificate */
2153 /* find certificates that match the requested server_name
2156 if (server_name
[0] != 0)
2158 for (i
= 0; i
< cred
->ncerts
; i
++)
2160 if (cred
->certs
[i
].names
!= NULL
&& _gnutls_str_array_match(cred
->certs
[i
].names
, server_name
) != 0)
2162 /* if requested algorithms are also compatible select it */
2163 gnutls_pk_algorithm pk
=
2164 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2167 _gnutls_handshake_log("HSK[%p]: Requested server name: '%s', ctype: %s (%d)", session
, server_name
,
2168 gnutls_certificate_type_get_name (session
->security_parameters
.cert_type
),
2169 session
->security_parameters
.cert_type
);
2171 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2173 for (j
= 0; j
< pk_algos_size
; j
++)
2174 if (pk_algos
[j
] == pk
)
2184 for (j
= 0; j
< pk_algos_size
; j
++)
2186 _gnutls_handshake_log
2187 ("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n",
2188 session
, gnutls_pk_get_name (pk_algos
[j
]), pk_algos
[j
],
2189 gnutls_certificate_type_get_name (session
->security_parameters
.
2191 session
->security_parameters
.cert_type
);
2193 for (i
= 0; i
< cred
->ncerts
; i
++)
2195 gnutls_pk_algorithm pk
=
2196 gnutls_pubkey_get_pk_algorithm (cred
->certs
[i
].cert_list
[0].pubkey
,
2198 /* find one compatible certificate
2200 _gnutls_handshake_log
2201 ("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d)\n",
2202 session
, i
, gnutls_pk_get_name (pk
), pk
,
2203 gnutls_certificate_type_get_name (cred
->certs
[i
].cert_list
[0].type
),
2204 cred
->certs
[i
].cert_list
[0].type
);
2206 if (pk_algos
[j
] == pk
)
2208 /* if cert type matches
2211 if (session
->security_parameters
.cert_type
== cred
->certs
[i
].cert_list
[0].type
)
2221 /* store the certificate pointer for future use, in the handshake.
2222 * (This will allow not calling this callback again.)
2227 _gnutls_selected_certs_set (session
,
2228 &cred
->certs
[idx
].cert_list
[0],
2229 cred
->certs
[idx
].cert_list_length
,
2230 cred
->pkey
[idx
], 0);
2235 /* Certificate does not support REQUESTED_ALGO. */
2236 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
2242 /* Frees the rsa_info_st structure.
2245 _gnutls_free_rsa_info (rsa_info_st
* rsa
)
2247 _gnutls_free_datum (&rsa
->modulus
);
2248 _gnutls_free_datum (&rsa
->exponent
);