*** empty log message ***
[gnutls.git] / lib / gnutls_cert.c
bloba586a3cf725aab25cfee188618b645bb6f15a863
1 /*
2 * Copyright (C) 2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <gnutls_int.h>
23 #include <gnutls_errors.h>
24 #include <auth_cert.h>
25 #include <gnutls_cert.h>
26 #include <x509_asn1.h>
27 #include <x509_der.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_global.h>
31 #include <x509_verify.h>
32 #include <gnutls_privkey.h>
33 #include <x509_extensions.h>
34 #include <gnutls_algorithms.h>
35 #include <gnutls_dh.h>
36 #include <gnutls_str.h>
37 #include <gnutls_state.h>
38 #include <gnutls_auth_int.h>
39 #include <gnutls_x509.h>
40 #include <gnutls_extra.h>
42 /* KX mappings to PK algorithms */
43 typedef struct {
44 KXAlgorithm kx_algorithm;
45 PKAlgorithm pk_algorithm;
46 } gnutls_pk_map;
48 /* This table maps the Key exchange algorithms to
49 * the certificate algorithms. Eg. if we have
50 * RSA algorithm in the certificate then we can
51 * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
53 static const gnutls_pk_map pk_mappings[] = {
54 {GNUTLS_KX_RSA, GNUTLS_PK_RSA},
55 {GNUTLS_KX_DHE_RSA, GNUTLS_PK_RSA},
56 {GNUTLS_KX_DHE_DSS, GNUTLS_PK_DSA},
57 {0}
60 #define GNUTLS_PK_MAP_LOOP(b) \
61 const gnutls_pk_map *p; \
62 for(p = pk_mappings; p->kx_algorithm != 0; p++) { b ; }
64 #define GNUTLS_PK_MAP_ALG_LOOP(a) \
65 GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
68 /* returns the PKAlgorithm which is compatible with
69 * the given KXAlgorithm.
71 PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm)
73 PKAlgorithm ret = -1;
75 GNUTLS_PK_MAP_ALG_LOOP(ret = p->pk_algorithm);
76 return ret;
79 void _gnutls_free_cert(gnutls_cert cert)
81 int i;
83 for (i = 0; i < cert.params_size; i++) {
84 _gnutls_mpi_release(&cert.params[i]);
87 gnutls_free_datum(&cert.signature);
88 gnutls_free_datum(&cert.raw);
90 return;
93 /**
94 * gnutls_certificate_free_sc - Used to free an allocated CERTIFICATE CREDENTIALS structure
95 * @sc: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
97 * This structure is complex enough to manipulate directly thus
98 * this helper function is provided in order to free (deallocate)
99 * the structure.
101 void gnutls_certificate_free_sc(GNUTLS_CERTIFICATE_CREDENTIALS sc)
103 int i, j;
105 for (i = 0; i < sc->ncerts; i++) {
106 for (j = 0; j < sc->cert_list_length[i]; j++) {
107 _gnutls_free_cert(sc->cert_list[i][j]);
109 gnutls_free( sc->cert_list[i]);
112 gnutls_free(sc->cert_list_length);
113 gnutls_free(sc->cert_list);
115 for (j = 0; j < sc->x509_ncas; j++) {
116 _gnutls_free_cert( sc->x509_ca_list[j]);
119 gnutls_free( sc->x509_ca_list);
120 gnutls_free_datum( &sc->keyring);
122 for (i = 0; i < sc->ncerts; i++) {
123 _gnutls_free_private_key(sc->pkey[i]);
126 gnutls_free( sc->pkey);
127 gnutls_free( sc->x509_rdn_sequence.data);
129 gnutls_free( sc);
134 * gnutls_certificate_allocate_sc - Used to allocate an x509 SERVER CREDENTIALS structure
135 * @res: is a pointer to an &GNUTLS_CERTIFICATE_CREDENTIALS structure.
137 * This structure is complex enough to manipulate directly thus
138 * this helper function is provided in order to allocate
139 * the structure.
141 int gnutls_certificate_allocate_sc(GNUTLS_CERTIFICATE_CREDENTIALS * res)
143 *res = gnutls_calloc(1, sizeof(CERTIFICATE_CREDENTIALS_INT));
145 if (*res == NULL)
146 return GNUTLS_E_MEMORY_ERROR;
148 (*res)->dh_params = &_gnutls_dh_default_params;
150 return 0;
154 /* returns the KX algorithms that are supported by a
155 * certificate. (Eg a certificate with RSA params, supports
156 * GNUTLS_KX_RSA algorithm).
157 * This function also uses the KeyUsage field of the certificate
158 * extensions in order to disable unneded algorithms.
160 int _gnutls_cert_supported_kx(const gnutls_cert * cert, KXAlgorithm ** alg,
161 int *alg_size)
163 KXAlgorithm kx;
164 int i;
165 PKAlgorithm pk;
166 KXAlgorithm kxlist[MAX_ALGOS];
168 i = 0;
169 for (kx = 0; kx < MAX_ALGOS; kx++) {
170 pk = _gnutls_map_pk_get_pk(kx);
171 if (pk == cert->subject_pk_algorithm) {
172 if (cert->cert_type==GNUTLS_CRT_X509) {
173 /* then check key usage */
174 if (_gnutls_check_x509_key_usage(cert, kx) == 0) {
175 kxlist[i] = kx;
176 i++;
178 } else if ( cert->cert_type==GNUTLS_CRT_OPENPGP) {
179 /* FIXME: something like key usage
180 * should be added
182 kxlist[i] = kx;
183 i++;
188 if (i==0) {
189 gnutls_assert();
190 return GNUTLS_E_INVALID_PARAMETERS;
193 *alg = gnutls_calloc(1, sizeof(KXAlgorithm) * i);
194 if (*alg == NULL)
195 return GNUTLS_E_MEMORY_ERROR;
197 *alg_size = i;
199 memcpy(*alg, kxlist, i * sizeof(KXAlgorithm));
201 return 0;
206 * gnutls_certificate_server_set_request - Used to set whether to request a client certificate
207 * @state: is an &GNUTLS_STATE structure.
208 * @req: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE
210 * This function specifies if we (in case of a server) are going
211 * to send a certificate request message to the client. If 'req'
212 * is GNUTLS_CERT_REQUIRE then the server will return an error if
213 * the peer does not provide a certificate. If you do not
214 * call this function then the client will not be asked to
215 * send a certificate.
217 void gnutls_certificate_server_set_request(GNUTLS_STATE state,
218 CertificateRequest req)
220 state->gnutls_internals.send_cert_req = req;
224 * gnutls_certificate_client_set_select_func - Used to set a callback while selecting the proper (client) certificate
225 * @state: is a &GNUTLS_STATE structure.
226 * @func: is the callback function
228 * The callback's function form is:
229 * int (*callback)(GNUTLS_STATE, gnutls_datum *client_cert, int ncerts, gnutls_datum* req_ca_cert, int nreqs);
231 * 'client_cert' contains 'ncerts' gnutls_datum structures which hold
232 * the raw certificates (DER for X.509 or binary for OpenPGP), of the
233 * client.
235 * 'req_ca_cert', is only used in X.509 certificates.
236 * Contains a list with the CA names that the server considers trusted.
237 * Normaly we should send a certificate that is signed
238 * by one of these CAs. These names are DER encoded. To get a more
239 * meaningful value use the function gnutls_x509_extract_dn().
241 * This function specifies what we, in case of a client, are going
242 * to do when we have to send a certificate. If this callback
243 * function is not provided then gnutls will automaticaly try to
244 * find an appropriate certificate to send.
246 * If the callback function is provided then gnutls will call it
247 * once with NULL parameters. If the callback function returns
248 * a positive or zero number then gnutls will attempt to automaticaly
249 * choose the appropriate certificate. If gnutls fails to find an appropriate
250 * certificate, then it will call the callback function again with the
251 * appropriate parameters.
253 * In case the callback returned a negative number then gnutls will
254 * not attempt to choose the appropriate certificate and will call again
255 * the callback function with the appropriate parameters, and rely
256 * only to the return value of the callback function.
258 * The callback function should return the index of the certificate
259 * choosen by the user. -1 indicates that the user
260 * does not want to use client authentication.
262 * This function returns 0 on success.
264 void gnutls_certificate_client_set_select_func(GNUTLS_STATE state,
265 certificate_client_select_func
266 * func)
268 state->gnutls_internals.client_cert_callback = func;
272 * gnutls_certificate_server_set_select_func - Used to set a callback while selecting the proper (server) certificate
273 * @state: is a &GNUTLS_STATE structure.
274 * @func: is the callback function
276 * The callback's function form is:
277 * int (*callback)(GNUTLS_STATE, gnutls_datum *server_cert, int ncerts);
279 * 'server_cert' contains 'ncerts' gnutls_datum structures which hold
280 * the raw certificate (DER encoded in X.509) of the server.
282 * This function specifies what we, in case of a server, are going
283 * to do when we have to send a certificate. If this callback
284 * function is not provided then gnutls will automaticaly try to
285 * find an appropriate certificate to send. (actually send the first in the list)
287 * In case the callback returned a negative number then gnutls will
288 * not attempt to choose the appropriate certificate and the caller function
289 * will fail.
291 * The callback function will only be called once per handshake.
292 * The callback function should return the index of the certificate
293 * choosen by the server. -1 indicates an error.
296 void gnutls_certificate_server_set_select_func(GNUTLS_STATE state,
297 certificate_server_select_func
298 * func)
300 state->gnutls_internals.server_cert_callback = func;
303 /* These are set by the gnutls_extra library's initialization function.
306 OPENPGP_KEY_CREATION_TIME_FUNC _E_gnutls_openpgp_extract_key_creation_time = NULL;
307 OPENPGP_KEY_EXPIRATION_TIME_FUNC _E_gnutls_openpgp_extract_key_expiration_time = NULL;
308 OPENPGP_VERIFY_KEY_FUNC _E_gnutls_openpgp_verify_key = NULL;
311 * _gnutls_openpgp_cert_verify_peers - This function returns the peer's certificate status
312 * @state: is a gnutls state
314 * This function will try to verify the peer's certificate and return it's status (TRUSTED, INVALID etc.).
315 * Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
318 int _gnutls_openpgp_cert_verify_peers(GNUTLS_STATE state)
320 CERTIFICATE_AUTH_INFO info;
321 const GNUTLS_CERTIFICATE_CREDENTIALS cred;
322 CertificateStatus verify;
323 int peer_certificate_list_size;
325 CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
327 info = _gnutls_get_auth_info(state);
328 if (info == NULL)
329 return GNUTLS_E_INVALID_REQUEST;
331 cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_CERTIFICATE, NULL);
332 if (cred == NULL) {
333 gnutls_assert();
334 return GNUTLS_E_INSUFICIENT_CRED;
337 if (info->raw_certificate_list == NULL || info->ncerts == 0) {
338 gnutls_assert();
339 return GNUTLS_E_NO_CERTIFICATE_FOUND;
342 /* generate a list of gnutls_certs based on the auth info
343 * raw certs.
345 peer_certificate_list_size = info->ncerts;
347 if (peer_certificate_list_size != 1) {
348 gnutls_assert();
349 return GNUTLS_E_UNKNOWN_ERROR;
352 /* Verify certificate
354 if (_E_gnutls_openpgp_verify_key==NULL) {
355 gnutls_assert();
356 return GNUTLS_E_INVALID_REQUEST;
358 verify = _E_gnutls_openpgp_verify_key( cred->pgp_trustdb, &cred->keyring, &info->raw_certificate_list[0],
359 peer_certificate_list_size);
361 if (verify < 0) {
362 gnutls_assert();
363 return GNUTLS_CERT_INVALID;
367 return verify;
371 * gnutls_certificate_verify_peers - This function returns the peer's certificate verification status
372 * @state: is a gnutls state
374 * This function will try to verify the peer's certificate and return it's status (TRUSTED, INVALID etc.).
375 * The return value (status) should be one of the CertificateStatus enumerated elements.
376 * However you must also check the peer's name in order to check if the verified certificate belongs to the
377 * actual peer.
379 * The return value (status) should be one or more of the CertificateStatus
380 * enumerated elements bitwise or'd. The return value is the same as
381 * gnutls_x509_verify_certificate().
384 int gnutls_certificate_verify_peers(GNUTLS_STATE state)
386 CERTIFICATE_AUTH_INFO info;
388 CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
390 info = _gnutls_get_auth_info(state);
391 if (info == NULL) {
392 gnutls_assert();
393 return GNUTLS_E_NO_CERTIFICATE_FOUND;
396 if (info->raw_certificate_list == NULL || info->ncerts == 0)
397 return GNUTLS_E_NO_CERTIFICATE_FOUND;
399 switch( gnutls_cert_type_get( state)) {
400 case GNUTLS_CRT_X509:
401 return _gnutls_x509_cert_verify_peers( state);
402 case GNUTLS_CRT_OPENPGP:
403 return _gnutls_openpgp_cert_verify_peers( state);
404 default:
405 return GNUTLS_E_INVALID_REQUEST;
410 * gnutls_certificate_expiration_time_peers - This function returns the peer's certificate expiration time
411 * @state: is a gnutls state
413 * This function will return the peer's certificate expiration time.
415 * Returns (time_t) -1 on error.
418 time_t gnutls_certificate_expiration_time_peers(GNUTLS_STATE state)
420 CERTIFICATE_AUTH_INFO info;
422 CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
424 info = _gnutls_get_auth_info(state);
425 if (info == NULL) {
426 gnutls_assert();
427 return (time_t) -1;
430 if (info->raw_certificate_list == NULL || info->ncerts == 0) {
431 gnutls_assert();
432 return (time_t) -1;
435 switch( gnutls_cert_type_get( state)) {
436 case GNUTLS_CRT_X509:
437 return gnutls_x509_extract_certificate_expiration_time(
438 &info->raw_certificate_list[0]);
439 case GNUTLS_CRT_OPENPGP:
440 if (_E_gnutls_openpgp_extract_key_expiration_time==NULL)
441 return (time_t)-1;
442 return _E_gnutls_openpgp_extract_key_expiration_time(
443 &info->raw_certificate_list[0]);
444 default:
445 return (time_t)-1;
450 * gnutls_certificate_activation_time_peers - This function returns the peer's certificate activation time
451 * @state: is a gnutls state
453 * This function will return the peer's certificate activation time.
454 * This is the creation time for openpgp keys.
456 * Returns (time_t) -1 on error.
459 time_t gnutls_certificate_activation_time_peers(GNUTLS_STATE state)
461 CERTIFICATE_AUTH_INFO info;
463 CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
465 info = _gnutls_get_auth_info(state);
466 if (info == NULL) {
467 gnutls_assert();
468 return (time_t) -1;
471 if (info->raw_certificate_list == NULL || info->ncerts == 0) {
472 gnutls_assert();
473 return (time_t) -1;
476 switch( gnutls_cert_type_get( state)) {
477 case GNUTLS_CRT_X509:
478 return gnutls_x509_extract_certificate_activation_time(
479 &info->raw_certificate_list[0]);
480 case GNUTLS_CRT_OPENPGP:
481 if (_E_gnutls_openpgp_extract_key_creation_time==NULL)
482 return (time_t)-1;
483 return _E_gnutls_openpgp_extract_key_creation_time(
484 &info->raw_certificate_list[0]);
485 default:
486 return (time_t)-1;