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 * Note that values lower than 512 bits may allow decryption of the
90 * This function has no effect in server side.
94 gnutls_dh_set_prime_bits (gnutls_session_t session
, unsigned int bits
)
96 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
);
97 session
->internals
.dh_prime_bits
= bits
;
102 * gnutls_dh_get_group:
103 * @session: is a gnutls session
104 * @raw_gen: will hold the generator.
105 * @raw_prime: will hold the prime.
107 * This function will return the group parameters used in the last
108 * Diffie-Hellman key exchange with the peer. These are the prime and
109 * the generator used. This function should be used for both
110 * anonymous and ephemeral Diffie-Hellman. The output parameters must
111 * be freed with gnutls_free().
113 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
114 * an error code is returned.
117 gnutls_dh_get_group (gnutls_session_t session
,
118 gnutls_datum_t
* raw_gen
, gnutls_datum_t
* raw_prime
)
122 anon_auth_info_t anon_info
;
123 cert_auth_info_t cert_info
;
124 psk_auth_info_t psk_info
;
126 switch (gnutls_auth_get_type (session
))
128 case GNUTLS_CRD_ANON
:
129 anon_info
= _gnutls_get_auth_info (session
);
130 if (anon_info
== NULL
)
131 return GNUTLS_E_INTERNAL_ERROR
;
135 psk_info
= _gnutls_get_auth_info (session
);
136 if (psk_info
== NULL
)
137 return GNUTLS_E_INTERNAL_ERROR
;
140 case GNUTLS_CRD_CERTIFICATE
:
141 cert_info
= _gnutls_get_auth_info (session
);
142 if (cert_info
== NULL
)
143 return GNUTLS_E_INTERNAL_ERROR
;
148 return GNUTLS_E_INVALID_REQUEST
;
151 ret
= _gnutls_set_datum (raw_prime
, dh
->prime
.data
, dh
->prime
.size
);
158 ret
= _gnutls_set_datum (raw_gen
, dh
->generator
.data
, dh
->generator
.size
);
162 _gnutls_free_datum (raw_prime
);
170 * gnutls_dh_get_pubkey:
171 * @session: is a gnutls session
172 * @raw_key: will hold the public key.
174 * This function will return the peer's public key used in the last
175 * Diffie-Hellman key exchange. This function should be used for both
176 * anonymous and ephemeral Diffie-Hellman. The output parameters must
177 * be freed with gnutls_free().
179 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
180 * an error code is returned.
183 gnutls_dh_get_pubkey (gnutls_session_t session
, gnutls_datum_t
* raw_key
)
186 anon_auth_info_t anon_info
;
187 cert_auth_info_t cert_info
;
188 cert_auth_info_t psk_info
;
190 switch (gnutls_auth_get_type (session
))
192 case GNUTLS_CRD_ANON
:
194 anon_info
= _gnutls_get_auth_info (session
);
195 if (anon_info
== NULL
)
196 return GNUTLS_E_INTERNAL_ERROR
;
202 psk_info
= _gnutls_get_auth_info (session
);
203 if (psk_info
== NULL
)
204 return GNUTLS_E_INTERNAL_ERROR
;
208 case GNUTLS_CRD_CERTIFICATE
:
211 cert_info
= _gnutls_get_auth_info (session
);
212 if (cert_info
== NULL
)
213 return GNUTLS_E_INTERNAL_ERROR
;
219 return GNUTLS_E_INVALID_REQUEST
;
222 return _gnutls_set_datum (raw_key
, dh
->public_key
.data
,
223 dh
->public_key
.size
);
227 * gnutls_rsa_export_get_pubkey:
228 * @session: is a gnutls session
229 * @exponent: will hold the exponent.
230 * @modulus: will hold the modulus.
232 * This function will return the peer's public key exponent and
233 * modulus used in the last RSA-EXPORT authentication. The output
234 * parameters must be freed with gnutls_free().
236 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
237 * an error code is returned.
240 gnutls_rsa_export_get_pubkey (gnutls_session_t session
,
241 gnutls_datum_t
* exponent
,
242 gnutls_datum_t
* modulus
)
244 cert_auth_info_t info
;
247 if (gnutls_auth_get_type (session
) == GNUTLS_CRD_CERTIFICATE
)
249 info
= _gnutls_get_auth_info (session
);
251 return GNUTLS_E_INTERNAL_ERROR
;
253 ret
= _gnutls_set_datum (modulus
, info
->rsa_export
.modulus
.data
,
254 info
->rsa_export
.modulus
.size
);
261 ret
= _gnutls_set_datum (exponent
, info
->rsa_export
.exponent
.data
,
262 info
->rsa_export
.exponent
.size
);
266 _gnutls_free_datum (modulus
);
273 return GNUTLS_E_INVALID_REQUEST
;
278 * gnutls_dh_get_secret_bits:
279 * @session: is a gnutls session
281 * This function will return the bits used in the last Diffie-Hellman
282 * key exchange with the peer. Should be used for both anonymous and
283 * ephemeral Diffie-Hellman.
285 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
286 * an error code is returned.
289 gnutls_dh_get_secret_bits (gnutls_session_t session
)
291 switch (gnutls_auth_get_type (session
))
293 case GNUTLS_CRD_ANON
:
295 anon_auth_info_t info
;
297 info
= _gnutls_get_auth_info (session
);
299 return GNUTLS_E_INTERNAL_ERROR
;
300 return info
->dh
.secret_bits
;
304 psk_auth_info_t info
;
306 info
= _gnutls_get_auth_info (session
);
308 return GNUTLS_E_INTERNAL_ERROR
;
309 return info
->dh
.secret_bits
;
311 case GNUTLS_CRD_CERTIFICATE
:
313 cert_auth_info_t info
;
315 info
= _gnutls_get_auth_info (session
);
317 return GNUTLS_E_INTERNAL_ERROR
;
319 return info
->dh
.secret_bits
;
323 return GNUTLS_E_INVALID_REQUEST
;
328 mpi_buf2bits (gnutls_datum_t
* mpi_buf
)
333 rc
= _gnutls_mpi_scan_nz (&mpi
, mpi_buf
->data
, mpi_buf
->size
);
340 rc
= _gnutls_mpi_get_nbits (mpi
);
341 _gnutls_mpi_release (&mpi
);
347 * gnutls_dh_get_prime_bits:
348 * @session: is a gnutls session
350 * This function will return the bits of the prime used in the last
351 * Diffie-Hellman key exchange with the peer. Should be used for both
352 * anonymous and ephemeral Diffie-Hellman. Note that some ciphers,
353 * like RSA and DSA without DHE, do not use a Diffie-Hellman key
354 * exchange, and then this function will return 0.
356 * Returns: The Diffie-Hellman bit strength is returned, or 0 if no
357 * Diffie-Hellman key exchange was done, or a negative error code on
361 gnutls_dh_get_prime_bits (gnutls_session_t session
)
365 switch (gnutls_auth_get_type (session
))
367 case GNUTLS_CRD_ANON
:
369 anon_auth_info_t info
;
371 info
= _gnutls_get_auth_info (session
);
373 return GNUTLS_E_INTERNAL_ERROR
;
379 psk_auth_info_t info
;
381 info
= _gnutls_get_auth_info (session
);
383 return GNUTLS_E_INTERNAL_ERROR
;
387 case GNUTLS_CRD_CERTIFICATE
:
389 cert_auth_info_t info
;
391 info
= _gnutls_get_auth_info (session
);
393 return GNUTLS_E_INTERNAL_ERROR
;
400 return GNUTLS_E_INVALID_REQUEST
;
403 return mpi_buf2bits (&dh
->prime
);
407 * gnutls_rsa_export_get_modulus_bits:
408 * @session: is a gnutls session
410 * Get the export RSA parameter's modulus size.
412 * Returns: The bits used in the last RSA-EXPORT key exchange with the
413 * peer, or a negative error code in case of error.
416 gnutls_rsa_export_get_modulus_bits (gnutls_session_t session
)
418 cert_auth_info_t info
;
420 info
= _gnutls_get_auth_info (session
);
422 return GNUTLS_E_INTERNAL_ERROR
;
424 return mpi_buf2bits (&info
->rsa_export
.modulus
);
428 * gnutls_dh_get_peers_public_bits:
429 * @session: is a gnutls session
431 * Get the Diffie-Hellman public key bit size. Can be used for both
432 * anonymous and ephemeral Diffie-Hellman.
434 * Returns: The public key bit size used in the last Diffie-Hellman
435 * key exchange with the peer, or a negative error code in case of error.
438 gnutls_dh_get_peers_public_bits (gnutls_session_t session
)
442 switch (gnutls_auth_get_type (session
))
444 case GNUTLS_CRD_ANON
:
446 anon_auth_info_t info
;
448 info
= _gnutls_get_auth_info (session
);
450 return GNUTLS_E_INTERNAL_ERROR
;
457 psk_auth_info_t info
;
459 info
= _gnutls_get_auth_info (session
);
461 return GNUTLS_E_INTERNAL_ERROR
;
466 case GNUTLS_CRD_CERTIFICATE
:
468 cert_auth_info_t info
;
470 info
= _gnutls_get_auth_info (session
);
472 return GNUTLS_E_INTERNAL_ERROR
;
479 return GNUTLS_E_INVALID_REQUEST
;
482 return mpi_buf2bits (&dh
->public_key
);
485 /* CERTIFICATE STUFF */
488 * gnutls_certificate_get_ours:
489 * @session: is a gnutls session
491 * Gets the certificate as sent to the peer in the last handshake.
492 * The certificate is in raw (DER) format. No certificate
493 * list is being returned. Only the first certificate.
495 * Returns: a pointer to a #gnutls_datum_t containing our
496 * certificate, or %NULL in case of an error or if no certificate
499 const gnutls_datum_t
*
500 gnutls_certificate_get_ours (gnutls_session_t session
)
502 gnutls_certificate_credentials_t cred
;
504 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
506 cred
= (gnutls_certificate_credentials_t
)
507 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
508 if (cred
== NULL
|| cred
->certs
== NULL
)
514 if (session
->internals
.selected_cert_list
== NULL
)
517 return &session
->internals
.selected_cert_list
[0].cert
;
521 * gnutls_certificate_get_peers:
522 * @session: is a gnutls session
523 * @list_size: is the length of the certificate list
525 * Get the peer's raw certificate (chain) as sent by the peer. These
526 * certificates are in raw format (DER encoded for X.509). In case of
527 * a X.509 then a certificate list may be present. The first
528 * certificate in the list is the peer's certificate, following the
529 * issuer's certificate, then the issuer's issuer etc.
531 * In case of OpenPGP keys a single key will be returned in raw
534 * Returns: a pointer to a #gnutls_datum_t containing our
535 * certificates, or %NULL in case of an error or if no certificate
538 const gnutls_datum_t
*
539 gnutls_certificate_get_peers (gnutls_session_t
540 session
, unsigned int *list_size
)
542 cert_auth_info_t info
;
544 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE
, NULL
);
546 info
= _gnutls_get_auth_info (session
);
550 *list_size
= info
->ncerts
;
551 return info
->raw_certificate_list
;
556 * gnutls_certificate_client_get_request_status:
557 * @session: is a gnutls session
559 * Get whether client certificate is requested or not.
561 * Returns: 0 if the peer (server) did not request client
562 * authentication or 1 otherwise, or a negative error code in case of
566 gnutls_certificate_client_get_request_status (gnutls_session_t session
)
568 return session
->key
->crt_requested
;
572 * gnutls_fingerprint:
573 * @algo: is a digest algorithm
575 * @result: is the place where the result will be copied (may be null).
576 * @result_size: should hold the size of the result. The actual size
577 * of the returned result will also be copied there.
579 * This function will calculate a fingerprint (actually a hash), of
580 * the given data. The result is not printable data. You should
581 * convert it to hex, or to something else printable.
583 * This is the usual way to calculate a fingerprint of an X.509 DER
584 * encoded certificate. Note however that the fingerprint of an
585 * OpenPGP is not just a hash and cannot be calculated with this
588 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
589 * an error code is returned.
592 gnutls_fingerprint (gnutls_digest_algorithm_t algo
,
593 const gnutls_datum_t
* data
, void *result
,
594 size_t * result_size
)
597 int hash_len
= _gnutls_hash_get_algo_len (algo
);
599 if (hash_len
< 0 || (unsigned) hash_len
> *result_size
|| result
== NULL
)
601 *result_size
= hash_len
;
602 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
604 *result_size
= hash_len
;
608 ret
= _gnutls_hash_fast( algo
, data
->data
, data
->size
, result
);
610 return gnutls_assert_val(ret
);
618 * gnutls_certificate_set_dh_params:
619 * @res: is a gnutls_certificate_credentials_t structure
620 * @dh_params: is a structure that holds Diffie-Hellman parameters.
622 * This function will set the Diffie-Hellman parameters for a
623 * certificate server to use. These parameters will be used in
624 * Ephemeral Diffie-Hellman cipher suites. Note that only a pointer
625 * to the parameters are stored in the certificate handle, so if you
626 * deallocate the parameters before the certificate is deallocated,
627 * you must change the parameters stored in the certificate first.
631 gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res
,
632 gnutls_dh_params_t dh_params
)
634 res
->dh_params
= dh_params
;
638 * gnutls_certificate_set_params_function:
639 * @res: is a gnutls_certificate_credentials_t structure
640 * @func: is the function to be called
642 * This function will set a callback in order for the server to get
643 * the Diffie-Hellman or RSA parameters for certificate
644 * authentication. The callback should return %GNUTLS_E_SUCCESS (0) on success.
647 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res
,
648 gnutls_params_function
* func
)
650 res
->params_func
= func
;
655 * gnutls_certificate_set_verify_flags:
656 * @res: is a gnutls_certificate_credentials_t structure
657 * @flags: are the flags
659 * This function will set the flags to be used at verification of the
660 * certificates. Flags must be OR of the
661 * #gnutls_certificate_verify_flags enumerations.
665 gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
666 res
, unsigned int flags
)
668 res
->verify_flags
= flags
;
672 * gnutls_certificate_set_verify_limits:
673 * @res: is a gnutls_certificate_credentials structure
674 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
675 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
677 * This function will set some upper limits for the default
678 * verification function, gnutls_certificate_verify_peers2(), to avoid
679 * denial of service attacks. You can set them to zero to disable
683 gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res
,
684 unsigned int max_bits
,
685 unsigned int max_depth
)
687 res
->verify_depth
= max_depth
;
688 res
->verify_bits
= max_bits
;
692 * gnutls_certificate_set_rsa_export_params:
693 * @res: is a gnutls_certificate_credentials_t structure
694 * @rsa_params: is a structure that holds temporary RSA parameters.
696 * This function will set the temporary RSA parameters for a
697 * certificate server to use. These parameters will be used in
698 * RSA-EXPORT cipher suites.
701 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
702 res
, gnutls_rsa_params_t rsa_params
)
704 res
->rsa_params
= rsa_params
;
708 * gnutls_psk_set_params_function:
709 * @res: is a gnutls_psk_server_credentials_t structure
710 * @func: is the function to be called
712 * This function will set a callback in order for the server to get
713 * the Diffie-Hellman or RSA parameters for PSK authentication. The
714 * callback should return %GNUTLS_E_SUCCESS (0) on success.
717 gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res
,
718 gnutls_params_function
* func
)
720 res
->params_func
= func
;
724 * gnutls_anon_set_params_function:
725 * @res: is a gnutls_anon_server_credentials_t structure
726 * @func: is the function to be called
728 * This function will set a callback in order for the server to get
729 * the Diffie-Hellman or RSA parameters for anonymous authentication.
730 * The callback should return %GNUTLS_E_SUCCESS (0) on success.
733 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res
,
734 gnutls_params_function
* func
)
736 res
->params_func
= func
;