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,
26 /* This file contains certificate authentication functions to be exported in the
27 * API and did not fit elsewhere.
30 #include <gnutls_int.h>
32 #include <auth_anon.h>
33 #include <auth_cert.h>
35 #include <gnutls_errors.h>
36 #include <gnutls_auth.h>
37 #include <gnutls_state.h>
38 #include <gnutls_datum.h>
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.
60 gnutls_dh_set_prime_bits (gnutls_session_t session
, unsigned int bits
)
62 session
->internals
.dh_prime_bits
= bits
;
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.
82 gnutls_dh_get_group (gnutls_session_t session
,
83 gnutls_datum_t
* raw_gen
, gnutls_datum_t
* raw_prime
)
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
))
94 anon_info
= _gnutls_get_auth_info (session
);
95 if (anon_info
== NULL
)
96 return GNUTLS_E_INTERNAL_ERROR
;
100 psk_info
= _gnutls_get_auth_info (session
);
101 if (psk_info
== NULL
)
102 return GNUTLS_E_INTERNAL_ERROR
;
105 case GNUTLS_CRD_CERTIFICATE
:
106 cert_info
= _gnutls_get_auth_info (session
);
107 if (cert_info
== NULL
)
108 return GNUTLS_E_INTERNAL_ERROR
;
113 return GNUTLS_E_INVALID_REQUEST
;
116 ret
= _gnutls_set_datum (raw_prime
, dh
->prime
.data
, dh
->prime
.size
);
123 ret
= _gnutls_set_datum (raw_gen
, dh
->generator
.data
, dh
->generator
.size
);
127 _gnutls_free_datum (raw_prime
);
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
)
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
;
167 psk_info
= _gnutls_get_auth_info (session
);
168 if (psk_info
== NULL
)
169 return GNUTLS_E_INTERNAL_ERROR
;
173 case GNUTLS_CRD_CERTIFICATE
:
176 cert_info
= _gnutls_get_auth_info (session
);
177 if (cert_info
== NULL
)
178 return GNUTLS_E_INTERNAL_ERROR
;
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
;
212 if (gnutls_auth_get_type (session
) == GNUTLS_CRD_CERTIFICATE
)
214 info
= _gnutls_get_auth_info (session
);
216 return GNUTLS_E_INTERNAL_ERROR
;
218 ret
= _gnutls_set_datum (modulus
, info
->rsa_export
.modulus
.data
,
219 info
->rsa_export
.modulus
.size
);
226 ret
= _gnutls_set_datum (exponent
, info
->rsa_export
.exponent
.data
,
227 info
->rsa_export
.exponent
.size
);
231 _gnutls_free_datum (modulus
);
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
);
264 return GNUTLS_E_INTERNAL_ERROR
;
265 return info
->dh
.secret_bits
;
269 psk_auth_info_t info
;
271 info
= _gnutls_get_auth_info (session
);
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
);
282 return GNUTLS_E_INTERNAL_ERROR
;
284 return info
->dh
.secret_bits
;
288 return GNUTLS_E_INVALID_REQUEST
;
293 mpi_buf2bits (gnutls_datum_t
* mpi_buf
)
298 rc
= _gnutls_mpi_scan_nz (&mpi
, mpi_buf
->data
, mpi_buf
->size
);
305 rc
= _gnutls_mpi_get_nbits (mpi
);
306 _gnutls_mpi_release (&mpi
);
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
326 gnutls_dh_get_prime_bits (gnutls_session_t session
)
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
);
338 return GNUTLS_E_INTERNAL_ERROR
;
344 psk_auth_info_t info
;
346 info
= _gnutls_get_auth_info (session
);
348 return GNUTLS_E_INTERNAL_ERROR
;
352 case GNUTLS_CRD_CERTIFICATE
:
354 cert_auth_info_t info
;
356 info
= _gnutls_get_auth_info (session
);
358 return GNUTLS_E_INTERNAL_ERROR
;
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
);
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
)
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
);
415 return GNUTLS_E_INTERNAL_ERROR
;
422 psk_auth_info_t info
;
424 info
= _gnutls_get_auth_info (session
);
426 return GNUTLS_E_INTERNAL_ERROR
;
431 case GNUTLS_CRD_CERTIFICATE
:
433 cert_auth_info_t info
;
435 info
= _gnutls_get_auth_info (session
);
437 return GNUTLS_E_INTERNAL_ERROR
;
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
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
)
479 if (session
->internals
.selected_cert_list
== 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
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
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
);
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
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
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
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
)
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
;
573 int ret
= _gnutls_hash_init (&td
, HASH2MAC (algo
));
580 _gnutls_hash (&td
, data
->data
, data
->size
);
582 _gnutls_hash_deinit (&td
, result
);
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.
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.
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.
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
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.
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.
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.
705 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res
,
706 gnutls_params_function
* func
)
708 res
->params_func
= func
;