2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 /* The certificate authentication functions which are needed in the handshake,
26 * and are common to RSA and DHE key exchange, are in this file.
29 #include <gnutls_int.h>
30 #include "gnutls_auth_int.h"
31 #include "gnutls_errors.h"
32 #include <gnutls_cert.h>
33 #include <auth_cert.h>
34 #include "gnutls_dh.h"
35 #include "gnutls_num.h"
37 #include "gnutls_datum.h"
38 #include <gnutls_pk.h>
39 #include <gnutls_algorithms.h>
40 #include <gnutls_global.h>
41 #include <gnutls_record.h>
42 #include <gnutls_sig.h>
43 #include <gnutls_state.h>
44 #include <gnutls_pk.h>
45 #include <gnutls_x509.h>
46 #include <gnutls_extra_hooks.h>
49 static gnutls_cert
*alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
,
51 static gnutls_privkey
*alloc_and_load_x509_key (gnutls_x509_privkey_t key
);
52 static gnutls_cert
*alloc_and_load_pgp_certs (gnutls_openpgp_key_t cert
);
53 static gnutls_privkey
*alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
57 /* Copies data from a internal certificate struct (gnutls_cert) to
58 * exported certificate struct (cert_auth_info_t)
61 _gnutls_copy_certificate_auth_info (cert_auth_info_t info
,
62 gnutls_cert
* cert
, int ncerts
)
64 /* Copy peer's information to auth_info_t
70 info
->raw_certificate_list
= NULL
;
75 info
->raw_certificate_list
=
76 gnutls_calloc (1, sizeof (gnutls_datum_t
) * ncerts
);
77 if (info
->raw_certificate_list
== NULL
)
80 return GNUTLS_E_MEMORY_ERROR
;
83 for (i
= 0; i
< ncerts
; i
++)
85 if (cert
->raw
.size
> 0)
88 _gnutls_set_datum (&info
->
89 raw_certificate_list
[i
],
90 cert
[i
].raw
.data
, cert
[i
].raw
.size
);
98 info
->ncerts
= ncerts
;
104 for (j
= 0; j
< i
; j
++)
105 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
107 gnutls_free (info
->raw_certificate_list
);
108 info
->raw_certificate_list
= NULL
;
116 /* returns 0 if the algo_to-check exists in the pk_algos list,
120 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t
*
121 pk_algos
, int pk_algos_length
,
122 gnutls_pk_algorithm_t algo_to_check
)
125 for (i
= 0; i
< pk_algos_length
; i
++)
127 if (algo_to_check
== pk_algos
[i
])
136 /* Returns the issuer's Distinguished name in odn, of the certificate
140 _gnutls_cert_get_issuer_dn (gnutls_cert
* cert
, gnutls_datum_t
* odn
)
146 if ((result
= asn1_create_element
147 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn
)) != ASN1_SUCCESS
)
150 return _gnutls_asn2err (result
);
153 result
= asn1_der_decoding (&dn
, cert
->raw
.data
, cert
->raw
.size
, NULL
);
154 if (result
!= ASN1_SUCCESS
)
156 /* couldn't decode DER */
158 asn1_delete_structure (&dn
);
159 return _gnutls_asn2err (result
);
162 result
= asn1_der_decoding_startEnd (dn
, cert
->raw
.data
, cert
->raw
.size
,
163 "tbsCertificate.issuer", &start
, &end
);
165 if (result
!= ASN1_SUCCESS
)
167 /* couldn't decode DER */
169 asn1_delete_structure (&dn
);
170 return _gnutls_asn2err (result
);
172 asn1_delete_structure (&dn
);
174 len
= end
- start
+ 1;
177 odn
->data
= &cert
->raw
.data
[start
];
183 /* Locates the most appropriate x509 certificate using the
184 * given DN. If indx == -1 then no certificate was found.
186 * That is to guess which certificate to use, based on the
187 * CAs and sign algorithms supported by the peer server.
190 _find_x509_cert (const gnutls_certificate_credentials_t cred
,
191 opaque
* _data
, size_t _data_size
,
192 const gnutls_pk_algorithm_t
* pk_algos
,
193 int pk_algos_length
, int *indx
)
197 opaque
*data
= _data
;
198 ssize_t data_size
= _data_size
;
207 DECR_LENGTH_RET (data_size
, 2, 0);
208 size
= _gnutls_read_uint16 (data
);
209 DECR_LENGTH_RET (data_size
, size
, 0);
212 for (i
= 0; i
< cred
->ncerts
; i
++)
214 for (j
= 0; j
< cred
->cert_list_length
[i
]; j
++)
217 _gnutls_cert_get_issuer_dn (&cred
->
218 cert_list
[i
][j
], &odn
)) < 0)
224 if (odn
.size
!= size
)
227 /* If the DN matches and
228 * the *_SIGN algorithm matches
229 * the cert is our cert!
231 cert_pk
= cred
->cert_list
[i
][0].subject_pk_algorithm
;
233 if ((memcmp (odn
.data
, data
, size
) == 0) &&
234 (_gnutls_check_pk_algo_in_list
235 (pk_algos
, pk_algos_length
, cert_pk
) == 0))
248 /* move to next record */
258 /* Locates the most appropriate openpgp cert
261 _find_openpgp_cert (const gnutls_certificate_credentials_t cred
,
262 gnutls_pk_algorithm_t
* pk_algos
,
263 int pk_algos_length
, int *indx
)
269 for (i
= 0; i
< cred
->ncerts
; i
++)
271 for (j
= 0; j
< cred
->cert_list_length
[i
]; j
++)
274 /* If the *_SIGN algorithm matches
275 * the cert is our cert!
277 if ((_gnutls_check_pk_algo_in_list
278 (pk_algos
, pk_algos_length
,
279 cred
->cert_list
[i
][0].subject_pk_algorithm
) == 0)
280 && (cred
->cert_list
[i
][0].cert_type
== GNUTLS_CRT_OPENPGP
))
293 /* Returns the number of issuers in the server's
294 * certificate request packet.
297 get_issuers_num (gnutls_session_t session
, opaque
* data
, ssize_t data_size
)
299 int issuers_dn_len
= 0, result
;
302 /* Count the number of the given issuers;
303 * This is used to allocate the issuers_dn without
307 if (data_size
== 0 || data
== NULL
)
313 /* This works like DECR_LEN()
315 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
316 DECR_LENGTH_COM (data_size
, 2, goto error
);
317 size
= _gnutls_read_uint16 (data
);
319 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
320 DECR_LENGTH_COM (data_size
, size
, goto error
);
336 return issuers_dn_len
;
342 /* Returns the issuers in the server's certificate request
346 get_issuers (gnutls_session_t session
,
347 gnutls_datum_t
* issuers_dn
, int issuers_len
,
348 opaque
* data
, size_t data_size
)
353 if (gnutls_certificate_type_get (session
) != GNUTLS_CRT_X509
)
356 /* put the requested DNs to req_dn, only in case
357 * of X509 certificates.
362 for (i
= 0; i
< issuers_len
; i
++)
364 /* The checks here for the buffer boundaries
365 * are not needed since the buffer has been
370 size
= _gnutls_read_uint16 (data
);
374 issuers_dn
[i
].data
= data
;
375 issuers_dn
[i
].size
= size
;
384 /* Calls the client get callback.
387 call_get_cert_callback (gnutls_session_t session
,
388 gnutls_datum_t
* issuers_dn
,
389 int issuers_dn_length
,
390 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
393 gnutls_cert
*local_certs
= NULL
;
394 gnutls_privkey
*local_key
= NULL
;
397 gnutls_certificate_type_t type
= gnutls_certificate_type_get (session
);
398 gnutls_certificate_credentials_t cred
;
400 cred
= (gnutls_certificate_credentials_t
)
401 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
405 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
408 memset (&st
, 0, sizeof (st
));
410 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
412 ret
= cred
->server_get_cert_callback (session
, &st
);
417 cred
->client_get_cert_callback (session
,
418 issuers_dn
, issuers_dn_length
,
419 pk_algos
, pk_algos_length
, &st
);
425 return GNUTLS_E_INTERNAL_ERROR
;
429 return 0; /* no certificate was selected */
434 ret
= GNUTLS_E_INVALID_REQUEST
;
438 if (type
== GNUTLS_CRT_X509
)
440 local_certs
= alloc_and_load_x509_certs (st
.cert
.x509
, st
.ncerts
);
441 if (local_certs
!= NULL
)
442 local_key
= alloc_and_load_x509_key (st
.key
.x509
);
450 ret
= GNUTLS_E_INVALID_REQUEST
;
454 local_certs
= alloc_and_load_pgp_certs (st
.cert
.pgp
);
455 if (local_certs
!= NULL
)
456 local_key
= alloc_and_load_pgp_key (st
.key
.pgp
);
460 _gnutls_selected_certs_set (session
, local_certs
,
461 (local_certs
!= NULL
) ? st
.ncerts
: 0,
468 if (st
.type
== GNUTLS_CRT_X509
)
472 for (i
= 0; i
< st
.ncerts
; i
++)
474 gnutls_x509_crt_deinit (st
.cert
.x509
[i
]);
476 gnutls_free (st
.cert
.x509
);
477 gnutls_x509_privkey_deinit (st
.key
.x509
);
484 if (_E_gnutls_openpgp_key_deinit
== NULL
||
485 _E_gnutls_openpgp_privkey_deinit
== NULL
)
488 return GNUTLS_E_INIT_LIBEXTRA
;
491 _E_gnutls_openpgp_key_deinit (st
.cert
.pgp
);
492 _E_gnutls_openpgp_privkey_deinit (st
.key
.pgp
);
499 /* Finds the appropriate certificate depending on the cA Distinguished name
500 * advertized by the server. If none matches then returns 0 and -1 as index.
501 * In case of an error a negative value, is returned.
503 * 20020128: added ability to select a certificate depending on the SIGN
504 * algorithm (only in automatic mode).
507 _select_client_cert (gnutls_session_t session
,
508 opaque
* _data
, size_t _data_size
,
509 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
513 gnutls_certificate_credentials_t cred
;
514 opaque
*data
= _data
;
515 ssize_t data_size
= _data_size
;
516 int issuers_dn_length
;
517 gnutls_datum_t
*issuers_dn
= NULL
;
519 cred
= (gnutls_certificate_credentials_t
)
520 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
524 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
527 if (cred
->client_get_cert_callback
!= NULL
)
530 /* use a callback to get certificate
532 if (session
->security_parameters
.cert_type
!= GNUTLS_CRT_X509
)
533 issuers_dn_length
= 0;
536 issuers_dn_length
= get_issuers_num (session
, data
, data_size
);
537 if (issuers_dn_length
< 0)
540 return issuers_dn_length
;
543 if (issuers_dn_length
> 0)
546 gnutls_malloc (sizeof (gnutls_datum_t
) * issuers_dn_length
);
547 if (issuers_dn
== NULL
)
550 return GNUTLS_E_MEMORY_ERROR
;
554 get_issuers (session
, issuers_dn
, issuers_dn_length
,
565 call_get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
566 pk_algos
, pk_algos_length
);
572 /* If we have no callbacks, try to guess.
576 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
)
578 _find_x509_cert (cred
, _data
, _data_size
,
579 pk_algos
, pk_algos_length
, &indx
);
581 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
)
582 result
= _find_openpgp_cert (cred
, pk_algos
, pk_algos_length
, &indx
);
593 _gnutls_selected_certs_set (session
,
594 &cred
->cert_list
[indx
][0],
595 cred
->cert_list_length
[indx
],
596 &cred
->pkey
[indx
], 0);
600 _gnutls_selected_certs_set (session
, NULL
, 0, NULL
, 0);
607 gnutls_free (issuers_dn
);
612 /* Generate client certificate
616 _gnutls_gen_x509_crt (gnutls_session_t session
, opaque
** data
)
620 gnutls_cert
*apr_cert_list
;
621 gnutls_privkey
*apr_pkey
;
622 int apr_cert_list_length
;
624 /* find the appropriate certificate
627 _gnutls_get_selected_cert (session
, &apr_cert_list
,
628 &apr_cert_list_length
, &apr_pkey
)) < 0)
635 for (i
= 0; i
< apr_cert_list_length
; i
++)
637 ret
+= apr_cert_list
[i
].raw
.size
+ 3;
642 /* if no certificates were found then send:
643 * 0B 00 00 03 00 00 00 // Certificate with no certs
645 * 0B 00 00 00 // empty certificate handshake
647 * ( the above is the whole handshake message, not
648 * the one produced here )
651 (*data
) = gnutls_malloc (ret
);
657 return GNUTLS_E_MEMORY_ERROR
;
659 _gnutls_write_uint24 (ret
- 3, pdata
);
661 for (i
= 0; i
< apr_cert_list_length
; i
++)
663 _gnutls_write_datum24 (pdata
, apr_cert_list
[i
].raw
);
664 pdata
+= (3 + apr_cert_list
[i
].raw
.size
);
670 enum PGPKeyDescriptorType
671 { PGP_KEY_FINGERPRINT
, PGP_KEY
};
674 _gnutls_gen_openpgp_certificate (gnutls_session_t session
, opaque
** data
)
678 gnutls_cert
*apr_cert_list
;
679 gnutls_privkey
*apr_pkey
;
680 int apr_cert_list_length
;
682 /* find the appropriate certificate */
684 _gnutls_get_selected_cert (session
, &apr_cert_list
,
685 &apr_cert_list_length
, &apr_pkey
)) < 0)
693 if (apr_cert_list_length
> 0)
694 ret
+= apr_cert_list
[0].raw
.size
;
696 (*data
) = gnutls_malloc (ret
);
702 return GNUTLS_E_MEMORY_ERROR
;
705 _gnutls_write_uint24 (ret
- 3, pdata
);
708 *pdata
= PGP_KEY
; /* whole key */
711 if (apr_cert_list_length
> 0)
713 _gnutls_write_datum24 (pdata
, apr_cert_list
[0].raw
);
714 pdata
+= (3 + apr_cert_list
[0].raw
.size
);
716 else /* empty - no certificate */
717 _gnutls_write_uint24 (0, pdata
);
723 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session
, opaque
** data
)
725 int ret
, packet_size
;
728 gnutls_cert
*apr_cert_list
;
729 gnutls_privkey
*apr_pkey
;
730 int apr_cert_list_length
;
732 /* find the appropriate certificate */
734 _gnutls_get_selected_cert (session
, &apr_cert_list
,
735 &apr_cert_list_length
, &apr_pkey
)) < 0)
743 /* Only v4 fingerprints are sent
745 if (apr_cert_list_length
> 0 && apr_cert_list
[0].version
== 4)
746 packet_size
+= 20 + 1;
747 else /* empty certificate case */
748 return _gnutls_gen_openpgp_certificate (session
, data
);
750 (*data
) = gnutls_malloc (packet_size
);
756 return GNUTLS_E_MEMORY_ERROR
;
759 _gnutls_write_uint24 (packet_size
- 3, pdata
);
762 *pdata
= PGP_KEY_FINGERPRINT
; /* key fingerprint */
770 if (_E_gnutls_openpgp_fingerprint
== NULL
)
773 return GNUTLS_E_INIT_LIBEXTRA
;
777 _E_gnutls_openpgp_fingerprint (&apr_cert_list
[0].raw
, pdata
,
790 _gnutls_gen_cert_client_certificate (gnutls_session_t session
, opaque
** data
)
792 switch (session
->security_parameters
.cert_type
)
794 case GNUTLS_CRT_OPENPGP
:
795 if (_gnutls_openpgp_send_fingerprint (session
) == 0)
796 return _gnutls_gen_openpgp_certificate (session
, data
);
798 return _gnutls_gen_openpgp_certificate_fpr (session
, data
);
800 case GNUTLS_CRT_X509
:
801 return _gnutls_gen_x509_crt (session
, data
);
805 return GNUTLS_E_INTERNAL_ERROR
;
810 _gnutls_gen_cert_server_certificate (gnutls_session_t session
, opaque
** data
)
812 switch (session
->security_parameters
.cert_type
)
814 case GNUTLS_CRT_OPENPGP
:
815 return _gnutls_gen_openpgp_certificate (session
, data
);
816 case GNUTLS_CRT_X509
:
817 return _gnutls_gen_x509_crt (session
, data
);
820 return GNUTLS_E_INTERNAL_ERROR
;
824 /* Process server certificate
827 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
829 _gnutls_proc_x509_server_certificate (gnutls_session_t session
,
830 opaque
* data
, size_t data_size
)
834 cert_auth_info_t info
;
835 gnutls_certificate_credentials_t cred
;
836 ssize_t dsize
= data_size
;
838 gnutls_cert
*peer_certificate_list
;
839 int peer_certificate_list_size
= 0;
842 cred
= (gnutls_certificate_credentials_t
)
843 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
847 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
852 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
853 sizeof (cert_auth_info_st
), 1)) < 0)
859 info
= _gnutls_get_auth_info (session
);
861 if (data
== NULL
|| data_size
== 0)
864 /* no certificate was sent */
865 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
869 size
= _gnutls_read_uint24 (p
);
875 /* no certificate was sent */
876 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
883 len
= _gnutls_read_uint24 (p
);
885 DECR_LEN (dsize
, len
);
886 peer_certificate_list_size
++;
891 if (peer_certificate_list_size
== 0)
894 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
897 /* Ok we now allocate the memory to hold the
901 peer_certificate_list
=
902 gnutls_malloc (sizeof (gnutls_cert
) * (peer_certificate_list_size
));
904 if (peer_certificate_list
== NULL
)
907 return GNUTLS_E_MEMORY_ERROR
;
909 memset (peer_certificate_list
, 0, sizeof (gnutls_cert
) *
910 peer_certificate_list_size
);
914 /* Now we start parsing the list (again).
915 * We don't use DECR_LEN since the list has
916 * been parsed before.
919 for (j
= 0; j
< peer_certificate_list_size
; j
++)
921 len
= _gnutls_read_uint24 (p
);
928 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
930 CERT_ONLY_EXTENSIONS
)) < 0)
941 _gnutls_copy_certificate_auth_info (info
,
942 peer_certificate_list
,
943 peer_certificate_list_size
)) < 0)
950 _gnutls_check_key_usage (&peer_certificate_list
[0],
951 gnutls_kx_get (session
))) < 0)
961 gnutls_free (peer_certificate_list
);
966 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
968 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session
,
969 opaque
* data
, size_t data_size
)
973 cert_auth_info_t info
;
974 gnutls_certificate_credentials_t cred
;
975 ssize_t dsize
= data_size
;
977 gnutls_cert
*peer_certificate_list
= NULL
;
978 int peer_certificate_list_size
= 0;
979 gnutls_datum_t tmp
, akey
= { NULL
, 0 };
981 cred
= (gnutls_certificate_credentials_t
)
982 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
986 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
990 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
991 sizeof (cert_auth_info_st
), 1)) < 0)
997 info
= _gnutls_get_auth_info (session
);
999 if (data
== NULL
|| data_size
== 0)
1002 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1005 DECR_LEN (dsize
, 3);
1006 size
= _gnutls_read_uint24 (p
);
1012 /* no certificate was sent */
1013 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1017 /* Read PGPKeyDescriptor */
1018 DECR_LEN (dsize
, 1);
1019 if (*p
== PGP_KEY_FINGERPRINT
)
1020 { /* the fingerprint */
1023 DECR_LEN (dsize
, 1);
1024 len
= (uint8_t) * p
;
1030 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED
;
1033 DECR_LEN (dsize
, 20);
1035 /* request the actual key from our database, or
1036 * a key server or anything.
1038 if (_E_gnutls_openpgp_request_key
== NULL
)
1041 return GNUTLS_E_INIT_LIBEXTRA
;
1044 _E_gnutls_openpgp_request_key (session
, &akey
, cred
, p
, 20)) < 0)
1050 peer_certificate_list_size
++;
1053 else if (*p
== PGP_KEY
)
1054 { /* the whole key */
1058 /* Read the actual certificate */
1059 DECR_LEN (dsize
, 3);
1060 len
= _gnutls_read_uint24 (p
);
1066 /* no certificate was sent */
1067 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1070 DECR_LEN (dsize
, len
);
1071 peer_certificate_list_size
++;
1080 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1083 /* ok we now have the peer's key in tmp datum
1086 if (peer_certificate_list_size
== 0)
1089 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1092 peer_certificate_list
=
1093 gnutls_alloca (sizeof (gnutls_cert
) * (peer_certificate_list_size
));
1094 if (peer_certificate_list
== NULL
)
1097 ret
= GNUTLS_E_MEMORY_ERROR
;
1100 memset (peer_certificate_list
, 0, sizeof (gnutls_cert
) *
1101 peer_certificate_list_size
);
1103 if (_E_gnutls_openpgp_raw_key_to_gcert
== NULL
)
1106 ret
= GNUTLS_E_INIT_LIBEXTRA
;
1111 _E_gnutls_openpgp_raw_key_to_gcert (&peer_certificate_list
[0],
1119 _gnutls_copy_certificate_auth_info (info
,
1120 peer_certificate_list
,
1121 peer_certificate_list_size
)) < 0)
1128 _gnutls_check_key_usage (&peer_certificate_list
[0],
1129 gnutls_kx_get (session
))) < 0)
1139 _gnutls_free_datum (&akey
);
1141 gnutls_afree (peer_certificate_list
);
1147 _gnutls_proc_cert_server_certificate (gnutls_session_t session
,
1148 opaque
* data
, size_t data_size
)
1150 switch (session
->security_parameters
.cert_type
)
1152 case GNUTLS_CRT_OPENPGP
:
1153 return _gnutls_proc_openpgp_server_certificate (session
,
1155 case GNUTLS_CRT_X509
:
1156 return _gnutls_proc_x509_server_certificate (session
, data
, data_size
);
1159 return GNUTLS_E_INTERNAL_ERROR
;
1163 #define MAX_SIGN_ALGOS 2
1164 typedef enum CertificateSigType
1165 { RSA_SIGN
= 1, DSA_SIGN
1166 } CertificateSigType
;
1168 /* Checks if we support the given signature algorithm
1169 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1173 _gnutls_check_supported_sign_algo (CertificateSigType algo
)
1178 return GNUTLS_PK_RSA
;
1180 return GNUTLS_PK_DSA
;
1187 _gnutls_proc_cert_cert_req (gnutls_session_t session
, opaque
* data
,
1192 gnutls_certificate_credentials_t cred
;
1193 cert_auth_info_t info
;
1196 gnutls_pk_algorithm_t pk_algos
[MAX_SIGN_ALGOS
];
1197 int pk_algos_length
;
1198 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1200 cred
= (gnutls_certificate_credentials_t
)
1201 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1205 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1209 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1210 sizeof (cert_auth_info_st
), 0)) < 0)
1216 info
= _gnutls_get_auth_info (session
);
1221 DECR_LEN (dsize
, 1);
1224 /* check if the sign algorithm is supported.
1226 pk_algos_length
= j
= 0;
1227 for (i
= 0; i
< size
; i
++, p
++)
1229 DECR_LEN (dsize
, 1);
1230 if ((ret
= _gnutls_check_supported_sign_algo (*p
)) > 0)
1232 if (j
< MAX_SIGN_ALGOS
)
1234 pk_algos
[j
++] = ret
;
1240 if (pk_algos_length
== 0)
1243 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1246 if (ver
== GNUTLS_TLS1_2
)
1248 /* read supported hashes */
1250 DECR_LEN (dsize
, 1);
1252 hash_num
= p
[0] & 0xFF;
1255 DECR_LEN (dsize
, hash_num
);
1259 /* read the certificate authorities */
1260 DECR_LEN (dsize
, 2);
1261 size
= _gnutls_read_uint16 (p
);
1264 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
&& size
!= 0)
1266 gnutls_assert(); // size should be zero
1267 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1270 DECR_LEN (dsize
, size
);
1272 /* now we ask the user to tell which one
1276 _select_client_cert (session
, p
, size
, pk_algos
, pk_algos_length
)) < 0)
1282 /* We should reply with a certificate message,
1283 * even if we have no certificate to send.
1285 session
->key
->certificate_requested
= 1;
1291 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session
, opaque
** data
)
1294 gnutls_cert
*apr_cert_list
;
1295 gnutls_privkey
*apr_pkey
;
1296 int apr_cert_list_length
, size
;
1297 gnutls_datum_t signature
;
1301 /* find the appropriate certificate */
1303 _gnutls_get_selected_cert (session
, &apr_cert_list
,
1304 &apr_cert_list_length
, &apr_pkey
)) < 0)
1310 if (apr_pkey
!= NULL
)
1313 _gnutls_tls_sign_hdata (session
,
1315 apr_pkey
, &signature
)) < 0)
1326 *data
= gnutls_malloc (signature
.size
+ 2);
1329 _gnutls_free_datum (&signature
);
1330 return GNUTLS_E_MEMORY_ERROR
;
1332 size
= signature
.size
;
1333 _gnutls_write_uint16 (size
, *data
);
1335 memcpy (&(*data
)[2], signature
.data
, size
);
1337 _gnutls_free_datum (&signature
);
1343 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session
,
1344 opaque
* data
, size_t data_size
)
1347 ssize_t dsize
= data_size
;
1348 opaque
*pdata
= data
;
1350 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
1351 gnutls_cert peer_cert
;
1353 if (info
== NULL
|| info
->ncerts
== 0)
1356 /* we need this in order to get peer's certificate */
1357 return GNUTLS_E_INTERNAL_ERROR
;
1360 DECR_LEN (dsize
, 2);
1361 size
= _gnutls_read_uint16 (pdata
);
1364 DECR_LEN (dsize
, size
);
1369 ret
= _gnutls_raw_cert_to_gcert (&peer_cert
,
1370 session
->security_parameters
.cert_type
,
1371 &info
->raw_certificate_list
[0],
1380 if ((ret
= _gnutls_verify_sig_hdata (session
, &peer_cert
, &sig
)) < 0)
1383 _gnutls_gcert_deinit (&peer_cert
);
1386 _gnutls_gcert_deinit (&peer_cert
);
1391 #define CERTTYPE_SIZE 3
1393 _gnutls_gen_cert_server_cert_req (gnutls_session_t session
, opaque
** data
)
1395 gnutls_certificate_credentials_t cred
;
1398 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1400 /* Now we need to generate the RDN sequence. This is
1401 * already in the CERTIFICATE_CRED structure, to improve
1405 cred
= (gnutls_certificate_credentials_t
)
1406 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1410 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1413 size
= CERTTYPE_SIZE
+ 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1416 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1417 session
->internals
.ignore_rdn_sequence
== 0)
1418 size
+= cred
->x509_rdn_sequence
.size
;
1420 if (ver
== GNUTLS_TLS1_2
)
1421 /* Need at least one byte to announce the number of supported hash
1422 functions (see below). */
1425 (*data
) = gnutls_malloc (size
);
1431 return GNUTLS_E_MEMORY_ERROR
;
1434 pdata
[0] = CERTTYPE_SIZE
- 1;
1436 pdata
[1] = RSA_SIGN
;
1437 pdata
[2] = DSA_SIGN
; /* only these for now */
1438 pdata
+= CERTTYPE_SIZE
;
1440 if (ver
== GNUTLS_TLS1_2
)
1442 /* Supported hashes (nothing for now -- FIXME). */
1447 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1448 session
->internals
.ignore_rdn_sequence
== 0)
1450 _gnutls_write_datum16 (pdata
, cred
->x509_rdn_sequence
);
1451 /* pdata += cred->x509_rdn_sequence.size + 2; */
1455 _gnutls_write_uint16( 0, pdata
);
1463 /* This function will return the appropriate certificate to use.
1464 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1465 * The return value is a negative value on error.
1467 * It is normal to return 0 with no certificates in client side.
1471 _gnutls_get_selected_cert (gnutls_session_t session
,
1472 gnutls_cert
** apr_cert_list
,
1473 int *apr_cert_list_length
,
1474 gnutls_privkey
** apr_pkey
)
1476 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
1479 /* select_client_cert() has been called before.
1482 *apr_cert_list
= session
->internals
.selected_cert_list
;
1483 *apr_pkey
= session
->internals
.selected_key
;
1484 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1486 if (*apr_cert_list_length
== 0 || *apr_pkey
== NULL
||
1487 *apr_cert_list
== NULL
)
1490 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1498 /* we have already decided which certificate
1501 *apr_cert_list
= session
->internals
.selected_cert_list
;
1502 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1503 *apr_pkey
= session
->internals
.selected_key
;
1510 /* converts the given x509 certificate to gnutls_cert* and allocates
1513 static gnutls_cert
*
1514 alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
, unsigned ncerts
)
1516 gnutls_cert
*local_certs
;
1523 local_certs
= gnutls_malloc (sizeof (gnutls_cert
) * ncerts
);
1524 if (local_certs
== NULL
)
1530 for (i
= 0; i
< ncerts
; i
++)
1532 ret
= _gnutls_x509_crt_to_gcert (&local_certs
[i
], certs
[i
], 0);
1540 for (j
= 0; j
< i
; j
++)
1542 _gnutls_gcert_deinit (&local_certs
[j
]);
1544 gnutls_free (local_certs
);
1551 /* converts the given x509 key to gnutls_privkey* and allocates
1554 static gnutls_privkey
*
1555 alloc_and_load_x509_key (gnutls_x509_privkey_t key
)
1557 gnutls_privkey
*local_key
;
1563 local_key
= gnutls_malloc (sizeof (gnutls_privkey
));
1564 if (local_key
== NULL
)
1570 ret
= _gnutls_x509_privkey_to_gkey (local_key
, key
);
1580 /* converts the given pgp certificate to gnutls_cert* and allocates
1583 static gnutls_cert
*
1584 alloc_and_load_pgp_certs (gnutls_openpgp_key_t cert
)
1586 gnutls_cert
*local_certs
;
1592 local_certs
= gnutls_malloc (sizeof (gnutls_cert
));
1593 if (local_certs
== NULL
)
1599 if (_E_gnutls_openpgp_key_to_gcert
== NULL
)
1605 ret
= _E_gnutls_openpgp_key_to_gcert (local_certs
, cert
);
1615 _gnutls_gcert_deinit (local_certs
);
1616 gnutls_free (local_certs
);
1623 /* converts the given raw key to gnutls_privkey* and allocates
1626 static gnutls_privkey
*
1627 alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key
)
1629 gnutls_privkey
*local_key
;
1635 local_key
= gnutls_malloc (sizeof (gnutls_privkey
));
1636 if (local_key
== NULL
)
1642 if (_E_gnutls_openpgp_privkey_to_gkey
== NULL
)
1648 ret
= _E_gnutls_openpgp_privkey_to_gkey (local_key
, key
);
1660 _gnutls_selected_certs_deinit (gnutls_session_t session
)
1662 if (session
->internals
.selected_need_free
!= 0)
1666 for (i
= 0; i
< session
->internals
.selected_cert_list_length
; i
++)
1668 _gnutls_gcert_deinit (&session
->internals
.selected_cert_list
[i
]);
1670 gnutls_free (session
->internals
.selected_cert_list
);
1671 session
->internals
.selected_cert_list
= NULL
;
1672 session
->internals
.selected_cert_list_length
= 0;
1674 _gnutls_gkey_deinit (session
->internals
.selected_key
);
1675 if (session
->internals
.selected_key
)
1677 gnutls_free (session
->internals
.selected_key
);
1678 session
->internals
.selected_key
= NULL
;
1686 _gnutls_selected_certs_set (gnutls_session_t session
,
1687 gnutls_cert
* certs
, int ncerts
,
1688 gnutls_privkey
* key
, int need_free
)
1690 _gnutls_selected_certs_deinit (session
);
1692 session
->internals
.selected_cert_list
= certs
;
1693 session
->internals
.selected_cert_list_length
= ncerts
;
1694 session
->internals
.selected_key
= key
;
1695 session
->internals
.selected_need_free
= need_free
;
1700 /* finds the most appropriate certificate in the cert list.
1701 * The 'appropriate' is defined by the user.
1703 * requested_algo holds the parameters required by the peer (RSA, DSA
1706 * Returns 0 on success and a negative value on error. The
1707 * selected certificate will be in session->internals.selected_*.
1711 _gnutls_server_select_cert (gnutls_session_t session
,
1712 gnutls_pk_algorithm_t requested_algo
)
1716 gnutls_certificate_credentials_t cred
;
1718 cred
= (gnutls_certificate_credentials_t
)
1719 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1723 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1726 /* If the callback which retrieves certificate has been set,
1729 if (cred
->server_get_cert_callback
!= NULL
)
1730 return call_get_cert_callback (session
, NULL
, 0, NULL
, 0);
1735 idx
= -1; /* default is use no certificate */
1738 for (i
= 0; i
< cred
->ncerts
; i
++)
1740 /* find one compatible certificate
1742 if (requested_algo
== GNUTLS_PK_ANY
||
1743 requested_algo
== cred
->cert_list
[i
][0].subject_pk_algorithm
)
1745 /* if cert type matches
1747 if (session
->security_parameters
.cert_type
==
1748 cred
->cert_list
[i
][0].cert_type
)
1756 /* store the certificate pointer for future use, in the handshake.
1757 * (This will allow not calling this callback again.)
1759 if (idx
>= 0 && ret
== 0)
1761 _gnutls_selected_certs_set (session
,
1762 &cred
->cert_list
[idx
][0],
1763 cred
->cert_list_length
[idx
],
1764 &cred
->pkey
[idx
], 0);
1767 /* Certificate does not support REQUESTED_ALGO. */
1768 ret
= GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1773 /* Frees the rsa_info_st structure.
1776 _gnutls_free_rsa_info (rsa_info_st
* rsa
)
1778 _gnutls_free_datum (&rsa
->modulus
);
1779 _gnutls_free_datum (&rsa
->exponent
);