Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_ui.c
1 /*
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010 Free
3  * Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
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.
13  *
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.
18  *
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,
22  * USA
23  *
24  */
25
26 /* This file contains certificate authentication functions to be exported in the
27  * API and did not fit elsewhere.
28  */
29
30 #include <gnutls_int.h>
31 #include <auth_srp.h>
32 #include <auth_anon.h>
33 #include <auth_cert.h>
34 #include <auth_psk.h>
35 #include <gnutls_errors.h>
36 #include <gnutls_auth.h>
37 #include <gnutls_state.h>
38 #include <gnutls_datum.h>
39
40 /* ANON & DHE */
41
42 /**
43  * gnutls_dh_set_prime_bits:
44  * @session: is a #gnutls_session_t structure.
45  * @bits: is the number of bits
46  *
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.
51  *
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.
55  *
56  * This function has no effect in server side.
57  *
58  **/
59 void
60 gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits)
61 {
62   session->internals.dh_prime_bits = bits;
63 }
64
65
66 /**
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.
71  *
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().
77  *
78  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
79  *   an error code is returned.
80  **/
81 int
82 gnutls_dh_get_group (gnutls_session_t session,
83                      gnutls_datum_t * raw_gen, gnutls_datum_t * raw_prime)
84 {
85   dh_info_st *dh;
86   int ret;
87   anon_auth_info_t anon_info;
88   cert_auth_info_t cert_info;
89   psk_auth_info_t psk_info;
90
91   switch (gnutls_auth_get_type (session))
92     {
93     case GNUTLS_CRD_ANON:
94       anon_info = _gnutls_get_auth_info (session);
95       if (anon_info == NULL)
96         return GNUTLS_E_INTERNAL_ERROR;
97       dh = &anon_info->dh;
98       break;
99     case GNUTLS_CRD_PSK:
100       psk_info = _gnutls_get_auth_info (session);
101       if (psk_info == NULL)
102         return GNUTLS_E_INTERNAL_ERROR;
103       dh = &psk_info->dh;
104       break;
105     case GNUTLS_CRD_CERTIFICATE:
106       cert_info = _gnutls_get_auth_info (session);
107       if (cert_info == NULL)
108         return GNUTLS_E_INTERNAL_ERROR;
109       dh = &cert_info->dh;
110       break;
111     default:
112       gnutls_assert ();
113       return GNUTLS_E_INVALID_REQUEST;
114     }
115
116   ret = _gnutls_set_datum (raw_prime, dh->prime.data, dh->prime.size);
117   if (ret < 0)
118     {
119       gnutls_assert ();
120       return ret;
121     }
122
123   ret = _gnutls_set_datum (raw_gen, dh->generator.data, dh->generator.size);
124   if (ret < 0)
125     {
126       gnutls_assert ();
127       _gnutls_free_datum (raw_prime);
128       return ret;
129     }
130
131   return 0;
132 }
133
134 /**
135  * gnutls_dh_get_pubkey:
136  * @session: is a gnutls session
137  * @raw_key: will hold the public key.
138  *
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().
143  *
144  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
145  *   an error code is returned.
146  **/
147 int
148 gnutls_dh_get_pubkey (gnutls_session_t session, gnutls_datum_t * raw_key)
149 {
150   dh_info_st *dh;
151   anon_auth_info_t anon_info;
152   cert_auth_info_t cert_info;
153   cert_auth_info_t psk_info;
154
155   switch (gnutls_auth_get_type (session))
156     {
157     case GNUTLS_CRD_ANON:
158       {
159         anon_info = _gnutls_get_auth_info (session);
160         if (anon_info == NULL)
161           return GNUTLS_E_INTERNAL_ERROR;
162         dh = &anon_info->dh;
163         break;
164       }
165     case GNUTLS_CRD_PSK:
166       {
167         psk_info = _gnutls_get_auth_info (session);
168         if (psk_info == NULL)
169           return GNUTLS_E_INTERNAL_ERROR;
170         dh = &psk_info->dh;
171         break;
172       }
173     case GNUTLS_CRD_CERTIFICATE:
174       {
175
176         cert_info = _gnutls_get_auth_info (session);
177         if (cert_info == NULL)
178           return GNUTLS_E_INTERNAL_ERROR;
179         dh = &cert_info->dh;
180         break;
181       }
182     default:
183       gnutls_assert ();
184       return GNUTLS_E_INVALID_REQUEST;
185     }
186
187   return _gnutls_set_datum (raw_key, dh->public_key.data,
188                             dh->public_key.size);
189 }
190
191 /**
192  * gnutls_rsa_export_get_pubkey:
193  * @session: is a gnutls session
194  * @exponent: will hold the exponent.
195  * @modulus: will hold the modulus.
196  *
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().
200  *
201  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
202  *   an error code is returned.
203  **/
204 int
205 gnutls_rsa_export_get_pubkey (gnutls_session_t session,
206                               gnutls_datum_t * exponent,
207                               gnutls_datum_t * modulus)
208 {
209   cert_auth_info_t info;
210   int ret;
211
212   if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
213     {
214       info = _gnutls_get_auth_info (session);
215       if (info == NULL)
216         return GNUTLS_E_INTERNAL_ERROR;
217
218       ret = _gnutls_set_datum (modulus, info->rsa_export.modulus.data,
219                                info->rsa_export.modulus.size);
220       if (ret < 0)
221         {
222           gnutls_assert ();
223           return ret;
224         }
225
226       ret = _gnutls_set_datum (exponent, info->rsa_export.exponent.data,
227                                info->rsa_export.exponent.size);
228       if (ret < 0)
229         {
230           gnutls_assert ();
231           _gnutls_free_datum (modulus);
232           return ret;
233         }
234
235       return 0;
236     }
237
238   return GNUTLS_E_INVALID_REQUEST;
239 }
240
241
242 /**
243  * gnutls_dh_get_secret_bits:
244  * @session: is a gnutls session
245  *
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.
249  *
250  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
251  *   an error code is returned.
252  **/
253 int
254 gnutls_dh_get_secret_bits (gnutls_session_t session)
255 {
256   switch (gnutls_auth_get_type (session))
257     {
258     case GNUTLS_CRD_ANON:
259       {
260         anon_auth_info_t info;
261
262         info = _gnutls_get_auth_info (session);
263         if (info == NULL)
264           return GNUTLS_E_INTERNAL_ERROR;
265         return info->dh.secret_bits;
266       }
267     case GNUTLS_CRD_PSK:
268       {
269         psk_auth_info_t info;
270
271         info = _gnutls_get_auth_info (session);
272         if (info == NULL)
273           return GNUTLS_E_INTERNAL_ERROR;
274         return info->dh.secret_bits;
275       }
276     case GNUTLS_CRD_CERTIFICATE:
277       {
278         cert_auth_info_t info;
279
280         info = _gnutls_get_auth_info (session);
281         if (info == NULL)
282           return GNUTLS_E_INTERNAL_ERROR;
283
284         return info->dh.secret_bits;
285       }
286     default:
287       gnutls_assert ();
288       return GNUTLS_E_INVALID_REQUEST;
289     }
290 }
291
292 static int
293 mpi_buf2bits (gnutls_datum_t * mpi_buf)
294 {
295   bigint_t mpi;
296   int rc;
297
298   rc = _gnutls_mpi_scan_nz (&mpi, mpi_buf->data, mpi_buf->size);
299   if (rc)
300     {
301       gnutls_assert ();
302       return rc;
303     }
304
305   rc = _gnutls_mpi_get_nbits (mpi);
306   _gnutls_mpi_release (&mpi);
307
308   return rc;
309 }
310
311 /**
312  * gnutls_dh_get_prime_bits:
313  * @session: is a gnutls session
314  *
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.
320  *
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
323  *   failure.
324  **/
325 int
326 gnutls_dh_get_prime_bits (gnutls_session_t session)
327 {
328   dh_info_st *dh;
329
330   switch (gnutls_auth_get_type (session))
331     {
332     case GNUTLS_CRD_ANON:
333       {
334         anon_auth_info_t info;
335
336         info = _gnutls_get_auth_info (session);
337         if (info == NULL)
338           return GNUTLS_E_INTERNAL_ERROR;
339         dh = &info->dh;
340         break;
341       }
342     case GNUTLS_CRD_PSK:
343       {
344         psk_auth_info_t info;
345
346         info = _gnutls_get_auth_info (session);
347         if (info == NULL)
348           return GNUTLS_E_INTERNAL_ERROR;
349         dh = &info->dh;
350         break;
351       }
352     case GNUTLS_CRD_CERTIFICATE:
353       {
354         cert_auth_info_t info;
355
356         info = _gnutls_get_auth_info (session);
357         if (info == NULL)
358           return GNUTLS_E_INTERNAL_ERROR;
359
360         dh = &info->dh;
361         break;
362       }
363     default:
364       gnutls_assert ();
365       return GNUTLS_E_INVALID_REQUEST;
366     }
367
368   return mpi_buf2bits (&dh->prime);
369 }
370
371 /**
372  * gnutls_rsa_export_get_modulus_bits:
373  * @session: is a gnutls session
374  *
375  * Get the export RSA parameter's modulus size.
376  *
377  * Returns: the bits used in the last RSA-EXPORT key exchange with the
378  *   peer, or a negative value in case of error.
379  **/
380 int
381 gnutls_rsa_export_get_modulus_bits (gnutls_session_t session)
382 {
383   cert_auth_info_t info;
384
385   info = _gnutls_get_auth_info (session);
386   if (info == NULL)
387     return GNUTLS_E_INTERNAL_ERROR;
388
389   return mpi_buf2bits (&info->rsa_export.modulus);
390 }
391
392 /**
393  * gnutls_dh_get_peers_public_bits:
394  * @session: is a gnutls session
395  *
396  * Get the Diffie-Hellman public key bit size.  Can be used for both
397  * anonymous and ephemeral Diffie-Hellman.
398  *
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.
401  **/
402 int
403 gnutls_dh_get_peers_public_bits (gnutls_session_t session)
404 {
405   dh_info_st *dh;
406
407   switch (gnutls_auth_get_type (session))
408     {
409     case GNUTLS_CRD_ANON:
410       {
411         anon_auth_info_t info;
412
413         info = _gnutls_get_auth_info (session);
414         if (info == NULL)
415           return GNUTLS_E_INTERNAL_ERROR;
416
417         dh = &info->dh;
418         break;
419       }
420     case GNUTLS_CRD_PSK:
421       {
422         psk_auth_info_t info;
423
424         info = _gnutls_get_auth_info (session);
425         if (info == NULL)
426           return GNUTLS_E_INTERNAL_ERROR;
427
428         dh = &info->dh;
429         break;
430       }
431     case GNUTLS_CRD_CERTIFICATE:
432       {
433         cert_auth_info_t info;
434
435         info = _gnutls_get_auth_info (session);
436         if (info == NULL)
437           return GNUTLS_E_INTERNAL_ERROR;
438
439         dh = &info->dh;
440         break;
441       }
442     default:
443       gnutls_assert ();
444       return GNUTLS_E_INVALID_REQUEST;
445     }
446
447   return mpi_buf2bits (&dh->public_key);
448 }
449
450 /* CERTIFICATE STUFF */
451
452 /**
453  * gnutls_certificate_get_ours:
454  * @session: is a gnutls session
455  *
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.
459  *
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
462  *   was used.
463  **/
464 const gnutls_datum_t *
465 gnutls_certificate_get_ours (gnutls_session_t session)
466 {
467   gnutls_certificate_credentials_t cred;
468
469   CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
470
471   cred = (gnutls_certificate_credentials_t)
472     _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
473   if (cred == NULL || cred->cert_list == NULL)
474     {
475       gnutls_assert ();
476       return NULL;
477     }
478
479   if (session->internals.selected_cert_list == NULL)
480     return NULL;
481
482   return &session->internals.selected_cert_list[0].raw;
483 }
484
485 /**
486  * gnutls_certificate_get_peers:
487  * @session: is a gnutls session
488  * @list_size: is the length of the certificate list
489  *
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.
495  *
496  * In case of OpenPGP keys a single key will be returned in raw
497  * format.
498  *
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
501  *   was used.
502  **/
503 const gnutls_datum_t *
504 gnutls_certificate_get_peers (gnutls_session_t
505                               session, unsigned int *list_size)
506 {
507   cert_auth_info_t info;
508
509   CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
510
511   info = _gnutls_get_auth_info (session);
512   if (info == NULL)
513     return NULL;
514
515   *list_size = info->ncerts;
516   return info->raw_certificate_list;
517 }
518
519
520 /**
521  * gnutls_certificate_client_get_request_status:
522  * @session: is a gnutls session
523  *
524  * Get whether client certificate is requested or not.
525  *
526  * Returns: 0 if the peer (server) did not request client
527  *   authentication or 1 otherwise, or a negative value in case of
528  *   error.
529  **/
530 int
531 gnutls_certificate_client_get_request_status (gnutls_session_t session)
532 {
533   return session->key->certificate_requested;
534 }
535
536 /**
537  * gnutls_fingerprint:
538  * @algo: is a digest algorithm
539  * @data: is the data
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.
543  *
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.
547  *
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
551  * function.
552  *
553  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
554  *   an error code is returned.
555  **/
556 int
557 gnutls_fingerprint (gnutls_digest_algorithm_t algo,
558                     const gnutls_datum_t * data, void *result,
559                     size_t * result_size)
560 {
561   digest_hd_st td;
562   int hash_len = _gnutls_hash_get_algo_len (HASH2MAC (algo));
563
564   if (hash_len < 0 || (unsigned) hash_len > *result_size || result == NULL)
565     {
566       *result_size = hash_len;
567       return GNUTLS_E_SHORT_MEMORY_BUFFER;
568     }
569   *result_size = hash_len;
570
571   if (result)
572     {
573       int ret = _gnutls_hash_init (&td, HASH2MAC (algo));
574       if (ret < 0)
575         {
576           gnutls_assert ();
577           return ret;
578         }
579
580       _gnutls_hash (&td, data->data, data->size);
581
582       _gnutls_hash_deinit (&td, result);
583     }
584
585   return 0;
586 }
587
588
589 /**
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.
593  *
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.
600  *
601  **/
602 void
603 gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res,
604                                   gnutls_dh_params_t dh_params)
605 {
606   res->dh_params = dh_params;
607 }
608
609 /**
610  * gnutls_certificate_set_params_function:
611  * @res: is a gnutls_certificate_credentials_t structure
612  * @func: is the function to be called
613  *
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.
617  **/
618 void
619 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res,
620                                         gnutls_params_function * func)
621 {
622   res->params_func = func;
623 }
624
625
626 /**
627  * gnutls_certificate_set_verify_flags:
628  * @res: is a gnutls_certificate_credentials_t structure
629  * @flags: are the flags
630  *
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.
634  *
635  **/
636 void
637 gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
638                                      res, unsigned int flags)
639 {
640   res->verify_flags = flags;
641 }
642
643 /**
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)
648  *
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
652  * limits.
653  **/
654 void
655 gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res,
656                                       unsigned int max_bits,
657                                       unsigned int max_depth)
658 {
659   res->verify_depth = max_depth;
660   res->verify_bits = max_bits;
661 }
662
663 /**
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.
667  *
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.
671  **/
672 void
673 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
674                                           res, gnutls_rsa_params_t rsa_params)
675 {
676   res->rsa_params = rsa_params;
677 }
678
679 /**
680  * gnutls_psk_set_params_function:
681  * @res: is a gnutls_psk_server_credentials_t structure
682  * @func: is the function to be called
683  *
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.
687  **/
688 void
689 gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res,
690                                 gnutls_params_function * func)
691 {
692   res->params_func = func;
693 }
694
695 /**
696  * gnutls_anon_set_params_function:
697  * @res: is a gnutls_anon_server_credentials_t structure
698  * @func: is the function to be called
699  *
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.
703  **/
704 void
705 gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
706                                  gnutls_params_function * func)
707 {
708   res->params_func = func;
709 }