2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
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>
49 # include "openpgp/gnutls_openpgp.h"
51 static gnutls_privkey
*
52 alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key
);
54 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
);
58 static gnutls_cert
*alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
,
60 static gnutls_privkey
*alloc_and_load_x509_key (gnutls_x509_privkey_t key
);
64 /* Copies data from a internal certificate struct (gnutls_cert) to
65 * exported certificate struct (cert_auth_info_t)
68 _gnutls_copy_certificate_auth_info (cert_auth_info_t info
,
69 gnutls_cert
* cert
, int ncerts
)
71 /* Copy peer's information to auth_info_t
77 info
->raw_certificate_list
= NULL
;
82 info
->raw_certificate_list
=
83 gnutls_calloc (1, sizeof (gnutls_datum_t
) * ncerts
);
84 if (info
->raw_certificate_list
== NULL
)
87 return GNUTLS_E_MEMORY_ERROR
;
90 for (i
= 0; i
< ncerts
; i
++)
92 if (cert
->raw
.size
> 0)
95 _gnutls_set_datum (&info
->
96 raw_certificate_list
[i
],
97 cert
[i
].raw
.data
, cert
[i
].raw
.size
);
105 info
->ncerts
= ncerts
;
107 info
->cert_type
= cert
[0].cert_type
;
108 #ifdef ENABLE_OPENPGP
109 if (cert
[0].cert_type
== GNUTLS_CRT_OPENPGP
)
111 info
->use_subkey
= cert
[0].use_subkey
;
112 memcpy( info
->subkey_id
, cert
[0].subkey_id
, sizeof(info
->subkey_id
));
120 for (j
= 0; j
< i
; j
++)
121 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
123 gnutls_free (info
->raw_certificate_list
);
124 info
->raw_certificate_list
= NULL
;
132 /* returns 0 if the algo_to-check exists in the pk_algos list,
136 _gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t
*
137 pk_algos
, int pk_algos_length
,
138 gnutls_pk_algorithm_t algo_to_check
)
141 for (i
= 0; i
< pk_algos_length
; i
++)
143 if (algo_to_check
== pk_algos
[i
])
152 /* Returns the issuer's Distinguished name in odn, of the certificate
156 _gnutls_cert_get_issuer_dn (gnutls_cert
* cert
, gnutls_datum_t
* odn
)
162 if ((result
= asn1_create_element
163 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn
)) != ASN1_SUCCESS
)
166 return _gnutls_asn2err (result
);
169 result
= asn1_der_decoding (&dn
, cert
->raw
.data
, cert
->raw
.size
, NULL
);
170 if (result
!= ASN1_SUCCESS
)
172 /* couldn't decode DER */
174 asn1_delete_structure (&dn
);
175 return _gnutls_asn2err (result
);
178 result
= asn1_der_decoding_startEnd (dn
, cert
->raw
.data
, cert
->raw
.size
,
179 "tbsCertificate.issuer", &start
, &end
);
181 if (result
!= ASN1_SUCCESS
)
183 /* couldn't decode DER */
185 asn1_delete_structure (&dn
);
186 return _gnutls_asn2err (result
);
188 asn1_delete_structure (&dn
);
190 len
= end
- start
+ 1;
193 odn
->data
= &cert
->raw
.data
[start
];
199 /* Locates the most appropriate x509 certificate using the
200 * given DN. If indx == -1 then no certificate was found.
202 * That is to guess which certificate to use, based on the
203 * CAs and sign algorithms supported by the peer server.
206 _find_x509_cert (const gnutls_certificate_credentials_t cred
,
207 opaque
* _data
, size_t _data_size
,
208 const gnutls_pk_algorithm_t
* pk_algos
,
209 int pk_algos_length
, int *indx
)
212 gnutls_datum_t odn
= { NULL
, 0 };
213 opaque
*data
= _data
;
214 ssize_t data_size
= _data_size
;
223 DECR_LENGTH_RET (data_size
, 2, 0);
224 size
= _gnutls_read_uint16 (data
);
225 DECR_LENGTH_RET (data_size
, size
, 0);
228 for (i
= 0; i
< cred
->ncerts
; i
++)
230 for (j
= 0; j
< cred
->cert_list_length
[i
]; j
++)
233 _gnutls_cert_get_issuer_dn (&cred
->
234 cert_list
[i
][j
], &odn
)) < 0)
240 if (odn
.size
!= size
)
243 /* If the DN matches and
244 * the *_SIGN algorithm matches
245 * the cert is our cert!
247 cert_pk
= cred
->cert_list
[i
][0].subject_pk_algorithm
;
249 if ((memcmp (odn
.data
, data
, size
) == 0) &&
250 (_gnutls_check_pk_algo_in_list
251 (pk_algos
, pk_algos_length
, cert_pk
) == 0))
264 /* move to next record */
274 #ifdef ENABLE_OPENPGP
275 /* Locates the most appropriate openpgp cert
278 _find_openpgp_cert (const gnutls_certificate_credentials_t cred
,
279 gnutls_pk_algorithm_t
* pk_algos
,
280 int pk_algos_length
, int *indx
)
286 for (i
= 0; i
< cred
->ncerts
; i
++)
288 for (j
= 0; j
< cred
->cert_list_length
[i
]; j
++)
291 /* If the *_SIGN algorithm matches
292 * the cert is our cert!
294 if ((_gnutls_check_pk_algo_in_list
295 (pk_algos
, pk_algos_length
,
296 cred
->cert_list
[i
][0].subject_pk_algorithm
) == 0)
297 && (cred
->cert_list
[i
][0].cert_type
== GNUTLS_CRT_OPENPGP
))
311 /* Returns the number of issuers in the server's
312 * certificate request packet.
315 get_issuers_num (gnutls_session_t session
, opaque
* data
, ssize_t data_size
)
317 int issuers_dn_len
= 0, result
;
320 /* Count the number of the given issuers;
321 * This is used to allocate the issuers_dn without
325 if (data_size
== 0 || data
== NULL
)
331 /* This works like DECR_LEN()
333 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
334 DECR_LENGTH_COM (data_size
, 2, goto error
);
335 size
= _gnutls_read_uint16 (data
);
337 result
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
338 DECR_LENGTH_COM (data_size
, size
, goto error
);
354 return issuers_dn_len
;
360 /* Returns the issuers in the server's certificate request
364 get_issuers (gnutls_session_t session
,
365 gnutls_datum_t
* issuers_dn
, int issuers_len
,
366 opaque
* data
, size_t data_size
)
371 if (gnutls_certificate_type_get (session
) != GNUTLS_CRT_X509
)
374 /* put the requested DNs to req_dn, only in case
375 * of X509 certificates.
380 for (i
= 0; i
< issuers_len
; i
++)
382 /* The checks here for the buffer boundaries
383 * are not needed since the buffer has been
388 size
= _gnutls_read_uint16 (data
);
392 issuers_dn
[i
].data
= data
;
393 issuers_dn
[i
].size
= size
;
402 /* Calls the client get callback.
405 call_get_cert_callback (gnutls_session_t session
,
406 gnutls_datum_t
* issuers_dn
,
407 int issuers_dn_length
,
408 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
411 gnutls_cert
*local_certs
= NULL
;
412 gnutls_privkey
*local_key
= NULL
;
415 gnutls_certificate_type_t type
= gnutls_certificate_type_get (session
);
416 gnutls_certificate_credentials_t cred
;
418 cred
= (gnutls_certificate_credentials_t
)
419 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
423 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
426 memset (&st
, 0, sizeof (st
));
428 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
430 ret
= cred
->server_get_cert_callback (session
, &st
);
435 cred
->client_get_cert_callback (session
,
436 issuers_dn
, issuers_dn_length
,
437 pk_algos
, pk_algos_length
, &st
);
443 return GNUTLS_E_INTERNAL_ERROR
;
447 return 0; /* no certificate was selected */
452 ret
= GNUTLS_E_INVALID_REQUEST
;
456 if (type
== GNUTLS_CRT_X509
)
458 local_certs
= alloc_and_load_x509_certs (st
.cert
.x509
, st
.ncerts
);
459 if (local_certs
!= NULL
&& st
.key
.x509
!= NULL
)
461 local_key
= alloc_and_load_x509_key (st
.key
.x509
);
462 if (local_key
== NULL
)
465 ret
= GNUTLS_E_INTERNAL_ERROR
;
476 ret
= GNUTLS_E_INVALID_REQUEST
;
480 #ifdef ENABLE_OPENPGP
482 local_certs
= alloc_and_load_pgp_certs (st
.cert
.pgp
);
483 if (local_certs
!= NULL
&& st
.key
.pgp
!= NULL
)
485 local_key
= alloc_and_load_pgp_key (st
.key
.pgp
);
486 if (local_key
== NULL
)
489 ret
= GNUTLS_E_INTERNAL_ERROR
;
497 _gnutls_selected_certs_set (session
, local_certs
,
498 (local_certs
!= NULL
) ? st
.ncerts
: 0,
505 if (st
.type
== GNUTLS_CRT_X509
)
509 for (i
= 0; i
< st
.ncerts
; i
++)
511 gnutls_x509_crt_deinit (st
.cert
.x509
[i
]);
513 gnutls_free (st
.cert
.x509
);
514 gnutls_x509_privkey_deinit (st
.key
.x509
);
519 #ifdef ENABLE_OPENPGP
522 gnutls_openpgp_crt_deinit (st
.cert
.pgp
);
523 gnutls_openpgp_privkey_deinit (st
.key
.pgp
);
531 /* Finds the appropriate certificate depending on the cA Distinguished name
532 * advertized by the server. If none matches then returns 0 and -1 as index.
533 * In case of an error a negative value, is returned.
535 * 20020128: added ability to select a certificate depending on the SIGN
536 * algorithm (only in automatic mode).
539 _select_client_cert (gnutls_session_t session
,
540 opaque
* _data
, size_t _data_size
,
541 gnutls_pk_algorithm_t
* pk_algos
, int pk_algos_length
)
545 gnutls_certificate_credentials_t cred
;
546 opaque
*data
= _data
;
547 ssize_t data_size
= _data_size
;
548 int issuers_dn_length
;
549 gnutls_datum_t
*issuers_dn
= NULL
;
551 cred
= (gnutls_certificate_credentials_t
)
552 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
556 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
559 if (cred
->client_get_cert_callback
!= NULL
)
562 /* use a callback to get certificate
564 if (session
->security_parameters
.cert_type
!= GNUTLS_CRT_X509
)
565 issuers_dn_length
= 0;
568 issuers_dn_length
= get_issuers_num (session
, data
, data_size
);
569 if (issuers_dn_length
< 0)
572 return issuers_dn_length
;
575 if (issuers_dn_length
> 0)
578 gnutls_malloc (sizeof (gnutls_datum_t
) * issuers_dn_length
);
579 if (issuers_dn
== NULL
)
582 return GNUTLS_E_MEMORY_ERROR
;
586 get_issuers (session
, issuers_dn
, issuers_dn_length
,
597 call_get_cert_callback (session
, issuers_dn
, issuers_dn_length
,
598 pk_algos
, pk_algos_length
);
604 /* If we have no callbacks, try to guess.
608 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
)
610 _find_x509_cert (cred
, _data
, _data_size
,
611 pk_algos
, pk_algos_length
, &indx
);
613 #ifdef ENABLE_OPENPGP
614 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
)
615 result
= _find_openpgp_cert (cred
, pk_algos
, pk_algos_length
, &indx
);
626 _gnutls_selected_certs_set (session
,
627 &cred
->cert_list
[indx
][0],
628 cred
->cert_list_length
[indx
],
629 &cred
->pkey
[indx
], 0);
633 _gnutls_selected_certs_set (session
, NULL
, 0, NULL
, 0);
640 gnutls_free (issuers_dn
);
645 /* Generate client certificate
649 _gnutls_gen_x509_crt (gnutls_session_t session
, opaque
** data
)
653 gnutls_cert
*apr_cert_list
;
654 gnutls_privkey
*apr_pkey
;
655 int apr_cert_list_length
;
657 /* find the appropriate certificate
660 _gnutls_get_selected_cert (session
, &apr_cert_list
,
661 &apr_cert_list_length
, &apr_pkey
)) < 0)
668 for (i
= 0; i
< apr_cert_list_length
; i
++)
670 ret
+= apr_cert_list
[i
].raw
.size
+ 3;
675 /* if no certificates were found then send:
676 * 0B 00 00 03 00 00 00 // Certificate with no certs
678 * 0B 00 00 00 // empty certificate handshake
680 * ( the above is the whole handshake message, not
681 * the one produced here )
684 (*data
) = gnutls_malloc (ret
);
690 return GNUTLS_E_MEMORY_ERROR
;
692 _gnutls_write_uint24 (ret
- 3, pdata
);
694 for (i
= 0; i
< apr_cert_list_length
; i
++)
696 _gnutls_write_datum24 (pdata
, apr_cert_list
[i
].raw
);
697 pdata
+= (3 + apr_cert_list
[i
].raw
.size
);
703 enum PGPKeyDescriptorType
704 { PGP_KEY_FINGERPRINT
, PGP_KEY
, PGP_KEY_SUBKEY
, PGP_KEY_FINGERPRINT_SUBKEY
};
706 #ifdef ENABLE_OPENPGP
708 _gnutls_gen_openpgp_certificate (gnutls_session_t session
, opaque
** data
)
712 gnutls_cert
*apr_cert_list
;
713 gnutls_privkey
*apr_pkey
;
714 int apr_cert_list_length
;
716 /* find the appropriate certificate */
718 _gnutls_get_selected_cert (session
, &apr_cert_list
,
719 &apr_cert_list_length
, &apr_pkey
)) < 0)
728 if (apr_cert_list_length
> 0)
730 if (apr_cert_list
[0].use_subkey
!= 0)
731 ret
+= 1 + sizeof(apr_cert_list
[0].subkey_id
); /* for the keyid */
733 ret
+= apr_cert_list
[0].raw
.size
;
736 (*data
) = gnutls_malloc (ret
);
742 return GNUTLS_E_MEMORY_ERROR
;
745 _gnutls_write_uint24 (ret
- 3, pdata
);
749 if (apr_cert_list_length
> 0)
751 if (apr_cert_list
[0].use_subkey
!= 0)
753 *pdata
= PGP_KEY_SUBKEY
;
755 *pdata
= sizeof(apr_cert_list
[0].subkey_id
);
757 memcpy( pdata
, apr_cert_list
[0].subkey_id
, sizeof(apr_cert_list
[0].subkey_id
));
758 pdata
+= sizeof(apr_cert_list
[0].subkey_id
);
766 _gnutls_write_datum24 (pdata
, apr_cert_list
[0].raw
);
767 pdata
+= (3 + apr_cert_list
[0].raw
.size
);
769 else /* empty - no certificate */
773 _gnutls_write_uint24 (0, pdata
);
780 _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session
, opaque
** data
)
782 int ret
, packet_size
;
785 gnutls_cert
*apr_cert_list
;
786 gnutls_privkey
*apr_pkey
;
787 int apr_cert_list_length
;
789 /* find the appropriate certificate */
791 _gnutls_get_selected_cert (session
, &apr_cert_list
,
792 &apr_cert_list_length
, &apr_pkey
)) < 0)
800 if (apr_cert_list
[0].use_subkey
)
801 packet_size
+= 1 + sizeof(apr_cert_list
[0].subkey_id
); /* for the keyid */
803 /* Only v4 fingerprints are sent
805 if (apr_cert_list_length
> 0 && apr_cert_list
[0].version
== 4)
806 packet_size
+= 20 + 1;
807 else /* empty certificate case */
808 return _gnutls_gen_openpgp_certificate (session
, data
);
810 (*data
) = gnutls_malloc (packet_size
);
816 return GNUTLS_E_MEMORY_ERROR
;
819 _gnutls_write_uint24 (packet_size
- 3, pdata
);
822 if (apr_cert_list
[0].use_subkey
)
824 *pdata
= PGP_KEY_FINGERPRINT_SUBKEY
;
826 *pdata
= sizeof(apr_cert_list
[0].subkey_id
);
828 memcpy( pdata
, apr_cert_list
[0].subkey_id
, sizeof(apr_cert_list
[0].subkey_id
));
829 pdata
+= sizeof(apr_cert_list
[0].subkey_id
);
833 *pdata
= PGP_KEY_FINGERPRINT
; /* key fingerprint */
843 _gnutls_openpgp_fingerprint (&apr_cert_list
[0].raw
, pdata
,
856 _gnutls_gen_cert_client_certificate (gnutls_session_t session
, opaque
** data
)
858 switch (session
->security_parameters
.cert_type
)
860 #ifdef ENABLE_OPENPGP
861 case GNUTLS_CRT_OPENPGP
:
862 if (_gnutls_openpgp_send_fingerprint (session
) == 0)
863 return _gnutls_gen_openpgp_certificate (session
, data
);
865 return _gnutls_gen_openpgp_certificate_fpr (session
, data
);
867 case GNUTLS_CRT_X509
:
868 return _gnutls_gen_x509_crt (session
, data
);
872 return GNUTLS_E_INTERNAL_ERROR
;
877 _gnutls_gen_cert_server_certificate (gnutls_session_t session
, opaque
** data
)
879 switch (session
->security_parameters
.cert_type
)
881 #ifdef ENABLE_OPENPGP
882 case GNUTLS_CRT_OPENPGP
:
883 return _gnutls_gen_openpgp_certificate (session
, data
);
885 case GNUTLS_CRT_X509
:
886 return _gnutls_gen_x509_crt (session
, data
);
889 return GNUTLS_E_INTERNAL_ERROR
;
893 /* Process server certificate
896 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
898 _gnutls_proc_x509_server_certificate (gnutls_session_t session
,
899 opaque
* data
, size_t data_size
)
903 cert_auth_info_t info
;
904 gnutls_certificate_credentials_t cred
;
905 ssize_t dsize
= data_size
;
907 gnutls_cert
*peer_certificate_list
;
908 int peer_certificate_list_size
= 0;
911 cred
= (gnutls_certificate_credentials_t
)
912 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
916 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
921 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
922 sizeof (cert_auth_info_st
), 1)) < 0)
928 info
= _gnutls_get_auth_info (session
);
930 if (data
== NULL
|| data_size
== 0)
933 /* no certificate was sent */
934 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
938 size
= _gnutls_read_uint24 (p
);
941 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
942 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
944 if (size
== 0 || size
== 3)
947 /* no certificate was sent */
948 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
955 len
= _gnutls_read_uint24 (p
);
957 DECR_LEN (dsize
, len
);
958 peer_certificate_list_size
++;
963 if (peer_certificate_list_size
== 0)
966 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
969 /* Ok we now allocate the memory to hold the
973 peer_certificate_list
=
974 gnutls_malloc (sizeof (gnutls_cert
) * (peer_certificate_list_size
));
976 if (peer_certificate_list
== NULL
)
979 return GNUTLS_E_MEMORY_ERROR
;
981 memset (peer_certificate_list
, 0, sizeof (gnutls_cert
) *
982 peer_certificate_list_size
);
986 /* Now we start parsing the list (again).
987 * We don't use DECR_LEN since the list has
988 * been parsed before.
991 for (j
= 0; j
< peer_certificate_list_size
; j
++)
993 len
= _gnutls_read_uint24 (p
);
1000 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
1002 CERT_ONLY_EXTENSIONS
)) < 0)
1013 _gnutls_copy_certificate_auth_info (info
,
1014 peer_certificate_list
,
1015 peer_certificate_list_size
)) < 0)
1022 _gnutls_check_key_usage (&peer_certificate_list
[0],
1023 gnutls_kx_get (session
))) < 0)
1033 gnutls_free (peer_certificate_list
);
1038 #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
1039 #ifdef ENABLE_OPENPGP
1041 _gnutls_proc_openpgp_server_certificate (gnutls_session_t session
,
1042 opaque
* data
, size_t data_size
)
1046 cert_auth_info_t info
;
1047 gnutls_certificate_credentials_t cred
;
1048 ssize_t dsize
= data_size
;
1050 gnutls_cert
*peer_certificate_list
= NULL
;
1051 int peer_certificate_list_size
= 0;
1052 gnutls_datum_t tmp
, akey
= { NULL
, 0 };
1053 gnutls_openpgp_keyid_t subkey_id
;
1054 unsigned int subkey_id_set
= 0;
1056 cred
= (gnutls_certificate_credentials_t
)
1057 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1061 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1065 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1066 sizeof (cert_auth_info_st
), 1)) < 0)
1072 info
= _gnutls_get_auth_info (session
);
1074 if (data
== NULL
|| data_size
== 0)
1077 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1080 DECR_LEN (dsize
, 3);
1081 size
= _gnutls_read_uint24 (p
);
1087 /* no certificate was sent */
1088 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1092 /* Read PGPKeyDescriptor */
1093 DECR_LEN (dsize
, 1);
1097 /* Try to read the keyid if present */
1098 if (key_type
== PGP_KEY_FINGERPRINT_SUBKEY
|| key_type
== PGP_KEY_SUBKEY
)
1101 if (*p
!= sizeof( subkey_id
))
1104 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1107 DECR_LEN (dsize
, 1);
1110 DECR_LEN (dsize
, sizeof( subkey_id
));
1111 memcpy( subkey_id
, p
, sizeof( subkey_id
));
1112 p
+= sizeof( subkey_id
);
1118 /* read the actual key or fingerprint */
1119 if (key_type
== PGP_KEY_FINGERPRINT
|| key_type
== PGP_KEY_FINGERPRINT_SUBKEY
)
1120 { /* the fingerprint */
1122 DECR_LEN (dsize
, 1);
1123 len
= (uint8_t) * p
;
1129 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED
;
1132 DECR_LEN (dsize
, 20);
1134 /* request the actual key from our database, or
1135 * a key server or anything.
1138 _gnutls_openpgp_request_key (session
, &akey
, cred
, p
, 20)) < 0)
1144 peer_certificate_list_size
++;
1147 else if (key_type
== PGP_KEY
|| key_type
== PGP_KEY_SUBKEY
)
1148 { /* the whole key */
1150 /* Read the actual certificate */
1151 DECR_LEN (dsize
, 3);
1152 len
= _gnutls_read_uint24 (p
);
1158 /* no certificate was sent */
1159 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
1162 DECR_LEN (dsize
, len
);
1163 peer_certificate_list_size
++;
1172 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE
;
1175 /* ok we now have the peer's key in tmp datum
1178 if (peer_certificate_list_size
== 0)
1181 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1184 peer_certificate_list
=
1185 gnutls_malloc (sizeof (gnutls_cert
) * (peer_certificate_list_size
));
1186 if (peer_certificate_list
== NULL
)
1189 ret
= GNUTLS_E_MEMORY_ERROR
;
1192 memset (peer_certificate_list
, 0, sizeof (gnutls_cert
) *
1193 peer_certificate_list_size
);
1196 _gnutls_openpgp_raw_crt_to_gcert (&peer_certificate_list
[0],
1197 &tmp
, subkey_id_set
?subkey_id
:NULL
)) < 0)
1204 _gnutls_copy_certificate_auth_info (info
,
1205 peer_certificate_list
,
1206 peer_certificate_list_size
)) < 0)
1213 _gnutls_check_key_usage (&peer_certificate_list
[0],
1214 gnutls_kx_get (session
))) < 0)
1224 _gnutls_free_datum (&akey
);
1226 gnutls_free (peer_certificate_list
);
1233 _gnutls_proc_cert_server_certificate (gnutls_session_t session
,
1234 opaque
* data
, size_t data_size
)
1236 switch (session
->security_parameters
.cert_type
)
1238 #ifdef ENABLE_OPENPGP
1239 case GNUTLS_CRT_OPENPGP
:
1240 return _gnutls_proc_openpgp_server_certificate (session
,
1243 case GNUTLS_CRT_X509
:
1244 return _gnutls_proc_x509_server_certificate (session
, data
, data_size
);
1247 return GNUTLS_E_INTERNAL_ERROR
;
1251 #define MAX_SIGN_ALGOS 2
1252 typedef enum CertificateSigType
1253 { RSA_SIGN
= 1, DSA_SIGN
1254 } CertificateSigType
;
1256 /* Checks if we support the given signature algorithm
1257 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1261 _gnutls_check_supported_sign_algo (CertificateSigType algo
)
1266 return GNUTLS_PK_RSA
;
1268 return GNUTLS_PK_DSA
;
1275 _gnutls_proc_cert_cert_req (gnutls_session_t session
, opaque
* data
,
1280 gnutls_certificate_credentials_t cred
;
1281 cert_auth_info_t info
;
1284 gnutls_pk_algorithm_t pk_algos
[MAX_SIGN_ALGOS
];
1285 int pk_algos_length
;
1286 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1288 cred
= (gnutls_certificate_credentials_t
)
1289 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1293 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1297 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
1298 sizeof (cert_auth_info_st
), 0)) < 0)
1304 info
= _gnutls_get_auth_info (session
);
1309 DECR_LEN (dsize
, 1);
1312 /* check if the sign algorithm is supported.
1314 pk_algos_length
= j
= 0;
1315 for (i
= 0; i
< size
; i
++, p
++)
1317 DECR_LEN (dsize
, 1);
1318 if ((ret
= _gnutls_check_supported_sign_algo (*p
)) > 0)
1320 if (j
< MAX_SIGN_ALGOS
)
1322 pk_algos
[j
++] = ret
;
1328 if (pk_algos_length
== 0)
1331 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1334 if (ver
== GNUTLS_TLS1_2
)
1336 /* read supported hashes */
1338 DECR_LEN (dsize
, 1);
1340 hash_num
= p
[0] & 0xFF;
1343 DECR_LEN (dsize
, hash_num
);
1347 /* read the certificate authorities */
1348 DECR_LEN (dsize
, 2);
1349 size
= _gnutls_read_uint16 (p
);
1352 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_OPENPGP
&& size
!= 0)
1354 gnutls_assert(); // size should be zero
1355 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1358 DECR_LEN (dsize
, size
);
1360 /* now we ask the user to tell which one
1364 _select_client_cert (session
, p
, size
, pk_algos
, pk_algos_length
)) < 0)
1370 /* We should reply with a certificate message,
1371 * even if we have no certificate to send.
1373 session
->key
->certificate_requested
= 1;
1379 _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session
, opaque
** data
)
1382 gnutls_cert
*apr_cert_list
;
1383 gnutls_privkey
*apr_pkey
;
1384 int apr_cert_list_length
, size
;
1385 gnutls_datum_t signature
;
1389 /* find the appropriate certificate */
1391 _gnutls_get_selected_cert (session
, &apr_cert_list
,
1392 &apr_cert_list_length
, &apr_pkey
)) < 0)
1398 if (apr_cert_list_length
> 0)
1401 _gnutls_tls_sign_hdata (session
,
1403 apr_pkey
, &signature
)) < 0)
1414 *data
= gnutls_malloc (signature
.size
+ 2);
1417 _gnutls_free_datum (&signature
);
1418 return GNUTLS_E_MEMORY_ERROR
;
1420 size
= signature
.size
;
1421 _gnutls_write_uint16 (size
, *data
);
1423 memcpy (&(*data
)[2], signature
.data
, size
);
1425 _gnutls_free_datum (&signature
);
1431 _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session
,
1432 opaque
* data
, size_t data_size
)
1435 ssize_t dsize
= data_size
;
1436 opaque
*pdata
= data
;
1438 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
1439 gnutls_cert peer_cert
;
1441 if (info
== NULL
|| info
->ncerts
== 0)
1444 /* we need this in order to get peer's certificate */
1445 return GNUTLS_E_INTERNAL_ERROR
;
1448 DECR_LEN (dsize
, 2);
1449 size
= _gnutls_read_uint16 (pdata
);
1452 DECR_LEN (dsize
, size
);
1457 ret
= _gnutls_get_auth_info_gcert (&peer_cert
,
1458 session
->security_parameters
.cert_type
,
1459 info
, CERT_NO_COPY
);
1467 if ((ret
= _gnutls_verify_sig_hdata (session
, &peer_cert
, &sig
)) < 0)
1470 _gnutls_gcert_deinit (&peer_cert
);
1473 _gnutls_gcert_deinit (&peer_cert
);
1478 #define CERTTYPE_SIZE 3
1480 _gnutls_gen_cert_server_cert_req (gnutls_session_t session
, opaque
** data
)
1482 gnutls_certificate_credentials_t cred
;
1485 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
1487 /* Now we need to generate the RDN sequence. This is
1488 * already in the CERTIFICATE_CRED structure, to improve
1492 cred
= (gnutls_certificate_credentials_t
)
1493 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1497 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1500 size
= CERTTYPE_SIZE
+ 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1503 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1504 session
->internals
.ignore_rdn_sequence
== 0)
1505 size
+= cred
->x509_rdn_sequence
.size
;
1507 if (ver
== GNUTLS_TLS1_2
)
1508 /* Need at least one byte to announce the number of supported hash
1509 functions (see below). */
1512 (*data
) = gnutls_malloc (size
);
1518 return GNUTLS_E_MEMORY_ERROR
;
1521 pdata
[0] = CERTTYPE_SIZE
- 1;
1523 pdata
[1] = RSA_SIGN
;
1524 pdata
[2] = DSA_SIGN
; /* only these for now */
1525 pdata
+= CERTTYPE_SIZE
;
1527 if (ver
== GNUTLS_TLS1_2
)
1529 /* Supported hashes (nothing for now -- FIXME). */
1534 if (session
->security_parameters
.cert_type
== GNUTLS_CRT_X509
&&
1535 session
->internals
.ignore_rdn_sequence
== 0)
1537 _gnutls_write_datum16 (pdata
, cred
->x509_rdn_sequence
);
1538 /* pdata += cred->x509_rdn_sequence.size + 2; */
1542 _gnutls_write_uint16( 0, pdata
);
1550 /* This function will return the appropriate certificate to use.
1551 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1552 * The return value is a negative value on error.
1554 * It is normal to return 0 with no certificates in client side.
1558 _gnutls_get_selected_cert (gnutls_session_t session
,
1559 gnutls_cert
** apr_cert_list
,
1560 int *apr_cert_list_length
,
1561 gnutls_privkey
** apr_pkey
)
1563 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
1566 /* select_client_cert() has been called before.
1569 *apr_cert_list
= session
->internals
.selected_cert_list
;
1570 *apr_pkey
= session
->internals
.selected_key
;
1571 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1573 if (*apr_cert_list_length
== 0 || *apr_cert_list
== NULL
)
1576 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1584 /* we have already decided which certificate
1587 *apr_cert_list
= session
->internals
.selected_cert_list
;
1588 *apr_cert_list_length
= session
->internals
.selected_cert_list_length
;
1589 *apr_pkey
= session
->internals
.selected_key
;
1596 /* converts the given x509 certificate to gnutls_cert* and allocates
1599 static gnutls_cert
*
1600 alloc_and_load_x509_certs (gnutls_x509_crt_t
* certs
, unsigned ncerts
)
1602 gnutls_cert
*local_certs
;
1609 local_certs
= gnutls_malloc (sizeof (gnutls_cert
) * ncerts
);
1610 if (local_certs
== NULL
)
1616 for (i
= 0; i
< ncerts
; i
++)
1618 ret
= _gnutls_x509_crt_to_gcert (&local_certs
[i
], certs
[i
], 0);
1626 for (j
= 0; j
< i
; j
++)
1628 _gnutls_gcert_deinit (&local_certs
[j
]);
1630 gnutls_free (local_certs
);
1637 /* converts the given x509 key to gnutls_privkey* and allocates
1640 static gnutls_privkey
*
1641 alloc_and_load_x509_key (gnutls_x509_privkey_t key
)
1643 gnutls_privkey
*local_key
;
1649 local_key
= gnutls_malloc (sizeof (gnutls_privkey
));
1650 if (local_key
== NULL
)
1656 ret
= _gnutls_x509_privkey_to_gkey (local_key
, key
);
1666 /* converts the given pgp certificate to gnutls_cert* and allocates
1669 #ifdef ENABLE_OPENPGP
1670 static gnutls_cert
*
1671 alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert
)
1673 gnutls_cert
*local_certs
;
1679 local_certs
= gnutls_malloc (sizeof (gnutls_cert
));
1680 if (local_certs
== NULL
)
1686 ret
= _gnutls_openpgp_crt_to_gcert (local_certs
, cert
);
1696 _gnutls_gcert_deinit (local_certs
);
1697 gnutls_free (local_certs
);
1701 ret
= gnutls_openpgp_crt_get_preferred_key_id( cert
, local_certs
->subkey_id
);
1703 local_certs
->use_subkey
= 0;
1705 local_certs
->use_subkey
= 1;
1710 /* converts the given raw key to gnutls_privkey* and allocates
1713 static gnutls_privkey
*
1714 alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key
)
1716 gnutls_privkey
*local_key
;
1722 local_key
= gnutls_malloc (sizeof (gnutls_privkey
));
1723 if (local_key
== NULL
)
1729 ret
= _gnutls_openpgp_privkey_to_gkey (local_key
, key
);
1741 _gnutls_selected_certs_deinit (gnutls_session_t session
)
1743 if (session
->internals
.selected_need_free
!= 0)
1747 for (i
= 0; i
< session
->internals
.selected_cert_list_length
; i
++)
1749 _gnutls_gcert_deinit (&session
->internals
.selected_cert_list
[i
]);
1751 gnutls_free (session
->internals
.selected_cert_list
);
1752 session
->internals
.selected_cert_list
= NULL
;
1753 session
->internals
.selected_cert_list_length
= 0;
1755 _gnutls_gkey_deinit (session
->internals
.selected_key
);
1756 if (session
->internals
.selected_key
)
1758 gnutls_free (session
->internals
.selected_key
);
1759 session
->internals
.selected_key
= NULL
;
1767 _gnutls_selected_certs_set (gnutls_session_t session
,
1768 gnutls_cert
* certs
, int ncerts
,
1769 gnutls_privkey
* key
, int need_free
)
1771 _gnutls_selected_certs_deinit (session
);
1773 session
->internals
.selected_cert_list
= certs
;
1774 session
->internals
.selected_cert_list_length
= ncerts
;
1775 session
->internals
.selected_key
= key
;
1776 session
->internals
.selected_need_free
= need_free
;
1781 /* finds the most appropriate certificate in the cert list.
1782 * The 'appropriate' is defined by the user.
1784 * requested_algo holds the parameters required by the peer (RSA, DSA
1787 * Returns 0 on success and a negative value on error. The
1788 * selected certificate will be in session->internals.selected_*.
1792 _gnutls_server_select_cert (gnutls_session_t session
,
1793 gnutls_pk_algorithm_t requested_algo
)
1797 gnutls_certificate_credentials_t cred
;
1799 cred
= (gnutls_certificate_credentials_t
)
1800 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
1804 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1807 /* If the callback which retrieves certificate has been set,
1810 if (cred
->server_get_cert_callback
!= NULL
)
1811 return call_get_cert_callback (session
, NULL
, 0, NULL
, 0);
1816 idx
= -1; /* default is use no certificate */
1819 for (i
= 0; i
< cred
->ncerts
; i
++)
1821 /* find one compatible certificate
1823 if (requested_algo
== GNUTLS_PK_ANY
||
1824 requested_algo
== cred
->cert_list
[i
][0].subject_pk_algorithm
)
1826 /* if cert type matches
1828 if (session
->security_parameters
.cert_type
==
1829 cred
->cert_list
[i
][0].cert_type
)
1837 /* store the certificate pointer for future use, in the handshake.
1838 * (This will allow not calling this callback again.)
1840 if (idx
>= 0 && ret
== 0)
1842 _gnutls_selected_certs_set (session
,
1843 &cred
->cert_list
[idx
][0],
1844 cred
->cert_list_length
[idx
],
1845 &cred
->pkey
[idx
], 0);
1848 /* Certificate does not support REQUESTED_ALGO. */
1849 ret
= GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
1854 /* Frees the rsa_info_st structure.
1857 _gnutls_free_rsa_info (rsa_info_st
* rsa
)
1859 _gnutls_free_datum (&rsa
->modulus
);
1860 _gnutls_free_datum (&rsa
->exponent
);