2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains certificate authentication functions to be exported in the
24 * API which did not fit elsewhere.
27 #include <gnutls_int.h>
29 #include <auth/anon.h>
30 #include <auth/cert.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_auth.h>
34 #include <gnutls_state.h>
35 #include <gnutls_datum.h>
36 #include <extras/randomart.h>
37 #include <read-file.h>
41 * @type: The type of the random art
42 * @key_type: The type of the key (RSA, DSA etc.)
43 * @key_size: The size of the key in bits
44 * @fpr: The fingerprint of the key
45 * @fpr_size: The size of the fingerprint
46 * @art: The returned random art
48 * This function will convert a given fingerprint to an "artistic"
49 * image. The returned image is allocated using gnutls_malloc()
51 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
52 * an error code is returned.
55 int gnutls_random_art (gnutls_random_art_t type
,
56 const char* key_type
, unsigned int key_size
,
57 void * fpr
, size_t fpr_size
,
60 if (type
!= GNUTLS_RANDOM_ART_OPENSSH
)
61 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
63 art
->data
= (void*)_gnutls_key_fingerprint_randomart(fpr
, fpr_size
, key_type
, key_size
, NULL
);
64 if (art
->data
== NULL
)
65 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
67 art
->size
= strlen((char*)art
->data
);
75 * gnutls_dh_set_prime_bits:
76 * @session: is a #gnutls_session_t structure.
77 * @bits: is the number of bits
79 * This function sets the number of bits, for use in a Diffie-Hellman
80 * key exchange. This is used both in DH ephemeral and DH anonymous
81 * cipher suites. This will set the minimum size of the prime that
82 * will be used for the handshake.
84 * In the client side it sets the minimum accepted number of bits. If
85 * a server sends a prime with less bits than that
86 * %GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the handshake.
88 * Note that values lower than 512 bits may allow decryption of the
91 * This function has no effect in server side.
95 gnutls_dh_set_prime_bits (gnutls_session_t session
, unsigned int bits
)
97 if (bits
<= 512) _gnutls_audit_log(session
, "Note that the security level of the Diffie-Hellman key exchange has been lowered to %u bits and this may allow decryption of the session data\n", bits
);
98 session
->internals
.dh_prime_bits
= bits
;
103 * gnutls_dh_get_group:
104 * @session: is a gnutls session
105 * @raw_gen: will hold the generator.
106 * @raw_prime: will hold the prime.
108 * This function will return the group parameters used in the last
109 * Diffie-Hellman key exchange with the peer. These are the prime and
110 * the generator used. This function should be used for both
111 * anonymous and ephemeral Diffie-Hellman. The output parameters must
112 * be freed with gnutls_free().
114 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
115 * an error code is returned.
118 gnutls_dh_get_group (gnutls_session_t session
,
119 gnutls_datum_t
* raw_gen
, gnutls_datum_t
* raw_prime
)
123 anon_auth_info_t anon_info
;
124 cert_auth_info_t cert_info
;
125 psk_auth_info_t psk_info
;
127 switch (gnutls_auth_get_type (session
))
129 case GNUTLS_CRD_ANON
:
130 anon_info
= _gnutls_get_auth_info (session
);
131 if (anon_info
== NULL
)
132 return GNUTLS_E_INTERNAL_ERROR
;
136 psk_info
= _gnutls_get_auth_info (session
);
137 if (psk_info
== NULL
)
138 return GNUTLS_E_INTERNAL_ERROR
;
141 case GNUTLS_CRD_CERTIFICATE
:
142 cert_info
= _gnutls_get_auth_info (session
);
143 if (cert_info
== NULL
)
144 return GNUTLS_E_INTERNAL_ERROR
;
149 return GNUTLS_E_INVALID_REQUEST
;
152 ret
= _gnutls_set_datum (raw_prime
, dh
->prime
.data
, dh
->prime
.size
);
159 ret
= _gnutls_set_datum (raw_gen
, dh
->generator
.data
, dh
->generator
.size
);
163 _gnutls_free_datum (raw_prime
);
171 * gnutls_dh_get_pubkey:
172 * @session: is a gnutls session
173 * @raw_key: will hold the public key.
175 * This function will return the peer's public key used in the last
176 * Diffie-Hellman key exchange. This function should be used for both
177 * anonymous and ephemeral Diffie-Hellman. The output parameters must
178 * be freed with gnutls_free().
180 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
181 * an error code is returned.
184 gnutls_dh_get_pubkey (gnutls_session_t session
, gnutls_datum_t
* raw_key
)
187 anon_auth_info_t anon_info
;
188 cert_auth_info_t cert_info
;
189 cert_auth_info_t psk_info
;
191 switch (gnutls_auth_get_type (session
))
193 case GNUTLS_CRD_ANON
:
195 anon_info
= _gnutls_get_auth_info (session
);
196 if (anon_info
== NULL
)
197 return GNUTLS_E_INTERNAL_ERROR
;
203 psk_info
= _gnutls_get_auth_info (session
);
204 if (psk_info
== NULL
)
205 return GNUTLS_E_INTERNAL_ERROR
;
209 case GNUTLS_CRD_CERTIFICATE
:
212 cert_info
= _gnutls_get_auth_info (session
);
213 if (cert_info
== NULL
)
214 return GNUTLS_E_INTERNAL_ERROR
;
220 return GNUTLS_E_INVALID_REQUEST
;
223 return _gnutls_set_datum (raw_key
, dh
->public_key
.data
,
224 dh
->public_key
.size
);
228 * gnutls_rsa_export_get_pubkey:
229 * @session: is a gnutls session
230 * @exponent: will hold the exponent.
231 * @modulus: will hold the modulus.
233 * This function will return the peer's public key exponent and
234 * modulus used in the last RSA-EXPORT authentication. The output
235 * parameters must be freed with gnutls_free().
237 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
238 * an error code is returned.
241 gnutls_rsa_export_get_pubkey (gnutls_session_t session
,
242 gnutls_datum_t
* exponent
,
243 gnutls_datum_t
* modulus
)
245 cert_auth_info_t info
;
248 if (gnutls_auth_get_type (session
) == GNUTLS_CRD_CERTIFICATE
)
250 info
= _gnutls_get_auth_info (session
);
252 return GNUTLS_E_INTERNAL_ERROR
;
254 ret
= _gnutls_set_datum (modulus
, info
->rsa_export
.modulus
.data
,
255 info
->rsa_export
.modulus
.size
);
262 ret
= _gnutls_set_datum (exponent
, info
->rsa_export
.exponent
.data
,
263 info
->rsa_export
.exponent
.size
);
267 _gnutls_free_datum (modulus
);
274 return GNUTLS_E_INVALID_REQUEST
;
279 * gnutls_dh_get_secret_bits:
280 * @session: is a gnutls session
282 * This function will return the bits used in the last Diffie-Hellman
283 * key exchange with the peer. Should be used for both anonymous and
284 * ephemeral Diffie-Hellman.
286 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
287 * an error code is returned.
290 gnutls_dh_get_secret_bits (gnutls_session_t session
)
292 switch (gnutls_auth_get_type (session
))
294 case GNUTLS_CRD_ANON
:
296 anon_auth_info_t info
;
298 info
= _gnutls_get_auth_info (session
);
300 return GNUTLS_E_INTERNAL_ERROR
;
301 return info
->dh
.secret_bits
;
305 psk_auth_info_t info
;
307 info
= _gnutls_get_auth_info (session
);
309 return GNUTLS_E_INTERNAL_ERROR
;
310 return info
->dh
.secret_bits
;
312 case GNUTLS_CRD_CERTIFICATE
:
314 cert_auth_info_t info
;
316 info
= _gnutls_get_auth_info (session
);
318 return GNUTLS_E_INTERNAL_ERROR
;
320 return info
->dh
.secret_bits
;
324 return GNUTLS_E_INVALID_REQUEST
;
329 mpi_buf2bits (gnutls_datum_t
* mpi_buf
)
334 rc
= _gnutls_mpi_scan_nz (&mpi
, mpi_buf
->data
, mpi_buf
->size
);
341 rc
= _gnutls_mpi_get_nbits (mpi
);
342 _gnutls_mpi_release (&mpi
);
348 * gnutls_dh_get_prime_bits:
349 * @session: is a gnutls session
351 * This function will return the bits of the prime used in the last
352 * Diffie-Hellman key exchange with the peer. Should be used for both
353 * anonymous and ephemeral Diffie-Hellman. Note that some ciphers,
354 * like RSA and DSA without DHE, do not use a Diffie-Hellman key
355 * exchange, and then this function will return 0.
357 * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
358 * Diffie-Hellman key exchange was done, or a negative error code on
362 gnutls_dh_get_prime_bits (gnutls_session_t session
)
366 switch (gnutls_auth_get_type (session
))
368 case GNUTLS_CRD_ANON
:
370 anon_auth_info_t info
;
372 info
= _gnutls_get_auth_info (session
);
374 return GNUTLS_E_INTERNAL_ERROR
;
380 psk_auth_info_t info
;
382 info
= _gnutls_get_auth_info (session
);
384 return GNUTLS_E_INTERNAL_ERROR
;
388 case GNUTLS_CRD_CERTIFICATE
:
390 cert_auth_info_t info
;
392 info
= _gnutls_get_auth_info (session
);
394 return GNUTLS_E_INTERNAL_ERROR
;
401 return GNUTLS_E_INVALID_REQUEST
;
404 return mpi_buf2bits (&dh
->prime
);
408 * gnutls_rsa_export_get_modulus_bits:
409 * @session: is a gnutls session
411 * Get the export RSA parameter's modulus size.
413 * Returns: The bits used in the last RSA-EXPORT key exchange with the
414 * peer, or a negative error code in case of error.
417 gnutls_rsa_export_get_modulus_bits (gnutls_session_t session
)
419 cert_auth_info_t info
;
421 info
= _gnutls_get_auth_info (session
);
423 return GNUTLS_E_INTERNAL_ERROR
;
425 return mpi_buf2bits (&info
->rsa_export
.modulus
);
429 * gnutls_dh_get_peers_public_bits:
430 * @session: is a gnutls session
432 * Get the Diffie-Hellman public key bit size. Can be used for both
433 * anonymous and ephemeral Diffie-Hellman.
435 * Returns: The public key bit size used in the last Diffie-Hellman
436 * key exchange with the peer, or a negative error code in case of error.
439 gnutls_dh_get_peers_public_bits (gnutls_session_t session
)
443 switch (gnutls_auth_get_type (session
))
445 case GNUTLS_CRD_ANON
:
447 anon_auth_info_t info
;
449 info
= _gnutls_get_auth_info (session
);
451 return GNUTLS_E_INTERNAL_ERROR
;
458 psk_auth_info_t info
;
460 info
= _gnutls_get_auth_info (session
);
462 return GNUTLS_E_INTERNAL_ERROR
;
467 case GNUTLS_CRD_CERTIFICATE
:
469 cert_auth_info_t info
;
471 info
= _gnutls_get_auth_info (session
);
473 return GNUTLS_E_INTERNAL_ERROR
;
480 return GNUTLS_E_INVALID_REQUEST
;
483 return mpi_buf2bits (&dh
->public_key
);
486 /* CERTIFICATE STUFF */
489 * gnutls_certificate_get_ours:
490 * @session: is a gnutls session
492 * Gets the certificate as sent to the peer in the last handshake.
493 * The certificate is in raw (DER) format. No certificate
494 * list is being returned. Only the first certificate.
496 * Returns: a pointer to a #gnutls_datum_t containing our
497 * certificate, or %NULL in case of an error or if no certificate
500 const gnutls_datum_t
*
501 gnutls_certificate_get_ours (gnutls_session_t session
)
503 gnutls_certificate_credentials_t cred
;
505 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
507 cred
= (gnutls_certificate_credentials_t
)
508 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
509 if (cred
== NULL
|| cred
->certs
== NULL
)
515 if (session
->internals
.selected_cert_list
== NULL
)
518 return &session
->internals
.selected_cert_list
[0].cert
;
522 * gnutls_certificate_get_peers:
523 * @session: is a gnutls session
524 * @list_size: is the length of the certificate list
526 * Get the peer's raw certificate (chain) as sent by the peer. These
527 * certificates are in raw format (DER encoded for X.509). In case of
528 * a X.509 then a certificate list may be present. The first
529 * certificate in the list is the peer's certificate, following the
530 * issuer's certificate, then the issuer's issuer etc.
532 * In case of OpenPGP keys a single key will be returned in raw
535 * Returns: a pointer to a #gnutls_datum_t containing our
536 * certificates, or %NULL in case of an error or if no certificate
539 const gnutls_datum_t
*
540 gnutls_certificate_get_peers (gnutls_session_t
541 session
, unsigned int *list_size
)
543 cert_auth_info_t info
;
545 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
547 info
= _gnutls_get_auth_info (session
);
551 *list_size
= info
->ncerts
;
552 return info
->raw_certificate_list
;
557 * gnutls_certificate_client_get_request_status:
558 * @session: is a gnutls session
560 * Get whether client certificate is requested or not.
562 * Returns: 0 if the peer (server) did not request client
563 * authentication or 1 otherwise, or a negative error code in case of
567 gnutls_certificate_client_get_request_status (gnutls_session_t session
)
569 return session
->key
->crt_requested
;
573 * gnutls_fingerprint:
574 * @algo: is a digest algorithm
576 * @result: is the place where the result will be copied (may be null).
577 * @result_size: should hold the size of the result. The actual size
578 * of the returned result will also be copied there.
580 * This function will calculate a fingerprint (actually a hash), of
581 * the given data. The result is not printable data. You should
582 * convert it to hex, or to something else printable.
584 * This is the usual way to calculate a fingerprint of an X.509 DER
585 * encoded certificate. Note however that the fingerprint of an
586 * OpenPGP is not just a hash and cannot be calculated with this
589 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
590 * an error code is returned.
593 gnutls_fingerprint (gnutls_digest_algorithm_t algo
,
594 const gnutls_datum_t
* data
, void *result
,
595 size_t * result_size
)
598 int hash_len
= _gnutls_hash_get_algo_len (algo
);
600 if (hash_len
< 0 || (unsigned) hash_len
> *result_size
|| result
== NULL
)
602 *result_size
= hash_len
;
603 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
605 *result_size
= hash_len
;
609 ret
= _gnutls_hash_fast( algo
, data
->data
, data
->size
, result
);
611 return gnutls_assert_val(ret
);
619 * gnutls_certificate_set_dh_params:
620 * @res: is a gnutls_certificate_credentials_t structure
621 * @dh_params: is a structure that holds Diffie-Hellman parameters.
623 * This function will set the Diffie-Hellman parameters for a
624 * certificate server to use. These parameters will be used in
625 * Ephemeral Diffie-Hellman cipher suites. Note that only a pointer
626 * to the parameters are stored in the certificate handle, so if you
627 * deallocate the parameters before the certificate is deallocated,
628 * you must change the parameters stored in the certificate first.
632 gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res
,
633 gnutls_dh_params_t dh_params
)
635 res
->dh_params
= dh_params
;
639 * gnutls_certificate_set_params_function:
640 * @res: is a gnutls_certificate_credentials_t structure
641 * @func: is the function to be called
643 * This function will set a callback in order for the server to get
644 * the Diffie-Hellman or RSA parameters for certificate
645 * authentication. The callback should return %GNUTLS_E_SUCCESS (0) on success.
648 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res
,
649 gnutls_params_function
* func
)
651 res
->params_func
= func
;
656 * gnutls_certificate_set_verify_flags:
657 * @res: is a gnutls_certificate_credentials_t structure
658 * @flags: are the flags
660 * This function will set the flags to be used at verification of the
661 * certificates. Flags must be OR of the
662 * #gnutls_certificate_verify_flags enumerations. The default
663 * for TLS sessions is GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN.
667 gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
668 res
, unsigned int flags
)
670 res
->verify_flags
= flags
;
674 * gnutls_certificate_set_verify_limits:
675 * @res: is a gnutls_certificate_credentials structure
676 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
677 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
679 * This function will set some upper limits for the default
680 * verification function, gnutls_certificate_verify_peers2(), to avoid
681 * denial of service attacks. You can set them to zero to disable
685 gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res
,
686 unsigned int max_bits
,
687 unsigned int max_depth
)
689 res
->verify_depth
= max_depth
;
690 res
->verify_bits
= max_bits
;
694 * gnutls_certificate_set_rsa_export_params:
695 * @res: is a gnutls_certificate_credentials_t structure
696 * @rsa_params: is a structure that holds temporary RSA parameters.
698 * This function will set the temporary RSA parameters for a
699 * certificate server to use. These parameters will be used in
700 * RSA-EXPORT cipher suites.
703 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
704 res
, gnutls_rsa_params_t rsa_params
)
706 res
->rsa_params
= rsa_params
;
710 * gnutls_psk_set_params_function:
711 * @res: is a gnutls_psk_server_credentials_t structure
712 * @func: is the function to be called
714 * This function will set a callback in order for the server to get
715 * the Diffie-Hellman or RSA parameters for PSK authentication. The
716 * callback should return %GNUTLS_E_SUCCESS (0) on success.
719 gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res
,
720 gnutls_params_function
* func
)
722 res
->params_func
= func
;
726 * gnutls_anon_set_params_function:
727 * @res: is a gnutls_anon_server_credentials_t structure
728 * @func: is the function to be called
730 * This function will set a callback in order for the server to get
731 * the Diffie-Hellman or RSA parameters for anonymous authentication.
732 * The callback should return %GNUTLS_E_SUCCESS (0) on success.
735 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res
,
736 gnutls_params_function
* func
)
738 res
->params_func
= func
;
743 * @filename: the name of the file to load
744 * @data: Where the file will be stored
746 * This function will load a file into a datum. The data are
747 * zero terminated but the terminating null is not included in length.
748 * The returned data are allocated using gnutls_malloc().
750 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
751 * an error code is returned.
755 int gnutls_load_file(const char* filename
, gnutls_datum_t
* data
)
759 data
->data
= (void*)read_binary_file(filename
, &len
);
760 if (data
->data
== NULL
)
761 return GNUTLS_E_FILE_ERROR
;
763 if (malloc
!= gnutls_malloc
)
765 void* tmp
= gnutls_malloc(len
);
767 memcpy(tmp
, data
->data
, len
);
778 * gnutls_url_is_supported:
779 * @url: A PKCS 11 url
781 * Check whether url is supported. Depending on the system libraries
782 * GnuTLS may support pkcs11 or tpmkey URLs.
784 * Returns: return non-zero if the given URL is supported, and zero if
790 gnutls_url_is_supported (const char* url
)
793 if (strstr(url
, "pkcs11:") != NULL
)
797 if (strstr(url
, "tpmkey:") != NULL
)