updated doc
[gnutls.git] / lib / gnutls_sig.c
bloba2f38e564b36cc97e96dd32ef9b1341bbaacdb0f
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 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>
43 #include <x509/common.h>
45 static int
46 sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
47 gnutls_cert * cert, gnutls_privkey_t pkey,
48 const gnutls_datum_t * hash_concat,
49 gnutls_datum_t * signature);
51 /* While this is currently equal to the length of RSA/SHA512
52 * signature, it should also be sufficient for DSS signature and any
53 * other RSA signatures including one with the old MD5/SHA1-combined
54 * format.
56 #define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
58 /* Generates a signature of all the random data and the parameters.
59 * Used in DHE_* ciphersuites.
61 int
62 _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
63 gnutls_privkey_t pkey, gnutls_datum_t * params,
64 gnutls_datum_t * signature,
65 gnutls_sign_algorithm_t * sign_algo)
67 gnutls_datum_t dconcat;
68 int ret;
69 digest_hd_st td_sha;
70 opaque concat[MAX_SIG_SIZE];
71 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
72 gnutls_digest_algorithm_t hash_algo;
74 *sign_algo =
75 _gnutls_session_get_sign_algo (session, cert);
76 if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
78 gnutls_assert ();
79 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
82 hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);
84 _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
85 session, gnutls_sign_algorithm_get_name (*sign_algo));
87 ret = _gnutls_hash_init (&td_sha, hash_algo);
88 if (ret < 0)
90 gnutls_assert ();
91 return ret;
94 _gnutls_hash (&td_sha, session->security_parameters.client_random,
95 GNUTLS_RANDOM_SIZE);
96 _gnutls_hash (&td_sha, session->security_parameters.server_random,
97 GNUTLS_RANDOM_SIZE);
98 _gnutls_hash (&td_sha, params->data, params->size);
100 switch (cert->subject_pk_algorithm)
102 case GNUTLS_PK_RSA:
103 if (!_gnutls_version_has_selectable_sighash (ver))
105 digest_hd_st td_md5;
107 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
108 if (ret < 0)
110 gnutls_assert ();
111 return ret;
114 _gnutls_hash (&td_md5, session->security_parameters.client_random,
115 GNUTLS_RANDOM_SIZE);
116 _gnutls_hash (&td_md5, session->security_parameters.server_random,
117 GNUTLS_RANDOM_SIZE);
118 _gnutls_hash (&td_md5, params->data, params->size);
120 _gnutls_hash_deinit (&td_md5, concat);
121 _gnutls_hash_deinit (&td_sha, &concat[16]);
123 dconcat.data = concat;
124 dconcat.size = 36;
126 else
127 { /* TLS 1.2 way */
129 _gnutls_hash_deinit (&td_sha, concat);
131 dconcat.data = concat;
132 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
134 break;
135 case GNUTLS_PK_DSA:
136 _gnutls_hash_deinit (&td_sha, concat);
138 if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
139 && (hash_algo != GNUTLS_DIG_SHA256))
141 gnutls_assert ();
142 return GNUTLS_E_INTERNAL_ERROR;
144 dconcat.data = concat;
145 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
146 break;
148 default:
149 gnutls_assert ();
150 _gnutls_hash_deinit (&td_sha, NULL);
151 return GNUTLS_E_INTERNAL_ERROR;
154 ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
155 if (ret < 0)
157 gnutls_assert ();
160 return ret;
165 /* This will create a PKCS1 or DSA signature, using the given parameters, and the
166 * given data. The output will be allocated and be put in signature.
169 _gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
170 int params_size, const gnutls_datum_t * data,
171 gnutls_datum_t * signature)
173 int ret;
175 switch (algo)
177 case GNUTLS_PK_RSA:
178 /* encrypt */
179 if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params,
180 params_size, 1)) < 0)
182 gnutls_assert ();
183 return ret;
186 break;
187 case GNUTLS_PK_DSA:
188 /* sign */
189 if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0)
191 gnutls_assert ();
192 return ret;
194 break;
195 default:
196 gnutls_assert ();
197 return GNUTLS_E_INTERNAL_ERROR;
198 break;
201 return 0;
204 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
205 * Cert is the certificate of the corresponding private key. It is only checked if
206 * it supports signing.
208 static int
209 sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
210 gnutls_cert * cert, gnutls_privkey_t pkey,
211 const gnutls_datum_t * hash_concat,
212 gnutls_datum_t * signature)
214 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
216 /* If our certificate supports signing
219 if (cert != NULL)
221 if (cert->key_usage != 0)
222 if (!(cert->key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
224 gnutls_assert ();
225 _gnutls_debug_log("Key usage violation was detected (ignored).\n");
228 /* External signing. */
229 if (!pkey)
231 int ret;
233 if (!session->internals.sign_func)
234 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
236 if (!_gnutls_version_has_selectable_sighash (ver))
237 return (*session->internals.sign_func)
238 (session, session->internals.sign_func_userdata,
239 cert->cert_type, &cert->raw, hash_concat, signature);
240 else
242 gnutls_datum_t digest;
244 ret = _gnutls_set_datum(&digest, hash_concat->data, hash_concat->size);
245 if (ret < 0)
246 return gnutls_assert_val(ret);
248 ret = pk_prepare_hash (gnutls_privkey_get_pk_algorithm(pkey, NULL), hash_algo, &digest);
249 if (ret < 0)
251 gnutls_assert ();
252 goto es_cleanup;
255 ret = (*session->internals.sign_func)
256 (session, session->internals.sign_func_userdata,
257 cert->cert_type, &cert->raw, &digest, signature);
258 es_cleanup:
259 gnutls_free(digest.data);
261 return ret;
266 if (!_gnutls_version_has_selectable_sighash (ver))
267 return _gnutls_privkey_sign_hash (pkey, hash_concat, signature);
268 else
269 return gnutls_privkey_sign_hash (pkey, hash_algo, 0, hash_concat, signature);
272 static int
273 verify_tls_hash (gnutls_session_t session, gnutls_protocol_t ver, gnutls_cert * cert,
274 const gnutls_datum_t * hash_concat,
275 gnutls_datum_t * signature, size_t sha1pos,
276 gnutls_pk_algorithm_t pk_algo)
278 int ret;
279 gnutls_datum_t vdata;
281 if (cert == NULL || cert->version == 0)
282 { /* this is the only way to check
283 * if it is initialized
285 gnutls_assert ();
286 return GNUTLS_E_CERTIFICATE_ERROR;
289 /* If the certificate supports signing continue.
291 if (cert->key_usage != 0)
292 if (!(cert->key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
294 gnutls_assert ();
295 _gnutls_debug_log("Key usage violation was detected (ignored).\n");
298 if (pk_algo == GNUTLS_PK_UNKNOWN)
299 pk_algo = cert->subject_pk_algorithm;
300 switch (pk_algo)
302 case GNUTLS_PK_RSA:
304 vdata.data = hash_concat->data;
305 vdata.size = hash_concat->size;
307 /* verify signature */
308 if (!_gnutls_version_has_selectable_sighash (ver))
309 ret = _gnutls_rsa_verify (&vdata, signature, cert->params,
310 cert->params_size, 1);
311 else
312 ret = pubkey_verify_sig( NULL, &vdata, signature, pk_algo,
313 cert->params, cert->params_size);
315 if (ret < 0)
317 gnutls_assert ();
318 return ret;
321 break;
322 case GNUTLS_PK_DSA:
324 vdata.data = &hash_concat->data[sha1pos];
325 vdata.size = hash_concat->size - sha1pos;
327 ret = pubkey_verify_sig( NULL, &vdata, signature, pk_algo,
328 cert->params, cert->params_size);
329 /* verify signature */
330 if (ret < 0)
332 gnutls_assert ();
333 return ret;
336 break;
337 default:
338 gnutls_assert ();
339 return GNUTLS_E_INTERNAL_ERROR;
344 return 0;
348 /* Generates a signature of all the random data and the parameters.
349 * Used in DHE_* ciphersuites.
352 _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
353 const gnutls_datum_t * params,
354 gnutls_datum_t * signature,
355 gnutls_sign_algorithm_t algo)
357 gnutls_datum_t dconcat;
358 int ret;
359 digest_hd_st td_md5;
360 digest_hd_st td_sha;
361 opaque concat[MAX_SIG_SIZE];
362 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
363 gnutls_digest_algorithm_t hash_algo;
365 if (_gnutls_version_has_selectable_sighash (ver))
367 _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
368 session, gnutls_sign_algorithm_get_name (algo));
370 ret = cert_compatible_with_sig(cert, ver, algo);
371 if (ret < 0)
372 return gnutls_assert_val(ret);
374 ret = _gnutls_session_sign_algo_enabled (session, algo);
375 if (ret < 0)
376 return gnutls_assert_val(ret);
378 hash_algo = _gnutls_sign_get_hash_algorithm (algo);
380 else
382 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
383 if (ret < 0)
385 gnutls_assert ();
386 return ret;
389 _gnutls_hash (&td_md5, session->security_parameters.client_random,
390 GNUTLS_RANDOM_SIZE);
391 _gnutls_hash (&td_md5, session->security_parameters.server_random,
392 GNUTLS_RANDOM_SIZE);
393 _gnutls_hash (&td_md5, params->data, params->size);
395 hash_algo = GNUTLS_DIG_SHA1;
398 ret = _gnutls_hash_init (&td_sha, hash_algo);
399 if (ret < 0)
401 gnutls_assert ();
402 if (!_gnutls_version_has_selectable_sighash (ver))
403 _gnutls_hash_deinit (&td_md5, NULL);
404 return ret;
407 _gnutls_hash (&td_sha, session->security_parameters.client_random,
408 GNUTLS_RANDOM_SIZE);
409 _gnutls_hash (&td_sha, session->security_parameters.server_random,
410 GNUTLS_RANDOM_SIZE);
411 _gnutls_hash (&td_sha, params->data, params->size);
413 if (!_gnutls_version_has_selectable_sighash (ver))
415 _gnutls_hash_deinit (&td_md5, concat);
416 _gnutls_hash_deinit (&td_sha, &concat[16]);
417 dconcat.data = concat;
418 dconcat.size = 36;
420 else
422 _gnutls_hash_deinit (&td_sha, concat);
424 dconcat.data = concat;
425 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
428 ret = verify_tls_hash (session, ver, cert, &dconcat, signature,
429 dconcat.size -
430 _gnutls_hash_get_algo_len (hash_algo),
431 _gnutls_sign_get_pk_algorithm (algo));
432 if (ret < 0)
434 gnutls_assert ();
435 return ret;
438 return ret;
442 /* Client certificate verify calculations
445 /* this is _gnutls_handshake_verify_cert_vrfy for TLS 1.2
447 static int
448 _gnutls_handshake_verify_cert_vrfy12 (gnutls_session_t session,
449 gnutls_cert * cert,
450 gnutls_datum_t * signature,
451 gnutls_sign_algorithm_t sign_algo)
453 int ret;
454 opaque concat[MAX_SIG_SIZE];
455 digest_hd_st td;
456 gnutls_datum_t dconcat;
457 gnutls_sign_algorithm_t _sign_algo;
458 gnutls_digest_algorithm_t hash_algo;
459 digest_hd_st *handshake_td;
460 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
462 handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
463 hash_algo = handshake_td->algorithm;
464 _sign_algo =
465 _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
467 if (_sign_algo != sign_algo)
469 handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
470 hash_algo = handshake_td->algorithm;
471 _sign_algo =
472 _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
473 if (sign_algo != _sign_algo)
475 gnutls_assert ();
476 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
480 ret = _gnutls_hash_copy (&td, handshake_td);
481 if (ret < 0)
483 gnutls_assert ();
484 return GNUTLS_E_HASH_FAILED;
487 _gnutls_hash_deinit (&td, concat);
489 dconcat.data = concat;
490 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
492 ret =
493 verify_tls_hash (session, ver, cert, &dconcat, signature, 0,
494 cert->subject_pk_algorithm);
495 if (ret < 0)
497 gnutls_assert ();
498 return ret;
501 return ret;
505 /* Verifies a TLS signature (like the one in the client certificate
506 * verify message).
509 _gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
510 gnutls_cert * cert,
511 gnutls_datum_t * signature,
512 gnutls_sign_algorithm_t sign_algo)
514 int ret;
515 opaque concat[MAX_SIG_SIZE];
516 digest_hd_st td_md5;
517 digest_hd_st td_sha;
518 gnutls_datum_t dconcat;
519 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
521 _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
522 session, gnutls_sign_algorithm_get_name (sign_algo));
524 if (session->security_parameters.handshake_mac_handle_type ==
525 HANDSHAKE_MAC_TYPE_12)
527 return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
528 sign_algo);
530 else if (session->security_parameters.handshake_mac_handle_type !=
531 HANDSHAKE_MAC_TYPE_10)
533 gnutls_assert ();
534 return GNUTLS_E_INTERNAL_ERROR;
537 ret =
538 _gnutls_hash_copy (&td_md5,
539 &session->internals.handshake_mac_handle.tls10.md5);
540 if (ret < 0)
542 gnutls_assert ();
543 return ret;
546 ret =
547 _gnutls_hash_copy (&td_sha,
548 &session->internals.handshake_mac_handle.tls10.sha);
549 if (ret < 0)
551 gnutls_assert ();
552 _gnutls_hash_deinit (&td_md5, NULL);
553 return GNUTLS_E_HASH_FAILED;
556 if (ver == GNUTLS_SSL3)
558 ret = _gnutls_generate_master (session, 1);
559 if (ret < 0)
561 gnutls_assert ();
562 return ret;
565 _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
566 session->
567 security_parameters.master_secret,
568 GNUTLS_MASTER_SIZE);
569 _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
570 session->
571 security_parameters.master_secret,
572 GNUTLS_MASTER_SIZE);
574 else
576 _gnutls_hash_deinit (&td_md5, concat);
577 _gnutls_hash_deinit (&td_sha, &concat[16]);
580 dconcat.data = concat;
581 dconcat.size = 20 + 16; /* md5+ sha */
583 ret =
584 verify_tls_hash (session, ver, cert, &dconcat, signature, 16,
585 cert->subject_pk_algorithm);
586 if (ret < 0)
588 gnutls_assert ();
589 return ret;
592 return ret;
596 /* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
598 static int
599 _gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
600 gnutls_cert * cert, gnutls_privkey_t pkey,
601 gnutls_datum_t * signature)
603 gnutls_datum_t dconcat;
604 int ret;
605 opaque concat[MAX_SIG_SIZE];
606 digest_hd_st td;
607 gnutls_sign_algorithm_t sign_algo;
608 gnutls_digest_algorithm_t hash_algo;
609 digest_hd_st *handshake_td;
611 sign_algo =
612 _gnutls_session_get_sign_algo (session, cert);
613 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
615 gnutls_assert ();
616 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
619 hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
621 _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
622 gnutls_sign_algorithm_get_name (sign_algo),
623 gnutls_mac_get_name (hash_algo));
625 if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
626 handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
627 else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
628 handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
629 else
630 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */
632 ret = _gnutls_hash_copy (&td, handshake_td);
633 if (ret < 0)
635 gnutls_assert ();
636 return ret;
639 _gnutls_hash_deinit (&td, concat);
641 dconcat.data = concat;
642 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
644 ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
645 if (ret < 0)
647 gnutls_assert ();
648 return ret;
651 return sign_algo;
655 /* Generates a signature of all the previous sent packets in the
656 * handshake procedure.
657 * 20040227: now it works for SSL 3.0 as well
658 * 20091031: works for TLS 1.2 too!
660 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
661 * For TLS1.2 returns the signature algorithm used on success, or a negative value;
664 _gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
665 gnutls_cert * cert, gnutls_privkey_t pkey,
666 gnutls_datum_t * signature)
668 gnutls_datum_t dconcat;
669 int ret, hash_algo;
670 opaque concat[MAX_SIG_SIZE];
671 digest_hd_st td_md5;
672 digest_hd_st td_sha;
673 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
675 if (session->security_parameters.handshake_mac_handle_type ==
676 HANDSHAKE_MAC_TYPE_12)
678 return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
679 signature);
681 else if (session->security_parameters.handshake_mac_handle_type !=
682 HANDSHAKE_MAC_TYPE_10)
684 gnutls_assert ();
685 return GNUTLS_E_INTERNAL_ERROR;
688 ret =
689 _gnutls_hash_copy (&td_sha,
690 &session->internals.handshake_mac_handle.tls10.sha);
691 if (ret < 0)
693 gnutls_assert ();
694 return ret;
697 if (ver == GNUTLS_SSL3)
699 ret = _gnutls_generate_master (session, 1);
700 if (ret < 0)
702 gnutls_assert ();
703 return ret;
706 _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
707 session->
708 security_parameters.master_secret,
709 GNUTLS_MASTER_SIZE);
711 else
712 _gnutls_hash_deinit (&td_sha, &concat[16]);
714 switch (cert->subject_pk_algorithm)
716 case GNUTLS_PK_RSA:
717 ret =
718 _gnutls_hash_copy (&td_md5,
719 &session->internals.handshake_mac_handle.tls10.
720 md5);
721 if (ret < 0)
723 gnutls_assert ();
724 return ret;
727 if (ver == GNUTLS_SSL3)
728 _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
729 session->
730 security_parameters.master_secret,
731 GNUTLS_MASTER_SIZE);
732 else
733 _gnutls_hash_deinit (&td_md5, concat);
735 dconcat.data = concat;
736 dconcat.size = 36;
737 break;
738 case GNUTLS_PK_DSA:
739 /* ensure 1024 bit DSA keys are used */
740 hash_algo = _gnutls_dsa_q_to_hash (cert->params[1], NULL);
741 if (!_gnutls_version_has_selectable_sighash (ver) && hash_algo != GNUTLS_DIG_SHA1)
742 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
744 dconcat.data = &concat[16];
745 dconcat.size = 20;
746 break;
748 default:
749 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
751 ret = sign_tls_hash (session, GNUTLS_DIG_NULL, cert, pkey, &dconcat, signature);
752 if (ret < 0)
754 gnutls_assert ();
757 return ret;
761 pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
762 bigint_t * params,
763 const gnutls_datum_t * data, gnutls_datum_t * digest)
765 int ret;
767 digest->size = _gnutls_hash_get_algo_len (hash);
768 digest->data = gnutls_malloc (digest->size);
769 if (digest->data == NULL)
771 gnutls_assert ();
772 return GNUTLS_E_MEMORY_ERROR;
775 ret = _gnutls_hash_fast (hash, data->data, data->size, digest->data);
776 if (ret < 0)
778 gnutls_assert ();
779 goto cleanup;
782 return 0;
784 cleanup:
785 gnutls_free (digest->data);
786 return ret;
789 /* Writes the digest information and the digest in a DER encoded
790 * structure. The digest info is allocated and stored into the info structure.
792 static int
793 encode_ber_digest_info (gnutls_digest_algorithm_t hash,
794 const gnutls_datum_t * digest,
795 gnutls_datum_t * output)
797 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
798 int result;
799 const char *algo;
800 opaque *tmp_output;
801 int tmp_output_size;
803 algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
804 if (algo == NULL)
806 gnutls_assert ();
807 _gnutls_x509_log ("Hash algorithm: %d\n", hash);
808 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
811 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
812 "GNUTLS.DigestInfo",
813 &dinfo)) != ASN1_SUCCESS)
815 gnutls_assert ();
816 return _gnutls_asn2err (result);
819 result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
820 if (result != ASN1_SUCCESS)
822 gnutls_assert ();
823 asn1_delete_structure (&dinfo);
824 return _gnutls_asn2err (result);
827 /* Write an ASN.1 NULL in the parameters field. This matches RFC
828 3279 and RFC 4055, although is arguable incorrect from a historic
829 perspective (see those documents for more information).
830 Regardless of what is correct, this appears to be what most
831 implementations do. */
832 result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
833 ASN1_NULL, ASN1_NULL_SIZE);
834 if (result != ASN1_SUCCESS)
836 gnutls_assert ();
837 asn1_delete_structure (&dinfo);
838 return _gnutls_asn2err (result);
841 result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
842 if (result != ASN1_SUCCESS)
844 gnutls_assert ();
845 asn1_delete_structure (&dinfo);
846 return _gnutls_asn2err (result);
849 tmp_output_size = 0;
850 asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
852 tmp_output = gnutls_malloc (tmp_output_size);
853 if (output->data == NULL)
855 gnutls_assert ();
856 asn1_delete_structure (&dinfo);
857 return GNUTLS_E_MEMORY_ERROR;
860 result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
861 if (result != ASN1_SUCCESS)
863 gnutls_assert ();
864 asn1_delete_structure (&dinfo);
865 return _gnutls_asn2err (result);
868 asn1_delete_structure (&dinfo);
870 output->size = tmp_output_size;
871 output->data = tmp_output;
873 return 0;
877 * This function will do RSA PKCS #1 1.5 encoding
878 * on the given digest. The given digest must be allocated
879 * and will be freed if replacement is required.
882 pk_prepare_hash (gnutls_pk_algorithm_t pk,
883 gnutls_digest_algorithm_t hash, gnutls_datum_t * digest)
885 int ret;
886 gnutls_datum old_digest = { digest->data, digest->size };
888 switch (pk)
890 case GNUTLS_PK_RSA:
891 /* Encode the digest as a DigestInfo
893 if ((ret = encode_ber_digest_info (hash, &old_digest, digest)) != 0)
895 gnutls_assert ();
896 return ret;
899 _gnutls_free_datum (&old_digest);
900 break;
901 case GNUTLS_PK_DSA:
902 break;
903 default:
904 gnutls_assert ();
905 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
908 return 0;