Fixed leaks in key generation and other cleanups. Patch by Tomas Mraz.
[gnutls.git] / lib / gnutls_ui.c
blobc2d5b8850bc05edcebee635c9e3f8db494b26715
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains certificate authentication functions to be exported in the
27 * API and did not fit elsewhere.
30 #include <gnutls_int.h>
31 #include <auth_srp.h>
32 #include <auth_anon.h>
33 #include <auth_cert.h>
34 #include <auth_psk.h>
35 #include <gnutls_errors.h>
36 #include <gnutls_auth.h>
37 #include <gnutls_state.h>
38 #include <gnutls_datum.h>
40 /* ANON & DHE */
42 /**
43 * gnutls_dh_set_prime_bits:
44 * @session: is a #gnutls_session_t structure.
45 * @bits: is the number of bits
47 * This function sets the number of bits, for use in an Diffie-Hellman
48 * key exchange. This is used both in DH ephemeral and DH anonymous
49 * cipher suites. This will set the minimum size of the prime that
50 * will be used for the handshake.
52 * In the client side it sets the minimum accepted number of bits. If
53 * a server sends a prime with less bits than that
54 * %GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the handshake.
56 * This function has no effect in server side.
58 **/
59 void
60 gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits)
62 session->internals.dh_prime_bits = bits;
66 /**
67 * gnutls_dh_get_group:
68 * @session: is a gnutls session
69 * @raw_gen: will hold the generator.
70 * @raw_prime: will hold the prime.
72 * This function will return the group parameters used in the last
73 * Diffie-Hellman key exchange with the peer. These are the prime and
74 * the generator used. This function should be used for both
75 * anonymous and ephemeral Diffie-Hellman. The output parameters must
76 * be freed with gnutls_free().
78 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
79 * an error code is returned.
80 **/
81 int
82 gnutls_dh_get_group (gnutls_session_t session,
83 gnutls_datum_t * raw_gen, gnutls_datum_t * raw_prime)
85 dh_info_st *dh;
86 int ret;
87 anon_auth_info_t anon_info;
88 cert_auth_info_t cert_info;
89 psk_auth_info_t psk_info;
91 switch (gnutls_auth_get_type (session))
93 case GNUTLS_CRD_ANON:
94 anon_info = _gnutls_get_auth_info (session);
95 if (anon_info == NULL)
96 return GNUTLS_E_INTERNAL_ERROR;
97 dh = &anon_info->dh;
98 break;
99 case GNUTLS_CRD_PSK:
100 psk_info = _gnutls_get_auth_info (session);
101 if (psk_info == NULL)
102 return GNUTLS_E_INTERNAL_ERROR;
103 dh = &psk_info->dh;
104 break;
105 case GNUTLS_CRD_CERTIFICATE:
106 cert_info = _gnutls_get_auth_info (session);
107 if (cert_info == NULL)
108 return GNUTLS_E_INTERNAL_ERROR;
109 dh = &cert_info->dh;
110 break;
111 default:
112 gnutls_assert ();
113 return GNUTLS_E_INVALID_REQUEST;
116 ret = _gnutls_set_datum (raw_prime, dh->prime.data, dh->prime.size);
117 if (ret < 0)
119 gnutls_assert ();
120 return ret;
123 ret = _gnutls_set_datum (raw_gen, dh->generator.data, dh->generator.size);
124 if (ret < 0)
126 gnutls_assert ();
127 _gnutls_free_datum (raw_prime);
128 return ret;
131 return 0;
135 * gnutls_dh_get_pubkey:
136 * @session: is a gnutls session
137 * @raw_key: will hold the public key.
139 * This function will return the peer's public key used in the last
140 * Diffie-Hellman key exchange. This function should be used for both
141 * anonymous and ephemeral Diffie-Hellman. The output parameters must
142 * be freed with gnutls_free().
144 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
145 * an error code is returned.
148 gnutls_dh_get_pubkey (gnutls_session_t session, gnutls_datum_t * raw_key)
150 dh_info_st *dh;
151 anon_auth_info_t anon_info;
152 cert_auth_info_t cert_info;
153 cert_auth_info_t psk_info;
155 switch (gnutls_auth_get_type (session))
157 case GNUTLS_CRD_ANON:
159 anon_info = _gnutls_get_auth_info (session);
160 if (anon_info == NULL)
161 return GNUTLS_E_INTERNAL_ERROR;
162 dh = &anon_info->dh;
163 break;
165 case GNUTLS_CRD_PSK:
167 psk_info = _gnutls_get_auth_info (session);
168 if (psk_info == NULL)
169 return GNUTLS_E_INTERNAL_ERROR;
170 dh = &psk_info->dh;
171 break;
173 case GNUTLS_CRD_CERTIFICATE:
176 cert_info = _gnutls_get_auth_info (session);
177 if (cert_info == NULL)
178 return GNUTLS_E_INTERNAL_ERROR;
179 dh = &cert_info->dh;
180 break;
182 default:
183 gnutls_assert ();
184 return GNUTLS_E_INVALID_REQUEST;
187 return _gnutls_set_datum (raw_key, dh->public_key.data,
188 dh->public_key.size);
192 * gnutls_rsa_export_get_pubkey:
193 * @session: is a gnutls session
194 * @exponent: will hold the exponent.
195 * @modulus: will hold the modulus.
197 * This function will return the peer's public key exponent and
198 * modulus used in the last RSA-EXPORT authentication. The output
199 * parameters must be freed with gnutls_free().
201 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
202 * an error code is returned.
205 gnutls_rsa_export_get_pubkey (gnutls_session_t session,
206 gnutls_datum_t * exponent,
207 gnutls_datum_t * modulus)
209 cert_auth_info_t info;
210 int ret;
212 if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
214 info = _gnutls_get_auth_info (session);
215 if (info == NULL)
216 return GNUTLS_E_INTERNAL_ERROR;
218 ret = _gnutls_set_datum (modulus, info->rsa_export.modulus.data,
219 info->rsa_export.modulus.size);
220 if (ret < 0)
222 gnutls_assert ();
223 return ret;
226 ret = _gnutls_set_datum (exponent, info->rsa_export.exponent.data,
227 info->rsa_export.exponent.size);
228 if (ret < 0)
230 gnutls_assert ();
231 _gnutls_free_datum (modulus);
232 return ret;
235 return 0;
238 return GNUTLS_E_INVALID_REQUEST;
243 * gnutls_dh_get_secret_bits:
244 * @session: is a gnutls session
246 * This function will return the bits used in the last Diffie-Hellman
247 * key exchange with the peer. Should be used for both anonymous and
248 * ephemeral Diffie-Hellman.
250 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
251 * an error code is returned.
254 gnutls_dh_get_secret_bits (gnutls_session_t session)
256 switch (gnutls_auth_get_type (session))
258 case GNUTLS_CRD_ANON:
260 anon_auth_info_t info;
262 info = _gnutls_get_auth_info (session);
263 if (info == NULL)
264 return GNUTLS_E_INTERNAL_ERROR;
265 return info->dh.secret_bits;
267 case GNUTLS_CRD_PSK:
269 psk_auth_info_t info;
271 info = _gnutls_get_auth_info (session);
272 if (info == NULL)
273 return GNUTLS_E_INTERNAL_ERROR;
274 return info->dh.secret_bits;
276 case GNUTLS_CRD_CERTIFICATE:
278 cert_auth_info_t info;
280 info = _gnutls_get_auth_info (session);
281 if (info == NULL)
282 return GNUTLS_E_INTERNAL_ERROR;
284 return info->dh.secret_bits;
286 default:
287 gnutls_assert ();
288 return GNUTLS_E_INVALID_REQUEST;
292 static int
293 mpi_buf2bits (gnutls_datum_t * mpi_buf)
295 bigint_t mpi;
296 int rc;
298 rc = _gnutls_mpi_scan_nz (&mpi, mpi_buf->data, mpi_buf->size);
299 if (rc)
301 gnutls_assert ();
302 return rc;
305 rc = _gnutls_mpi_get_nbits (mpi);
306 _gnutls_mpi_release (&mpi);
308 return rc;
312 * gnutls_dh_get_prime_bits:
313 * @session: is a gnutls session
315 * This function will return the bits of the prime used in the last
316 * Diffie-Hellman key exchange with the peer. Should be used for both
317 * anonymous and ephemeral Diffie-Hellman. Note that some ciphers,
318 * like RSA and DSA without DHE, does not use a Diffie-Hellman key
319 * exchange, and then this function will return 0.
321 * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
322 * Diffie-Hellman key exchange was done, or a negative error code on
323 * failure.
326 gnutls_dh_get_prime_bits (gnutls_session_t session)
328 dh_info_st *dh;
330 switch (gnutls_auth_get_type (session))
332 case GNUTLS_CRD_ANON:
334 anon_auth_info_t info;
336 info = _gnutls_get_auth_info (session);
337 if (info == NULL)
338 return GNUTLS_E_INTERNAL_ERROR;
339 dh = &info->dh;
340 break;
342 case GNUTLS_CRD_PSK:
344 psk_auth_info_t info;
346 info = _gnutls_get_auth_info (session);
347 if (info == NULL)
348 return GNUTLS_E_INTERNAL_ERROR;
349 dh = &info->dh;
350 break;
352 case GNUTLS_CRD_CERTIFICATE:
354 cert_auth_info_t info;
356 info = _gnutls_get_auth_info (session);
357 if (info == NULL)
358 return GNUTLS_E_INTERNAL_ERROR;
360 dh = &info->dh;
361 break;
363 default:
364 gnutls_assert ();
365 return GNUTLS_E_INVALID_REQUEST;
368 return mpi_buf2bits (&dh->prime);
372 * gnutls_rsa_export_get_modulus_bits:
373 * @session: is a gnutls session
375 * Get the export RSA parameter's modulus size.
377 * Returns: the bits used in the last RSA-EXPORT key exchange with the
378 * peer, or a negative value in case of error.
381 gnutls_rsa_export_get_modulus_bits (gnutls_session_t session)
383 cert_auth_info_t info;
385 info = _gnutls_get_auth_info (session);
386 if (info == NULL)
387 return GNUTLS_E_INTERNAL_ERROR;
389 return mpi_buf2bits (&info->rsa_export.modulus);
393 * gnutls_dh_get_peers_public_bits:
394 * @session: is a gnutls session
396 * Get the Diffie-Hellman public key bit size. Can be used for both
397 * anonymous and ephemeral Diffie-Hellman.
399 * Returns: the public key bit size used in the last Diffie-Hellman
400 * key exchange with the peer, or a negative value in case of error.
403 gnutls_dh_get_peers_public_bits (gnutls_session_t session)
405 dh_info_st *dh;
407 switch (gnutls_auth_get_type (session))
409 case GNUTLS_CRD_ANON:
411 anon_auth_info_t info;
413 info = _gnutls_get_auth_info (session);
414 if (info == NULL)
415 return GNUTLS_E_INTERNAL_ERROR;
417 dh = &info->dh;
418 break;
420 case GNUTLS_CRD_PSK:
422 psk_auth_info_t info;
424 info = _gnutls_get_auth_info (session);
425 if (info == NULL)
426 return GNUTLS_E_INTERNAL_ERROR;
428 dh = &info->dh;
429 break;
431 case GNUTLS_CRD_CERTIFICATE:
433 cert_auth_info_t info;
435 info = _gnutls_get_auth_info (session);
436 if (info == NULL)
437 return GNUTLS_E_INTERNAL_ERROR;
439 dh = &info->dh;
440 break;
442 default:
443 gnutls_assert ();
444 return GNUTLS_E_INVALID_REQUEST;
447 return mpi_buf2bits (&dh->public_key);
450 /* CERTIFICATE STUFF */
453 * gnutls_certificate_get_ours:
454 * @session: is a gnutls session
456 * Get the certificate as sent to the peer, in the last handshake.
457 * These certificates are in raw format. In X.509 this is a
458 * certificate list. In OpenPGP this is a single certificate.
460 * Returns: return a pointer to a #gnutls_datum_t containing our
461 * certificates, or %NULL in case of an error or if no certificate
462 * was used.
464 const gnutls_datum_t *
465 gnutls_certificate_get_ours (gnutls_session_t session)
467 gnutls_certificate_credentials_t cred;
469 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
471 cred = (gnutls_certificate_credentials_t)
472 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
473 if (cred == NULL || cred->cert_list == NULL)
475 gnutls_assert ();
476 return NULL;
479 if (session->internals.selected_cert_list == NULL)
480 return NULL;
482 return &session->internals.selected_cert_list[0].raw;
486 * gnutls_certificate_get_peers:
487 * @session: is a gnutls session
488 * @list_size: is the length of the certificate list
490 * Get the peer's raw certificate (chain) as sent by the peer. These
491 * certificates are in raw format (DER encoded for X.509). In case of
492 * a X.509 then a certificate list may be present. The first
493 * certificate in the list is the peer's certificate, following the
494 * issuer's certificate, then the issuer's issuer etc.
496 * In case of OpenPGP keys a single key will be returned in raw
497 * format.
499 * Returns: return a pointer to a #gnutls_datum_t containing our
500 * certificates, or %NULL in case of an error or if no certificate
501 * was used.
503 const gnutls_datum_t *
504 gnutls_certificate_get_peers (gnutls_session_t
505 session, unsigned int *list_size)
507 cert_auth_info_t info;
509 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
511 info = _gnutls_get_auth_info (session);
512 if (info == NULL)
513 return NULL;
515 *list_size = info->ncerts;
516 return info->raw_certificate_list;
521 * gnutls_certificate_client_get_request_status:
522 * @session: is a gnutls session
524 * Get whether client certificate is requested or not.
526 * Returns: 0 if the peer (server) did not request client
527 * authentication or 1 otherwise, or a negative value in case of
528 * error.
531 gnutls_certificate_client_get_request_status (gnutls_session_t session)
533 return session->key->certificate_requested;
537 * gnutls_fingerprint:
538 * @algo: is a digest algorithm
539 * @data: is the data
540 * @result: is the place where the result will be copied (may be null).
541 * @result_size: should hold the size of the result. The actual size
542 * of the returned result will also be copied there.
544 * This function will calculate a fingerprint (actually a hash), of
545 * the given data. The result is not printable data. You should
546 * convert it to hex, or to something else printable.
548 * This is the usual way to calculate a fingerprint of an X.509 DER
549 * encoded certificate. Note however that the fingerprint of an
550 * OpenPGP is not just a hash and cannot be calculated with this
551 * function.
553 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
554 * an error code is returned.
557 gnutls_fingerprint (gnutls_digest_algorithm_t algo,
558 const gnutls_datum_t * data, void *result,
559 size_t * result_size)
561 digest_hd_st td;
562 int hash_len = _gnutls_hash_get_algo_len (HASH2MAC (algo));
564 if (hash_len < 0 || (unsigned) hash_len > *result_size || result == NULL)
566 *result_size = hash_len;
567 return GNUTLS_E_SHORT_MEMORY_BUFFER;
569 *result_size = hash_len;
571 if (result)
573 int ret = _gnutls_hash_init (&td, HASH2MAC (algo));
574 if (ret < 0)
576 gnutls_assert ();
577 return ret;
580 _gnutls_hash (&td, data->data, data->size);
582 _gnutls_hash_deinit (&td, result);
585 return 0;
590 * gnutls_certificate_set_dh_params:
591 * @res: is a gnutls_certificate_credentials_t structure
592 * @dh_params: is a structure that holds Diffie-Hellman parameters.
594 * This function will set the Diffie-Hellman parameters for a
595 * certificate server to use. These parameters will be used in
596 * Ephemeral Diffie-Hellman cipher suites. Note that only a pointer
597 * to the parameters are stored in the certificate handle, so if you
598 * deallocate the parameters before the certificate is deallocated,
599 * you must change the parameters stored in the certificate first.
602 void
603 gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res,
604 gnutls_dh_params_t dh_params)
606 res->dh_params = dh_params;
610 * gnutls_certificate_set_params_function:
611 * @res: is a gnutls_certificate_credentials_t structure
612 * @func: is the function to be called
614 * This function will set a callback in order for the server to get
615 * the Diffie-Hellman or RSA parameters for certificate
616 * authentication. The callback should return zero on success.
618 void
619 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res,
620 gnutls_params_function * func)
622 res->params_func = func;
627 * gnutls_certificate_set_verify_flags:
628 * @res: is a gnutls_certificate_credentials_t structure
629 * @flags: are the flags
631 * This function will set the flags to be used at verification of the
632 * certificates. Flags must be OR of the
633 * #gnutls_certificate_verify_flags enumerations.
636 void
637 gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
638 res, unsigned int flags)
640 res->verify_flags = flags;
644 * gnutls_certificate_set_verify_limits:
645 * @res: is a gnutls_certificate_credentials structure
646 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
647 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
649 * This function will set some upper limits for the default
650 * verification function, gnutls_certificate_verify_peers2(), to avoid
651 * denial of service attacks. You can set them to zero to disable
652 * limits.
654 void
655 gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res,
656 unsigned int max_bits,
657 unsigned int max_depth)
659 res->verify_depth = max_depth;
660 res->verify_bits = max_bits;
664 * gnutls_certificate_set_rsa_export_params:
665 * @res: is a gnutls_certificate_credentials_t structure
666 * @rsa_params: is a structure that holds temporary RSA parameters.
668 * This function will set the temporary RSA parameters for a
669 * certificate server to use. These parameters will be used in
670 * RSA-EXPORT cipher suites.
672 void
673 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
674 res, gnutls_rsa_params_t rsa_params)
676 res->rsa_params = rsa_params;
680 * gnutls_psk_set_params_function:
681 * @res: is a gnutls_psk_server_credentials_t structure
682 * @func: is the function to be called
684 * This function will set a callback in order for the server to get
685 * the Diffie-Hellman or RSA parameters for PSK authentication. The
686 * callback should return zero on success.
688 void
689 gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res,
690 gnutls_params_function * func)
692 res->params_func = func;
696 * gnutls_anon_set_params_function:
697 * @res: is a gnutls_anon_server_credentials_t structure
698 * @func: is the function to be called
700 * This function will set a callback in order for the server to get
701 * the Diffie-Hellman or RSA parameters for anonymous authentication.
702 * The callback should return zero on success.
704 void
705 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
706 gnutls_params_function * func)
708 res->params_func = func;