properly break lines.
[gnutls.git] / lib / gnutls_ui.c
blob28dcadea8866e6cbe2430fb4201fcf0d78295545
1 /*
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>
28 #include <auth/srp.h>
29 #include <auth/anon.h>
30 #include <auth/cert.h>
31 #include <auth/psk.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>
38 /**
39 * gnutls_random_art:
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.
53 **/
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,
57 gnutls_datum_t* art)
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);
68 return 0;
71 /* ANON & DHE */
73 /**
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.
89 **/
90 void
91 gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits)
93 session->internals.dh_prime_bits = bits;
97 /**
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)
116 dh_info_st *dh;
117 int ret;
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;
128 dh = &anon_info->dh;
129 break;
130 case GNUTLS_CRD_PSK:
131 psk_info = _gnutls_get_auth_info (session);
132 if (psk_info == NULL)
133 return GNUTLS_E_INTERNAL_ERROR;
134 dh = &psk_info->dh;
135 break;
136 case GNUTLS_CRD_CERTIFICATE:
137 cert_info = _gnutls_get_auth_info (session);
138 if (cert_info == NULL)
139 return GNUTLS_E_INTERNAL_ERROR;
140 dh = &cert_info->dh;
141 break;
142 default:
143 gnutls_assert ();
144 return GNUTLS_E_INVALID_REQUEST;
147 ret = _gnutls_set_datum (raw_prime, dh->prime.data, dh->prime.size);
148 if (ret < 0)
150 gnutls_assert ();
151 return ret;
154 ret = _gnutls_set_datum (raw_gen, dh->generator.data, dh->generator.size);
155 if (ret < 0)
157 gnutls_assert ();
158 _gnutls_free_datum (raw_prime);
159 return ret;
162 return 0;
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)
181 dh_info_st *dh;
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;
193 dh = &anon_info->dh;
194 break;
196 case GNUTLS_CRD_PSK:
198 psk_info = _gnutls_get_auth_info (session);
199 if (psk_info == NULL)
200 return GNUTLS_E_INTERNAL_ERROR;
201 dh = &psk_info->dh;
202 break;
204 case GNUTLS_CRD_CERTIFICATE:
207 cert_info = _gnutls_get_auth_info (session);
208 if (cert_info == NULL)
209 return GNUTLS_E_INTERNAL_ERROR;
210 dh = &cert_info->dh;
211 break;
213 default:
214 gnutls_assert ();
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;
241 int ret;
243 if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
245 info = _gnutls_get_auth_info (session);
246 if (info == NULL)
247 return GNUTLS_E_INTERNAL_ERROR;
249 ret = _gnutls_set_datum (modulus, info->rsa_export.modulus.data,
250 info->rsa_export.modulus.size);
251 if (ret < 0)
253 gnutls_assert ();
254 return ret;
257 ret = _gnutls_set_datum (exponent, info->rsa_export.exponent.data,
258 info->rsa_export.exponent.size);
259 if (ret < 0)
261 gnutls_assert ();
262 _gnutls_free_datum (modulus);
263 return ret;
266 return 0;
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);
294 if (info == NULL)
295 return GNUTLS_E_INTERNAL_ERROR;
296 return info->dh.secret_bits;
298 case GNUTLS_CRD_PSK:
300 psk_auth_info_t info;
302 info = _gnutls_get_auth_info (session);
303 if (info == NULL)
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);
312 if (info == NULL)
313 return GNUTLS_E_INTERNAL_ERROR;
315 return info->dh.secret_bits;
317 default:
318 gnutls_assert ();
319 return GNUTLS_E_INVALID_REQUEST;
323 static int
324 mpi_buf2bits (gnutls_datum_t * mpi_buf)
326 bigint_t mpi;
327 int rc;
329 rc = _gnutls_mpi_scan_nz (&mpi, mpi_buf->data, mpi_buf->size);
330 if (rc)
332 gnutls_assert ();
333 return rc;
336 rc = _gnutls_mpi_get_nbits (mpi);
337 _gnutls_mpi_release (&mpi);
339 return rc;
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
354 * failure.
357 gnutls_dh_get_prime_bits (gnutls_session_t session)
359 dh_info_st *dh;
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);
368 if (info == NULL)
369 return GNUTLS_E_INTERNAL_ERROR;
370 dh = &info->dh;
371 break;
373 case GNUTLS_CRD_PSK:
375 psk_auth_info_t info;
377 info = _gnutls_get_auth_info (session);
378 if (info == NULL)
379 return GNUTLS_E_INTERNAL_ERROR;
380 dh = &info->dh;
381 break;
383 case GNUTLS_CRD_CERTIFICATE:
385 cert_auth_info_t info;
387 info = _gnutls_get_auth_info (session);
388 if (info == NULL)
389 return GNUTLS_E_INTERNAL_ERROR;
391 dh = &info->dh;
392 break;
394 default:
395 gnutls_assert ();
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);
417 if (info == NULL)
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)
436 dh_info_st *dh;
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);
445 if (info == NULL)
446 return GNUTLS_E_INTERNAL_ERROR;
448 dh = &info->dh;
449 break;
451 case GNUTLS_CRD_PSK:
453 psk_auth_info_t info;
455 info = _gnutls_get_auth_info (session);
456 if (info == NULL)
457 return GNUTLS_E_INTERNAL_ERROR;
459 dh = &info->dh;
460 break;
462 case GNUTLS_CRD_CERTIFICATE:
464 cert_auth_info_t info;
466 info = _gnutls_get_auth_info (session);
467 if (info == NULL)
468 return GNUTLS_E_INTERNAL_ERROR;
470 dh = &info->dh;
471 break;
473 default:
474 gnutls_assert ();
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
493 * was used.
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)
506 gnutls_assert ();
507 return NULL;
510 if (session->internals.selected_cert_list == NULL)
511 return 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
528 * format.
530 * Returns: a pointer to a #gnutls_datum_t containing our
531 * certificates, or %NULL in case of an error or if no certificate
532 * was used.
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);
543 if (info == NULL)
544 return NULL;
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
559 * error.
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
570 * @data: is the data
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
582 * function.
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)
592 int ret;
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;
602 if (result)
604 ret = _gnutls_hash_fast( algo, data->data, data->size, result);
605 if (ret < 0)
606 return gnutls_assert_val(ret);
609 return 0;
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.
626 void
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.
642 void
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.
660 void
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
676 * limits.
678 void
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.
696 void
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.
712 void
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.
728 void
729 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
730 gnutls_params_function * func)
732 res->params_func = func;