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>
40 * @type: The type of the random art
41 * @key_type: The type of the key (RSA, DSA etc.)
42 * @key_size: The size of the key in bits
43 * @fpr: The fingerprint of the key
44 * @fpr_size: The size of the fingerprint
45 * @art: The returned random art
47 * This function will convert a given fingerprint to an "artistic"
48 * image. The returned image is allocated using gnutls_malloc()
50 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
51 * an error code is returned.
54 int gnutls_random_art (gnutls_random_art_t type
,
55 const char* key_type
, unsigned int key_size
,
56 void * fpr
, size_t fpr_size
,
59 if (type
!= GNUTLS_RANDOM_ART_OPENSSH
)
60 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST
);
62 art
->data
= (void*)_gnutls_key_fingerprint_randomart(fpr
, fpr_size
, key_type
, key_size
, NULL
);
63 if (art
->data
== NULL
)
64 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
66 art
->size
= strlen((char*)art
->data
);
74 * gnutls_dh_set_prime_bits:
75 * @session: is a #gnutls_session_t structure.
76 * @bits: is the number of bits
78 * This function sets the number of bits, for use in a Diffie-Hellman
79 * key exchange. This is used both in DH ephemeral and DH anonymous
80 * cipher suites. This will set the minimum size of the prime that
81 * will be used for the handshake.
83 * In the client side it sets the minimum accepted number of bits. If
84 * a server sends a prime with less bits than that
85 * %GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the handshake.
87 * This function has no effect in server side.
91 gnutls_dh_set_prime_bits (gnutls_session_t session
, unsigned int bits
)
93 session
->internals
.dh_prime_bits
= bits
;
98 * gnutls_dh_get_group:
99 * @session: is a gnutls session
100 * @raw_gen: will hold the generator.
101 * @raw_prime: will hold the prime.
103 * This function will return the group parameters used in the last
104 * Diffie-Hellman key exchange with the peer. These are the prime and
105 * the generator used. This function should be used for both
106 * anonymous and ephemeral Diffie-Hellman. The output parameters must
107 * be freed with gnutls_free().
109 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
110 * an error code is returned.
113 gnutls_dh_get_group (gnutls_session_t session
,
114 gnutls_datum_t
* raw_gen
, gnutls_datum_t
* raw_prime
)
118 anon_auth_info_t anon_info
;
119 cert_auth_info_t cert_info
;
120 psk_auth_info_t psk_info
;
122 switch (gnutls_auth_get_type (session
))
124 case GNUTLS_CRD_ANON
:
125 anon_info
= _gnutls_get_auth_info (session
);
126 if (anon_info
== NULL
)
127 return GNUTLS_E_INTERNAL_ERROR
;
131 psk_info
= _gnutls_get_auth_info (session
);
132 if (psk_info
== NULL
)
133 return GNUTLS_E_INTERNAL_ERROR
;
136 case GNUTLS_CRD_CERTIFICATE
:
137 cert_info
= _gnutls_get_auth_info (session
);
138 if (cert_info
== NULL
)
139 return GNUTLS_E_INTERNAL_ERROR
;
144 return GNUTLS_E_INVALID_REQUEST
;
147 ret
= _gnutls_set_datum (raw_prime
, dh
->prime
.data
, dh
->prime
.size
);
154 ret
= _gnutls_set_datum (raw_gen
, dh
->generator
.data
, dh
->generator
.size
);
158 _gnutls_free_datum (raw_prime
);
166 * gnutls_dh_get_pubkey:
167 * @session: is a gnutls session
168 * @raw_key: will hold the public key.
170 * This function will return the peer's public key used in the last
171 * Diffie-Hellman key exchange. This function should be used for both
172 * anonymous and ephemeral Diffie-Hellman. The output parameters must
173 * be freed with gnutls_free().
175 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
176 * an error code is returned.
179 gnutls_dh_get_pubkey (gnutls_session_t session
, gnutls_datum_t
* raw_key
)
182 anon_auth_info_t anon_info
;
183 cert_auth_info_t cert_info
;
184 cert_auth_info_t psk_info
;
186 switch (gnutls_auth_get_type (session
))
188 case GNUTLS_CRD_ANON
:
190 anon_info
= _gnutls_get_auth_info (session
);
191 if (anon_info
== NULL
)
192 return GNUTLS_E_INTERNAL_ERROR
;
198 psk_info
= _gnutls_get_auth_info (session
);
199 if (psk_info
== NULL
)
200 return GNUTLS_E_INTERNAL_ERROR
;
204 case GNUTLS_CRD_CERTIFICATE
:
207 cert_info
= _gnutls_get_auth_info (session
);
208 if (cert_info
== NULL
)
209 return GNUTLS_E_INTERNAL_ERROR
;
215 return GNUTLS_E_INVALID_REQUEST
;
218 return _gnutls_set_datum (raw_key
, dh
->public_key
.data
,
219 dh
->public_key
.size
);
223 * gnutls_rsa_export_get_pubkey:
224 * @session: is a gnutls session
225 * @exponent: will hold the exponent.
226 * @modulus: will hold the modulus.
228 * This function will return the peer's public key exponent and
229 * modulus used in the last RSA-EXPORT authentication. The output
230 * parameters must be freed with gnutls_free().
232 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
233 * an error code is returned.
236 gnutls_rsa_export_get_pubkey (gnutls_session_t session
,
237 gnutls_datum_t
* exponent
,
238 gnutls_datum_t
* modulus
)
240 cert_auth_info_t info
;
243 if (gnutls_auth_get_type (session
) == GNUTLS_CRD_CERTIFICATE
)
245 info
= _gnutls_get_auth_info (session
);
247 return GNUTLS_E_INTERNAL_ERROR
;
249 ret
= _gnutls_set_datum (modulus
, info
->rsa_export
.modulus
.data
,
250 info
->rsa_export
.modulus
.size
);
257 ret
= _gnutls_set_datum (exponent
, info
->rsa_export
.exponent
.data
,
258 info
->rsa_export
.exponent
.size
);
262 _gnutls_free_datum (modulus
);
269 return GNUTLS_E_INVALID_REQUEST
;
274 * gnutls_dh_get_secret_bits:
275 * @session: is a gnutls session
277 * This function will return the bits used in the last Diffie-Hellman
278 * key exchange with the peer. Should be used for both anonymous and
279 * ephemeral Diffie-Hellman.
281 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
282 * an error code is returned.
285 gnutls_dh_get_secret_bits (gnutls_session_t session
)
287 switch (gnutls_auth_get_type (session
))
289 case GNUTLS_CRD_ANON
:
291 anon_auth_info_t info
;
293 info
= _gnutls_get_auth_info (session
);
295 return GNUTLS_E_INTERNAL_ERROR
;
296 return info
->dh
.secret_bits
;
300 psk_auth_info_t info
;
302 info
= _gnutls_get_auth_info (session
);
304 return GNUTLS_E_INTERNAL_ERROR
;
305 return info
->dh
.secret_bits
;
307 case GNUTLS_CRD_CERTIFICATE
:
309 cert_auth_info_t info
;
311 info
= _gnutls_get_auth_info (session
);
313 return GNUTLS_E_INTERNAL_ERROR
;
315 return info
->dh
.secret_bits
;
319 return GNUTLS_E_INVALID_REQUEST
;
324 mpi_buf2bits (gnutls_datum_t
* mpi_buf
)
329 rc
= _gnutls_mpi_scan_nz (&mpi
, mpi_buf
->data
, mpi_buf
->size
);
336 rc
= _gnutls_mpi_get_nbits (mpi
);
337 _gnutls_mpi_release (&mpi
);
343 * gnutls_dh_get_prime_bits:
344 * @session: is a gnutls session
346 * This function will return the bits of the prime used in the last
347 * Diffie-Hellman key exchange with the peer. Should be used for both
348 * anonymous and ephemeral Diffie-Hellman. Note that some ciphers,
349 * like RSA and DSA without DHE, do not use a Diffie-Hellman key
350 * exchange, and then this function will return 0.
352 * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
353 * Diffie-Hellman key exchange was done, or a negative error code on
357 gnutls_dh_get_prime_bits (gnutls_session_t session
)
361 switch (gnutls_auth_get_type (session
))
363 case GNUTLS_CRD_ANON
:
365 anon_auth_info_t info
;
367 info
= _gnutls_get_auth_info (session
);
369 return GNUTLS_E_INTERNAL_ERROR
;
375 psk_auth_info_t info
;
377 info
= _gnutls_get_auth_info (session
);
379 return GNUTLS_E_INTERNAL_ERROR
;
383 case GNUTLS_CRD_CERTIFICATE
:
385 cert_auth_info_t info
;
387 info
= _gnutls_get_auth_info (session
);
389 return GNUTLS_E_INTERNAL_ERROR
;
396 return GNUTLS_E_INVALID_REQUEST
;
399 return mpi_buf2bits (&dh
->prime
);
403 * gnutls_rsa_export_get_modulus_bits:
404 * @session: is a gnutls session
406 * Get the export RSA parameter's modulus size.
408 * Returns: The bits used in the last RSA-EXPORT key exchange with the
409 * peer, or a negative error code in case of error.
412 gnutls_rsa_export_get_modulus_bits (gnutls_session_t session
)
414 cert_auth_info_t info
;
416 info
= _gnutls_get_auth_info (session
);
418 return GNUTLS_E_INTERNAL_ERROR
;
420 return mpi_buf2bits (&info
->rsa_export
.modulus
);
424 * gnutls_dh_get_peers_public_bits:
425 * @session: is a gnutls session
427 * Get the Diffie-Hellman public key bit size. Can be used for both
428 * anonymous and ephemeral Diffie-Hellman.
430 * Returns: The public key bit size used in the last Diffie-Hellman
431 * key exchange with the peer, or a negative error code in case of error.
434 gnutls_dh_get_peers_public_bits (gnutls_session_t session
)
438 switch (gnutls_auth_get_type (session
))
440 case GNUTLS_CRD_ANON
:
442 anon_auth_info_t info
;
444 info
= _gnutls_get_auth_info (session
);
446 return GNUTLS_E_INTERNAL_ERROR
;
453 psk_auth_info_t info
;
455 info
= _gnutls_get_auth_info (session
);
457 return GNUTLS_E_INTERNAL_ERROR
;
462 case GNUTLS_CRD_CERTIFICATE
:
464 cert_auth_info_t info
;
466 info
= _gnutls_get_auth_info (session
);
468 return GNUTLS_E_INTERNAL_ERROR
;
475 return GNUTLS_E_INVALID_REQUEST
;
478 return mpi_buf2bits (&dh
->public_key
);
481 /* CERTIFICATE STUFF */
484 * gnutls_certificate_get_ours:
485 * @session: is a gnutls session
487 * Gets the certificate as sent to the peer in the last handshake.
488 * The certificate is in raw (DER) format. No certificate
489 * list is being returned. Only the first certificate.
491 * Returns: a pointer to a #gnutls_datum_t containing our
492 * certificates, or %NULL in case of an error or if no certificate
495 const gnutls_datum_t
*
496 gnutls_certificate_get_ours (gnutls_session_t session
)
498 gnutls_certificate_credentials_t cred
;
500 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
502 cred
= (gnutls_certificate_credentials_t
)
503 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
504 if (cred
== NULL
|| cred
->certs
== NULL
)
510 if (session
->internals
.selected_cert_list
== NULL
)
513 return &session
->internals
.selected_cert_list
[0].cert
;
517 * gnutls_certificate_get_peers:
518 * @session: is a gnutls session
519 * @list_size: is the length of the certificate list
521 * Get the peer's raw certificate (chain) as sent by the peer. These
522 * certificates are in raw format (DER encoded for X.509). In case of
523 * a X.509 then a certificate list may be present. The first
524 * certificate in the list is the peer's certificate, following the
525 * issuer's certificate, then the issuer's issuer etc.
527 * In case of OpenPGP keys a single key will be returned in raw
530 * Returns: a pointer to a #gnutls_datum_t containing our
531 * certificates, or %NULL in case of an error or if no certificate
534 const gnutls_datum_t
*
535 gnutls_certificate_get_peers (gnutls_session_t
536 session
, unsigned int *list_size
)
538 cert_auth_info_t info
;
540 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
542 info
= _gnutls_get_auth_info (session
);
546 *list_size
= info
->ncerts
;
547 return info
->raw_certificate_list
;
552 * gnutls_certificate_client_get_request_status:
553 * @session: is a gnutls session
555 * Get whether client certificate is requested or not.
557 * Returns: 0 if the peer (server) did not request client
558 * authentication or 1 otherwise, or a negative error code in case of
562 gnutls_certificate_client_get_request_status (gnutls_session_t session
)
564 return session
->key
->certificate_requested
;
568 * gnutls_fingerprint:
569 * @algo: is a digest algorithm
571 * @result: is the place where the result will be copied (may be null).
572 * @result_size: should hold the size of the result. The actual size
573 * of the returned result will also be copied there.
575 * This function will calculate a fingerprint (actually a hash), of
576 * the given data. The result is not printable data. You should
577 * convert it to hex, or to something else printable.
579 * This is the usual way to calculate a fingerprint of an X.509 DER
580 * encoded certificate. Note however that the fingerprint of an
581 * OpenPGP is not just a hash and cannot be calculated with this
584 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
585 * an error code is returned.
588 gnutls_fingerprint (gnutls_digest_algorithm_t algo
,
589 const gnutls_datum_t
* data
, void *result
,
590 size_t * result_size
)
593 int hash_len
= _gnutls_hash_get_algo_len (algo
);
595 if (hash_len
< 0 || (unsigned) hash_len
> *result_size
|| result
== NULL
)
597 *result_size
= hash_len
;
598 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
600 *result_size
= hash_len
;
604 ret
= _gnutls_hash_fast( algo
, data
->data
, data
->size
, result
);
606 return gnutls_assert_val(ret
);
614 * gnutls_certificate_set_dh_params:
615 * @res: is a gnutls_certificate_credentials_t structure
616 * @dh_params: is a structure that holds Diffie-Hellman parameters.
618 * This function will set the Diffie-Hellman parameters for a
619 * certificate server to use. These parameters will be used in
620 * Ephemeral Diffie-Hellman cipher suites. Note that only a pointer
621 * to the parameters are stored in the certificate handle, so if you
622 * deallocate the parameters before the certificate is deallocated,
623 * you must change the parameters stored in the certificate first.
627 gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res
,
628 gnutls_dh_params_t dh_params
)
630 res
->dh_params
= dh_params
;
634 * gnutls_certificate_set_params_function:
635 * @res: is a gnutls_certificate_credentials_t structure
636 * @func: is the function to be called
638 * This function will set a callback in order for the server to get
639 * the Diffie-Hellman or RSA parameters for certificate
640 * authentication. The callback should return %GNUTLS_E_SUCCESS (0) on success.
643 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res
,
644 gnutls_params_function
* func
)
646 res
->params_func
= func
;
651 * gnutls_certificate_set_verify_flags:
652 * @res: is a gnutls_certificate_credentials_t structure
653 * @flags: are the flags
655 * This function will set the flags to be used at verification of the
656 * certificates. Flags must be OR of the
657 * #gnutls_certificate_verify_flags enumerations.
661 gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
662 res
, unsigned int flags
)
664 res
->verify_flags
= flags
;
668 * gnutls_certificate_set_verify_limits:
669 * @res: is a gnutls_certificate_credentials structure
670 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
671 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
673 * This function will set some upper limits for the default
674 * verification function, gnutls_certificate_verify_peers2(), to avoid
675 * denial of service attacks. You can set them to zero to disable
679 gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res
,
680 unsigned int max_bits
,
681 unsigned int max_depth
)
683 res
->verify_depth
= max_depth
;
684 res
->verify_bits
= max_bits
;
688 * gnutls_certificate_set_rsa_export_params:
689 * @res: is a gnutls_certificate_credentials_t structure
690 * @rsa_params: is a structure that holds temporary RSA parameters.
692 * This function will set the temporary RSA parameters for a
693 * certificate server to use. These parameters will be used in
694 * RSA-EXPORT cipher suites.
697 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
698 res
, gnutls_rsa_params_t rsa_params
)
700 res
->rsa_params
= rsa_params
;
704 * gnutls_psk_set_params_function:
705 * @res: is a gnutls_psk_server_credentials_t structure
706 * @func: is the function to be called
708 * This function will set a callback in order for the server to get
709 * the Diffie-Hellman or RSA parameters for PSK authentication. The
710 * callback should return %GNUTLS_E_SUCCESS (0) on success.
713 gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res
,
714 gnutls_params_function
* func
)
716 res
->params_func
= func
;
720 * gnutls_anon_set_params_function:
721 * @res: is a gnutls_anon_server_credentials_t structure
722 * @func: is the function to be called
724 * This function will set a callback in order for the server to get
725 * the Diffie-Hellman or RSA parameters for anonymous authentication.
726 * The callback should return %GNUTLS_E_SUCCESS (0) on success.
729 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res
,
730 gnutls_params_function
* func
)
732 res
->params_func
= func
;