Use libtasn1 v2.4.
[gnutls.git] / lib / gnutls_sig.c
blob0c78bf359b5b37c7d73c9aa163f1135983b4126b
1 /*
2 * Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library 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,
22 * USA
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <x509_b64.h>
29 #include <auth_cert.h>
30 #include <gnutls_algorithms.h>
31 #include <gnutls_cert.h>
32 #include <gnutls_datum.h>
33 #include <gnutls_mpi.h>
34 #include <gnutls_global.h>
35 #include <gnutls_pk.h>
36 #include <debug.h>
37 #include <gnutls_buffers.h>
38 #include <gnutls_sig.h>
39 #include <gnutls_kx.h>
40 #include <libtasn1.h>
41 #include <ext_signature.h>
42 #include <gnutls_state.h>
44 static int
45 _gnutls_tls_sign (gnutls_session_t session,
46 gnutls_cert * cert, gnutls_privkey * pkey,
47 const gnutls_datum_t * hash_concat,
48 gnutls_datum_t * signature);
50 /* While this is currently equal to the length of RSA/SHA512
51 * signature, it should also be sufficient for DSS signature and any
52 * other RSA signatures including one with the old MD5/SHA1-combined
53 * format.
55 #define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
57 /* Create a DER-encoded value as a opaque signature when RSA is used.
58 * See RFC 5246 DigitallySigned for the actual format.
60 static int
61 _gnutls_rsa_encode_sig (gnutls_mac_algorithm_t algo,
62 const gnutls_datum_t * hash,
63 gnutls_datum_t * signature)
65 ASN1_TYPE di;
66 const char *oid;
67 int result, signature_size;
69 oid = _gnutls_x509_mac_to_oid (algo);
70 if (!oid)
72 gnutls_assert ();
73 return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
76 if ((result = asn1_create_element
77 (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &di)) != ASN1_SUCCESS)
79 gnutls_assert ();
80 return _gnutls_asn2err (result);
83 if ((result = asn1_write_value (di, "digestAlgorithm.algorithm",
84 oid, strlen (oid))) != ASN1_SUCCESS)
86 gnutls_assert ();
87 asn1_delete_structure (&di);
88 return _gnutls_asn2err (result);
91 /* Use NULL parameters. */
92 if ((result = asn1_write_value (di, "digestAlgorithm.parameters",
93 "\x05\x00", 2)) != ASN1_SUCCESS)
95 gnutls_assert ();
96 asn1_delete_structure (&di);
97 return _gnutls_asn2err (result);
100 if ((result = asn1_write_value (di, "digest",
101 hash->data, hash->size)) != ASN1_SUCCESS)
103 gnutls_assert ();
104 asn1_delete_structure (&di);
105 return _gnutls_asn2err (result);
108 signature_size = signature->size;
109 result = asn1_der_coding (di, "", signature->data, &signature_size, NULL);
110 asn1_delete_structure (&di);
112 if (result != ASN1_SUCCESS)
114 gnutls_assert ();
115 return _gnutls_asn2err (result);
118 signature->size = signature_size;
120 return 0;
125 /* Generates a signature of all the random data and the parameters.
126 * Used in DHE_* ciphersuites.
129 _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
130 gnutls_privkey * pkey, gnutls_datum_t * params,
131 gnutls_datum_t * signature,
132 gnutls_sign_algorithm_t * sign_algo)
134 gnutls_datum_t dconcat;
135 int ret;
136 digest_hd_st td_sha;
137 opaque concat[MAX_SIG_SIZE];
138 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
139 gnutls_digest_algorithm_t hash_algo;
141 *sign_algo =
142 _gnutls_session_get_sign_algo (session, cert->subject_pk_algorithm,
143 &hash_algo);
144 if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
146 gnutls_assert ();
147 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
150 ret = _gnutls_hash_init (&td_sha, hash_algo);
151 if (ret < 0)
153 gnutls_assert ();
154 return ret;
157 _gnutls_hash (&td_sha, session->security_parameters.client_random,
158 GNUTLS_RANDOM_SIZE);
159 _gnutls_hash (&td_sha, session->security_parameters.server_random,
160 GNUTLS_RANDOM_SIZE);
161 _gnutls_hash (&td_sha, params->data, params->size);
163 switch (cert->subject_pk_algorithm)
165 case GNUTLS_PK_RSA:
166 if (!_gnutls_version_has_selectable_prf (ver))
168 digest_hd_st td_md5;
170 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
171 if (ret < 0)
173 gnutls_assert ();
174 return ret;
177 _gnutls_hash (&td_md5, session->security_parameters.client_random,
178 GNUTLS_RANDOM_SIZE);
179 _gnutls_hash (&td_md5, session->security_parameters.server_random,
180 GNUTLS_RANDOM_SIZE);
181 _gnutls_hash (&td_md5, params->data, params->size);
183 _gnutls_hash_deinit (&td_md5, concat);
184 _gnutls_hash_deinit (&td_sha, &concat[16]);
186 dconcat.data = concat;
187 dconcat.size = 36;
189 else
190 { /* TLS 1.2 way */
191 gnutls_datum_t hash;
193 _gnutls_hash_deinit (&td_sha, concat);
195 hash.data = concat;
196 hash.size = _gnutls_hash_get_algo_len (hash_algo);
197 dconcat.data = concat;
198 dconcat.size = sizeof concat;
200 _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
202 break;
203 case GNUTLS_PK_DSA:
204 _gnutls_hash_deinit (&td_sha, concat);
206 if (hash_algo != GNUTLS_DIG_SHA1)
208 gnutls_assert ();
209 return GNUTLS_E_INTERNAL_ERROR;
211 dconcat.data = concat;
212 dconcat.size = 20;
213 break;
215 default:
216 gnutls_assert ();
217 _gnutls_hash_deinit (&td_sha, NULL);
218 return GNUTLS_E_INTERNAL_ERROR;
220 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
221 if (ret < 0)
223 gnutls_assert ();
226 return ret;
231 /* This will create a PKCS1 or DSA signature, using the given parameters, and the
232 * given data. The output will be allocated and be put in signature.
235 _gnutls_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
236 int params_size, const gnutls_datum_t * data,
237 gnutls_datum_t * signature)
239 int ret;
241 switch (algo)
243 case GNUTLS_PK_RSA:
244 /* encrypt */
245 if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params,
246 params_size, 1)) < 0)
248 gnutls_assert ();
249 return ret;
252 break;
253 case GNUTLS_PK_DSA:
254 /* sign */
255 if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0)
257 gnutls_assert ();
258 return ret;
260 break;
261 default:
262 gnutls_assert ();
263 return GNUTLS_E_INTERNAL_ERROR;
264 break;
267 return 0;
270 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
271 * Cert is the certificate of the corresponding private key. It is only checked if
272 * it supports signing.
274 static int
275 _gnutls_tls_sign (gnutls_session_t session,
276 gnutls_cert * cert, gnutls_privkey * pkey,
277 const gnutls_datum_t * hash_concat,
278 gnutls_datum_t * signature)
281 /* If our certificate supports signing
284 if (cert != NULL)
286 if (cert->key_usage != 0)
287 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
289 gnutls_assert ();
290 return GNUTLS_E_KEY_USAGE_VIOLATION;
293 /* External signing. */
294 if (!pkey || pkey->params_size == 0)
296 if (!session->internals.sign_func)
297 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
299 return (*session->internals.sign_func)
300 (session, session->internals.sign_func_userdata,
301 cert->cert_type, &cert->raw, hash_concat, signature);
305 return _gnutls_sign (pkey->pk_algorithm, pkey->params,
306 pkey->params_size, hash_concat, signature);
309 static int
310 _gnutls_verify_sig (gnutls_cert * cert,
311 const gnutls_datum_t * hash_concat,
312 gnutls_datum_t * signature, size_t sha1pos,
313 gnutls_pk_algorithm_t pk_algo)
315 int ret;
316 gnutls_datum_t vdata;
318 if (cert == NULL || cert->version == 0)
319 { /* this is the only way to check
320 * if it is initialized
322 gnutls_assert ();
323 return GNUTLS_E_CERTIFICATE_ERROR;
326 /* If the certificate supports signing continue.
328 if (cert->key_usage != 0)
329 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
331 gnutls_assert ();
332 return GNUTLS_E_KEY_USAGE_VIOLATION;
335 if (pk_algo == GNUTLS_PK_UNKNOWN)
336 pk_algo = cert->subject_pk_algorithm;
337 switch (pk_algo)
339 case GNUTLS_PK_RSA:
341 vdata.data = hash_concat->data;
342 vdata.size = hash_concat->size;
344 /* verify signature */
345 if ((ret = _gnutls_rsa_verify (&vdata, signature, cert->params,
346 cert->params_size, 1)) < 0)
348 gnutls_assert ();
349 return ret;
352 break;
353 case GNUTLS_PK_DSA:
355 vdata.data = &hash_concat->data[sha1pos];
356 vdata.size = hash_concat->size - sha1pos;
358 /* verify signature */
359 if ((ret = _gnutls_dsa_verify (&vdata, signature, cert->params,
360 cert->params_size)) < 0)
362 gnutls_assert ();
363 return ret;
366 break;
368 default:
369 gnutls_assert ();
370 return GNUTLS_E_INTERNAL_ERROR;
375 return 0;
379 /* Generates a signature of all the random data and the parameters.
380 * Used in DHE_* ciphersuites.
383 _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
384 const gnutls_datum_t * params,
385 gnutls_datum_t * signature,
386 gnutls_sign_algorithm_t algo)
388 gnutls_datum_t dconcat;
389 int ret;
390 digest_hd_st td_md5;
391 digest_hd_st td_sha;
392 opaque concat[MAX_SIG_SIZE];
393 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
394 gnutls_digest_algorithm_t hash_algo = GNUTLS_DIG_SHA1;
396 ret = _gnutls_session_sign_algo_enabled (session, algo);
397 if (ret < 0)
399 gnutls_assert ();
400 return ret;
403 if (!_gnutls_version_has_selectable_prf (ver))
405 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
406 if (ret < 0)
408 gnutls_assert ();
409 return ret;
412 _gnutls_hash (&td_md5, session->security_parameters.client_random,
413 GNUTLS_RANDOM_SIZE);
414 _gnutls_hash (&td_md5, session->security_parameters.server_random,
415 GNUTLS_RANDOM_SIZE);
416 _gnutls_hash (&td_md5, params->data, params->size);
419 if (algo != GNUTLS_SIGN_UNKNOWN)
420 hash_algo = _gnutls_sign_get_hash_algorithm (algo);
422 ret = _gnutls_hash_init (&td_sha, hash_algo);
423 if (ret < 0)
425 gnutls_assert ();
426 if (!_gnutls_version_has_selectable_prf (ver))
427 _gnutls_hash_deinit (&td_md5, NULL);
428 return ret;
431 _gnutls_hash (&td_sha, session->security_parameters.client_random,
432 GNUTLS_RANDOM_SIZE);
433 _gnutls_hash (&td_sha, session->security_parameters.server_random,
434 GNUTLS_RANDOM_SIZE);
435 _gnutls_hash (&td_sha, params->data, params->size);
437 if (!_gnutls_version_has_selectable_prf (ver))
439 _gnutls_hash_deinit (&td_md5, concat);
440 _gnutls_hash_deinit (&td_sha, &concat[16]);
441 dconcat.data = concat;
442 dconcat.size = 36;
444 else
446 gnutls_datum_t hash;
448 _gnutls_hash_deinit (&td_sha, concat);
450 hash.data = concat;
451 hash.size = _gnutls_hash_get_algo_len (hash_algo);
452 dconcat.data = concat;
453 dconcat.size = sizeof concat;
455 _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
458 ret = _gnutls_verify_sig (cert, &dconcat, signature,
459 dconcat.size -
460 _gnutls_hash_get_algo_len (hash_algo),
461 _gnutls_sign_get_pk_algorithm (algo));
462 if (ret < 0)
464 gnutls_assert ();
465 return ret;
468 return ret;
472 /* Client certificate verify calculations
475 /* this is _gnutls_handshake_verify_cert_vrfy for TLS 1.2
477 static int
478 _gnutls_handshake_verify_cert_vrfy12 (gnutls_session_t session,
479 gnutls_cert * cert,
480 gnutls_datum_t * signature,
481 gnutls_sign_algorithm_t sign_algo)
483 int ret;
484 opaque concat[MAX_SIG_SIZE];
485 digest_hd_st td;
486 gnutls_datum_t dconcat;
487 gnutls_sign_algorithm_t _sign_algo;
488 gnutls_digest_algorithm_t hash_algo;
489 digest_hd_st *handshake_td;
491 handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
492 hash_algo = handshake_td->algorithm;
493 _sign_algo =
494 _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
496 if (_sign_algo != sign_algo)
498 handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
499 hash_algo = handshake_td->algorithm;
500 _sign_algo =
501 _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
502 if (sign_algo != _sign_algo)
504 gnutls_assert ();
505 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
509 ret = _gnutls_hash_copy (&td, handshake_td);
510 if (ret < 0)
512 gnutls_assert ();
513 return GNUTLS_E_HASH_FAILED;
516 _gnutls_hash_deinit (&td, concat);
518 dconcat.data = concat;
519 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
521 ret =
522 _gnutls_verify_sig (cert, &dconcat, signature, 0,
523 cert->subject_pk_algorithm);
524 if (ret < 0)
526 gnutls_assert ();
527 return ret;
530 return ret;
534 /* Verifies a TLS signature (like the one in the client certificate
535 * verify message).
538 _gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
539 gnutls_cert * cert,
540 gnutls_datum_t * signature,
541 gnutls_sign_algorithm_t sign_algo)
543 int ret;
544 opaque concat[MAX_SIG_SIZE];
545 digest_hd_st td_md5;
546 digest_hd_st td_sha;
547 gnutls_datum_t dconcat;
548 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
550 if (session->security_parameters.handshake_mac_handle_type ==
551 HANDSHAKE_MAC_TYPE_12)
553 return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
554 sign_algo);
556 else if (session->security_parameters.handshake_mac_handle_type !=
557 HANDSHAKE_MAC_TYPE_10)
559 gnutls_assert ();
560 return GNUTLS_E_INTERNAL_ERROR;
563 ret =
564 _gnutls_hash_copy (&td_md5,
565 &session->internals.handshake_mac_handle.tls10.md5);
566 if (ret < 0)
568 gnutls_assert ();
569 return ret;
572 ret =
573 _gnutls_hash_copy (&td_sha,
574 &session->internals.handshake_mac_handle.tls10.sha);
575 if (ret < 0)
577 gnutls_assert ();
578 _gnutls_hash_deinit (&td_md5, NULL);
579 return GNUTLS_E_HASH_FAILED;
582 if (ver == GNUTLS_SSL3)
584 ret = _gnutls_generate_master (session, 1);
585 if (ret < 0)
587 gnutls_assert ();
588 return ret;
591 _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
592 session->security_parameters.
593 master_secret, GNUTLS_MASTER_SIZE);
594 _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
595 session->security_parameters.
596 master_secret, GNUTLS_MASTER_SIZE);
598 else
600 _gnutls_hash_deinit (&td_md5, concat);
601 _gnutls_hash_deinit (&td_sha, &concat[16]);
604 dconcat.data = concat;
605 dconcat.size = 20 + 16; /* md5+ sha */
607 ret =
608 _gnutls_verify_sig (cert, &dconcat, signature, 16,
609 cert->subject_pk_algorithm);
610 if (ret < 0)
612 gnutls_assert ();
613 return ret;
616 return ret;
620 /* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
622 static int
623 _gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
624 gnutls_cert * cert, gnutls_privkey * pkey,
625 gnutls_datum_t * signature)
627 gnutls_datum_t dconcat;
628 int ret;
629 opaque concat[MAX_SIG_SIZE];
630 digest_hd_st td;
631 gnutls_sign_algorithm_t sign_algo;
632 gnutls_digest_algorithm_t hash_algo;
633 digest_hd_st *handshake_td;
635 handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
636 hash_algo = handshake_td->algorithm;
637 sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
639 /* The idea here is to try signing with the one of the algorithms
640 * that have been initiated at handshake (SHA1, SHA256). If they
641 * are not requested by peer... tough luck
643 ret = _gnutls_session_sign_algo_requested (session, sign_algo);
644 if (sign_algo == GNUTLS_SIGN_UNKNOWN || ret < 0)
646 handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
647 hash_algo = handshake_td->algorithm;
648 sign_algo =
649 _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
650 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
652 gnutls_assert ();
653 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
656 ret = _gnutls_session_sign_algo_requested (session, sign_algo);
657 if (ret < 0)
659 gnutls_assert ();
660 _gnutls_x509_log
661 ("Server did not allow either '%s' or '%s' for signing\n",
662 gnutls_mac_get_name (hash_algo),
663 gnutls_mac_get_name (session->internals.
664 handshake_mac_handle.tls12.sha1.algorithm));
665 return ret;
669 _gnutls_x509_log ("sign handshake cert vrfy: picked %s with %s\n",
670 gnutls_sign_algorithm_get_name (sign_algo),
671 gnutls_mac_get_name (hash_algo));
673 ret = _gnutls_hash_copy (&td, handshake_td);
674 if (ret < 0)
676 gnutls_assert ();
677 return ret;
680 _gnutls_hash_deinit (&td, concat);
682 dconcat.data = concat;
683 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
685 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
686 if (ret < 0)
688 gnutls_assert ();
689 return ret;
692 return sign_algo;
695 /* Generates a signature of all the previous sent packets in the
696 * handshake procedure.
697 * 20040227: now it works for SSL 3.0 as well
698 * 20091031: works for TLS 1.2 too!
700 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
701 * For TLS1.2 returns the signature algorithm used on success, or a negative value;
704 _gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
705 gnutls_cert * cert, gnutls_privkey * pkey,
706 gnutls_datum_t * signature)
708 gnutls_datum_t dconcat;
709 int ret;
710 opaque concat[MAX_SIG_SIZE];
711 digest_hd_st td_md5;
712 digest_hd_st td_sha;
713 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
715 if (session->security_parameters.handshake_mac_handle_type ==
716 HANDSHAKE_MAC_TYPE_12)
718 return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
719 signature);
721 else if (session->security_parameters.handshake_mac_handle_type !=
722 HANDSHAKE_MAC_TYPE_10)
724 gnutls_assert ();
725 return GNUTLS_E_INTERNAL_ERROR;
728 ret =
729 _gnutls_hash_copy (&td_sha,
730 &session->internals.handshake_mac_handle.tls10.sha);
731 if (ret < 0)
733 gnutls_assert ();
734 return ret;
737 if (ver == GNUTLS_SSL3)
739 ret = _gnutls_generate_master (session, 1);
740 if (ret < 0)
742 gnutls_assert ();
743 return ret;
746 _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
747 session->security_parameters.
748 master_secret, GNUTLS_MASTER_SIZE);
750 else
751 _gnutls_hash_deinit (&td_sha, &concat[16]);
753 switch (cert->subject_pk_algorithm)
755 case GNUTLS_PK_RSA:
756 ret =
757 _gnutls_hash_copy (&td_md5,
758 &session->internals.handshake_mac_handle.
759 tls10.md5);
760 if (ret < 0)
762 gnutls_assert ();
763 return ret;
766 if (ver == GNUTLS_SSL3)
767 _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
768 session->security_parameters.
769 master_secret, GNUTLS_MASTER_SIZE);
770 else
771 _gnutls_hash_deinit (&td_md5, concat);
773 dconcat.data = concat;
774 dconcat.size = 36;
775 break;
776 case GNUTLS_PK_DSA:
777 dconcat.data = &concat[16];
778 dconcat.size = 20;
779 break;
781 default:
782 gnutls_assert ();
783 return GNUTLS_E_INTERNAL_ERROR;
785 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
786 if (ret < 0)
788 gnutls_assert ();
791 return ret;