updated makefiles
[gnutls.git] / lib / gnutls_sig.c
blob7c7b64eaeceeeadc3f6ea6d9117c220b473634f9
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 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
25 #include <x509_b64.h>
26 #include <auth/cert.h>
27 #include <algorithms.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_mpi.h>
30 #include <gnutls_global.h>
31 #include <gnutls_pk.h>
32 #include <debug.h>
33 #include <gnutls_buffers.h>
34 #include <gnutls_sig.h>
35 #include <gnutls_kx.h>
36 #include <libtasn1.h>
37 #include <ext/signature.h>
38 #include <gnutls_state.h>
39 #include <x509/common.h>
40 #include <abstract_int.h>
42 static int
43 sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
44 gnutls_pcert_st* cert, gnutls_privkey_t pkey,
45 const gnutls_datum_t * hash_concat,
46 gnutls_datum_t * signature);
48 static int
49 encode_ber_digest_info (gnutls_digest_algorithm_t hash,
50 const gnutls_datum_t * digest,
51 gnutls_datum_t * output);
53 /* While this is currently equal to the length of RSA/SHA512
54 * signature, it should also be sufficient for DSS signature and any
55 * other RSA signatures including one with the old MD5/SHA1-combined
56 * format.
58 #define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
60 /* Generates a signature of all the random data and the parameters.
61 * Used in DHE_* ciphersuites.
63 int
64 _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert,
65 gnutls_privkey_t pkey, gnutls_datum_t * params,
66 gnutls_datum_t * signature,
67 gnutls_sign_algorithm_t * sign_algo)
69 gnutls_datum_t dconcat;
70 int ret;
71 digest_hd_st td_sha;
72 uint8_t concat[MAX_SIG_SIZE];
73 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
74 gnutls_digest_algorithm_t hash_algo;
76 *sign_algo =
77 _gnutls_session_get_sign_algo (session, cert);
78 if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
80 gnutls_assert ();
81 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
84 hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);
86 _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
87 session, gnutls_sign_algorithm_get_name (*sign_algo));
89 ret = _gnutls_hash_init (&td_sha, hash_algo);
90 if (ret < 0)
92 gnutls_assert ();
93 return ret;
96 _gnutls_hash (&td_sha, session->security_parameters.client_random,
97 GNUTLS_RANDOM_SIZE);
98 _gnutls_hash (&td_sha, session->security_parameters.server_random,
99 GNUTLS_RANDOM_SIZE);
100 _gnutls_hash (&td_sha, params->data, params->size);
102 switch (gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL))
104 case GNUTLS_PK_RSA:
105 if (!_gnutls_version_has_selectable_sighash (ver))
107 digest_hd_st td_md5;
109 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
110 if (ret < 0)
112 gnutls_assert ();
113 return ret;
116 _gnutls_hash (&td_md5, session->security_parameters.client_random,
117 GNUTLS_RANDOM_SIZE);
118 _gnutls_hash (&td_md5, session->security_parameters.server_random,
119 GNUTLS_RANDOM_SIZE);
120 _gnutls_hash (&td_md5, params->data, params->size);
122 _gnutls_hash_deinit (&td_md5, concat);
123 _gnutls_hash_deinit (&td_sha, &concat[16]);
125 dconcat.data = concat;
126 dconcat.size = 36;
128 else
129 { /* TLS 1.2 way */
131 _gnutls_hash_deinit (&td_sha, concat);
133 dconcat.data = concat;
134 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
136 break;
137 case GNUTLS_PK_DSA:
138 case GNUTLS_PK_EC:
139 _gnutls_hash_deinit (&td_sha, concat);
141 if (!IS_SHA(hash_algo))
143 gnutls_assert ();
144 return GNUTLS_E_INTERNAL_ERROR;
146 dconcat.data = concat;
147 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
148 break;
150 default:
151 gnutls_assert ();
152 _gnutls_hash_deinit (&td_sha, NULL);
153 return GNUTLS_E_INTERNAL_ERROR;
156 ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
157 if (ret < 0)
159 gnutls_assert ();
162 return ret;
167 /* This will create a PKCS1 or DSA signature, using the given parameters, and the
168 * given data. The output will be allocated and be put in signature.
171 _gnutls_soft_sign (gnutls_pk_algorithm_t algo, gnutls_pk_params_st * params,
172 const gnutls_datum_t * data,
173 gnutls_datum_t * signature)
175 int ret;
177 switch (algo)
179 case GNUTLS_PK_RSA:
180 /* encrypt */
181 if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params, 1)) < 0)
183 gnutls_assert ();
184 return ret;
187 break;
188 default:
189 ret = _gnutls_pk_sign( algo, signature, data, params);
190 if (ret < 0)
192 gnutls_assert ();
193 return ret;
195 break;
198 return 0;
201 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
202 * Cert is the certificate of the corresponding private key. It is only checked if
203 * it supports signing.
205 static int
206 sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
207 gnutls_pcert_st* cert, gnutls_privkey_t pkey,
208 const gnutls_datum_t * hash_concat,
209 gnutls_datum_t * signature)
211 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
212 unsigned int key_usage = 0;
213 /* If our certificate supports signing
216 if (cert != NULL)
218 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
220 if (key_usage != 0)
221 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
223 gnutls_assert ();
224 if (session->internals.priorities.allow_key_usage_violation == 0)
225 return GNUTLS_E_KEY_USAGE_VIOLATION;
226 else
227 _gnutls_audit_log(session, "Key usage violation was detected (ignored).\n");
230 /* External signing. Deprecated. To be removed. */
231 if (!pkey)
233 int ret;
235 if (!session->internals.sign_func)
236 return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
238 if (!_gnutls_version_has_selectable_sighash (ver))
239 return (*session->internals.sign_func)
240 (session, session->internals.sign_func_userdata,
241 cert->type, &cert->cert, hash_concat, signature);
242 else
244 gnutls_datum_t digest;
246 ret = _gnutls_set_datum(&digest, hash_concat->data, hash_concat->size);
247 if (ret < 0)
248 return gnutls_assert_val(ret);
250 ret = pk_prepare_hash (gnutls_privkey_get_pk_algorithm(pkey, NULL), hash_algo, &digest);
251 if (ret < 0)
253 gnutls_assert ();
254 goto es_cleanup;
257 ret = (*session->internals.sign_func)
258 (session, session->internals.sign_func_userdata,
259 cert->type, &cert->cert, &digest, signature);
260 es_cleanup:
261 gnutls_free(digest.data);
263 return ret;
268 if (!_gnutls_version_has_selectable_sighash (ver))
269 return _gnutls_privkey_sign_hash (pkey, hash_concat, signature);
270 else
271 return gnutls_privkey_sign_hash (pkey, hash_algo, 0, hash_concat, signature);
274 static int
275 verify_tls_hash (gnutls_session_t session, gnutls_protocol_t ver, gnutls_pcert_st* cert,
276 const gnutls_datum_t * hash_concat,
277 gnutls_datum_t * signature, size_t sha1pos,
278 gnutls_sign_algorithm_t sign_algo,
279 gnutls_pk_algorithm_t pk_algo)
281 int ret;
282 gnutls_datum_t vdata;
283 unsigned int key_usage = 0, flags;
285 if (cert == NULL)
287 gnutls_assert ();
288 return GNUTLS_E_CERTIFICATE_ERROR;
291 gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
293 /* If the certificate supports signing continue.
295 if (key_usage != 0)
296 if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
298 gnutls_assert ();
299 if (session->internals.priorities.allow_key_usage_violation == 0)
300 return GNUTLS_E_KEY_USAGE_VIOLATION;
301 else
302 _gnutls_audit_log(session, "Key usage violation was detected (ignored).\n");
305 if (pk_algo == GNUTLS_PK_UNKNOWN)
306 pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
307 switch (pk_algo)
309 case GNUTLS_PK_RSA:
311 vdata.data = hash_concat->data;
312 vdata.size = hash_concat->size;
314 /* verify signature */
315 if (!_gnutls_version_has_selectable_sighash (ver))
316 flags = GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA;
317 else
318 flags = 0;
321 break;
322 case GNUTLS_PK_DSA:
323 case GNUTLS_PK_EC:
325 vdata.data = &hash_concat->data[sha1pos];
326 vdata.size = hash_concat->size - sha1pos;
328 flags = 0;
330 break;
331 default:
332 gnutls_assert ();
333 return GNUTLS_E_INTERNAL_ERROR;
336 ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo, flags,
337 &vdata, signature);
339 if (ret < 0)
340 return gnutls_assert_val(ret);
343 return 0;
347 /* Generates a signature of all the random data and the parameters.
348 * Used in DHE_* ciphersuites.
351 _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert,
352 const gnutls_datum_t * params,
353 gnutls_datum_t * signature,
354 gnutls_sign_algorithm_t sign_algo)
356 gnutls_datum_t dconcat;
357 int ret;
358 digest_hd_st td_md5;
359 digest_hd_st td_sha;
360 uint8_t concat[MAX_SIG_SIZE];
361 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
362 gnutls_digest_algorithm_t hash_algo;
364 if (_gnutls_version_has_selectable_sighash (ver))
366 _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
367 session, gnutls_sign_algorithm_get_name (sign_algo));
369 ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, sign_algo);
370 if (ret < 0)
371 return gnutls_assert_val(ret);
373 ret = _gnutls_session_sign_algo_enabled (session, sign_algo);
374 if (ret < 0)
375 return gnutls_assert_val(ret);
377 hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
379 else
381 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
382 if (ret < 0)
384 gnutls_assert ();
385 return ret;
388 _gnutls_hash (&td_md5, session->security_parameters.client_random,
389 GNUTLS_RANDOM_SIZE);
390 _gnutls_hash (&td_md5, session->security_parameters.server_random,
391 GNUTLS_RANDOM_SIZE);
392 _gnutls_hash (&td_md5, params->data, params->size);
394 hash_algo = GNUTLS_DIG_SHA1;
397 ret = _gnutls_hash_init (&td_sha, hash_algo);
398 if (ret < 0)
400 gnutls_assert ();
401 if (!_gnutls_version_has_selectable_sighash (ver))
402 _gnutls_hash_deinit (&td_md5, NULL);
403 return ret;
406 _gnutls_hash (&td_sha, session->security_parameters.client_random,
407 GNUTLS_RANDOM_SIZE);
408 _gnutls_hash (&td_sha, session->security_parameters.server_random,
409 GNUTLS_RANDOM_SIZE);
410 _gnutls_hash (&td_sha, params->data, params->size);
412 if (!_gnutls_version_has_selectable_sighash (ver))
414 _gnutls_hash_deinit (&td_md5, concat);
415 _gnutls_hash_deinit (&td_sha, &concat[16]);
416 dconcat.data = concat;
417 dconcat.size = 36;
419 else
421 _gnutls_hash_deinit (&td_sha, concat);
423 dconcat.data = concat;
424 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
427 ret = verify_tls_hash (session, ver, cert, &dconcat, signature,
428 dconcat.size -
429 _gnutls_hash_get_algo_len (hash_algo),
430 sign_algo,
431 _gnutls_sign_get_pk_algorithm (sign_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_crt_vrfy for TLS 1.2
447 static int
448 _gnutls_handshake_verify_crt_vrfy12 (gnutls_session_t session,
449 gnutls_pcert_st* cert,
450 gnutls_datum_t * signature,
451 gnutls_sign_algorithm_t sign_algo)
453 int ret;
454 uint8_t concat[MAX_HASH_SIZE];
455 gnutls_datum_t dconcat;
456 gnutls_digest_algorithm_t hash_algo;
457 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
458 gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
460 ret = _gnutls_session_sign_algo_enabled(session, sign_algo);
461 if (ret < 0)
462 return gnutls_assert_val(ret);
464 hash_algo = _gnutls_sign_get_hash_algorithm(sign_algo);
466 ret = _gnutls_hash_fast(hash_algo, session->internals.handshake_hash_buffer.data,
467 session->internals.handshake_hash_buffer_prev_len,
468 concat);
469 if (ret < 0)
470 return gnutls_assert_val(ret);
472 dconcat.data = concat;
473 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
475 ret =
476 verify_tls_hash (session, ver, cert, &dconcat, signature, 0, sign_algo, pk);
477 if (ret < 0)
479 gnutls_assert ();
480 return ret;
483 return ret;
487 /* Verifies a TLS signature (like the one in the client certificate
488 * verify message).
491 _gnutls_handshake_verify_crt_vrfy (gnutls_session_t session,
492 gnutls_pcert_st *cert,
493 gnutls_datum_t * signature,
494 gnutls_sign_algorithm_t sign_algo)
496 int ret;
497 uint8_t concat[MAX_SIG_SIZE];
498 digest_hd_st td_md5;
499 digest_hd_st td_sha;
500 gnutls_datum_t dconcat;
501 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
503 _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
504 session, gnutls_sign_algorithm_get_name (sign_algo));
507 if (_gnutls_version_has_selectable_sighash(ver))
508 return _gnutls_handshake_verify_crt_vrfy12 (session, cert, signature,
509 sign_algo);
511 ret =
512 _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
513 if (ret < 0)
515 gnutls_assert ();
516 return ret;
519 ret =
520 _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
521 if (ret < 0)
523 gnutls_assert ();
524 _gnutls_hash_deinit (&td_md5, NULL);
525 return GNUTLS_E_HASH_FAILED;
528 _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len);
529 _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len);
531 if (ver == GNUTLS_SSL3)
533 ret = _gnutls_generate_master (session, 1);
534 if (ret < 0)
536 _gnutls_hash_deinit (&td_md5, NULL);
537 _gnutls_hash_deinit (&td_sha, NULL);
538 return gnutls_assert_val(ret);
541 ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
542 session->
543 security_parameters.master_secret,
544 GNUTLS_MASTER_SIZE);
545 if (ret < 0)
547 _gnutls_hash_deinit (&td_sha, NULL);
548 return gnutls_assert_val(ret);
551 ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
552 session->
553 security_parameters.master_secret,
554 GNUTLS_MASTER_SIZE);
555 if (ret < 0)
557 return gnutls_assert_val(ret);
560 else
562 _gnutls_hash_deinit (&td_md5, concat);
563 _gnutls_hash_deinit (&td_sha, &concat[16]);
566 dconcat.data = concat;
567 dconcat.size = 20 + 16; /* md5+ sha */
569 ret =
570 verify_tls_hash (session, ver, cert, &dconcat, signature, 16,
571 GNUTLS_SIGN_UNKNOWN,
572 gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL));
573 if (ret < 0)
575 gnutls_assert ();
576 return ret;
579 return ret;
583 /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2
585 static int
586 _gnutls_handshake_sign_crt_vrfy12 (gnutls_session_t session,
587 gnutls_pcert_st* cert, gnutls_privkey_t pkey,
588 gnutls_datum_t * signature)
590 gnutls_datum_t dconcat;
591 int ret;
592 uint8_t concat[MAX_SIG_SIZE];
593 gnutls_sign_algorithm_t sign_algo;
594 gnutls_digest_algorithm_t hash_algo;
596 sign_algo =
597 _gnutls_session_get_sign_algo (session, cert);
598 if (sign_algo == GNUTLS_SIGN_UNKNOWN)
600 gnutls_assert ();
601 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
604 hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
606 _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
607 gnutls_sign_algorithm_get_name (sign_algo),
608 gnutls_mac_get_name ((gnutls_mac_algorithm_t)hash_algo));
610 ret = _gnutls_hash_fast (hash_algo, session->internals.handshake_hash_buffer.data,
611 session->internals.handshake_hash_buffer.length,
612 concat);
613 if (ret < 0)
614 return gnutls_assert_val(ret);
616 dconcat.data = concat;
617 dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
619 ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
620 if (ret < 0)
622 gnutls_assert ();
623 return ret;
626 return sign_algo;
630 /* Generates a signature of all the previous sent packets in the
631 * handshake procedure.
632 * 20040227: now it works for SSL 3.0 as well
633 * 20091031: works for TLS 1.2 too!
635 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
636 * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
639 _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session,
640 gnutls_pcert_st* cert, gnutls_privkey_t pkey,
641 gnutls_datum_t * signature)
643 gnutls_datum_t dconcat;
644 int ret;
645 uint8_t concat[MAX_SIG_SIZE];
646 digest_hd_st td_md5;
647 digest_hd_st td_sha;
648 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
649 gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
651 if (_gnutls_version_has_selectable_sighash(ver))
652 return _gnutls_handshake_sign_crt_vrfy12 (session, cert, pkey,
653 signature);
655 ret =
656 _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
657 if (ret < 0)
659 gnutls_assert ();
660 return ret;
663 _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length);
665 if (ver == GNUTLS_SSL3)
667 ret = _gnutls_generate_master (session, 1);
668 if (ret < 0)
670 gnutls_assert ();
671 _gnutls_hash_deinit (&td_sha, NULL);
672 return ret;
675 ret = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
676 session->
677 security_parameters.master_secret,
678 GNUTLS_MASTER_SIZE);
679 if (ret < 0)
680 return gnutls_assert_val(ret);
682 else
683 _gnutls_hash_deinit (&td_sha, &concat[16]);
685 /* ensure 1024 bit DSA keys are used */
686 ret = _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver, GNUTLS_SIGN_UNKNOWN);
687 if (ret < 0)
688 return gnutls_assert_val(ret);
690 switch (pk)
692 case GNUTLS_PK_RSA:
693 ret =
694 _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
695 if (ret < 0)
696 return gnutls_assert_val(ret);
698 _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length);
700 if (ver == GNUTLS_SSL3)
702 ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
703 session->
704 security_parameters.master_secret,
705 GNUTLS_MASTER_SIZE);
706 if (ret < 0)
707 return gnutls_assert_val(ret);
709 else
710 _gnutls_hash_deinit (&td_md5, concat);
712 dconcat.data = concat;
713 dconcat.size = 36;
714 break;
715 case GNUTLS_PK_DSA:
716 case GNUTLS_PK_EC:
718 dconcat.data = &concat[16];
719 dconcat.size = 20;
720 break;
722 default:
723 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
725 ret = sign_tls_hash (session, GNUTLS_DIG_NULL, cert, pkey, &dconcat, signature);
726 if (ret < 0)
728 gnutls_assert ();
731 return ret;
735 pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
736 gnutls_pk_params_st* params,
737 const gnutls_datum_t * data, gnutls_datum_t * digest)
739 int ret;
741 digest->size = _gnutls_hash_get_algo_len (hash);
742 digest->data = gnutls_malloc (digest->size);
743 if (digest->data == NULL)
745 gnutls_assert ();
746 return GNUTLS_E_MEMORY_ERROR;
749 ret = _gnutls_hash_fast (hash, data->data, data->size, digest->data);
750 if (ret < 0)
752 gnutls_assert ();
753 goto cleanup;
756 return 0;
758 cleanup:
759 gnutls_free (digest->data);
760 return ret;
765 * This function will do RSA PKCS #1 1.5 encoding
766 * on the given digest. The given digest must be allocated
767 * and will be freed if replacement is required.
770 pk_prepare_hash (gnutls_pk_algorithm_t pk,
771 gnutls_digest_algorithm_t hash, gnutls_datum_t * digest)
773 int ret;
774 gnutls_datum_t old_digest = { digest->data, digest->size };
776 switch (pk)
778 case GNUTLS_PK_RSA:
779 /* Encode the digest as a DigestInfo
781 if ((ret = encode_ber_digest_info (hash, &old_digest, digest)) != 0)
783 gnutls_assert ();
784 return ret;
787 _gnutls_free_datum (&old_digest);
788 break;
789 case GNUTLS_PK_DSA:
790 case GNUTLS_PK_EC:
791 break;
792 default:
793 gnutls_assert ();
794 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
797 return 0;
800 /* Reads the digest information.
801 * we use DER here, although we should use BER. It works fine
802 * anyway.
805 decode_ber_digest_info (const gnutls_datum_t * info,
806 gnutls_digest_algorithm_t * hash,
807 uint8_t * digest, unsigned int *digest_size)
809 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
810 int result;
811 char str[1024];
812 int len;
814 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
815 "GNUTLS.DigestInfo",
816 &dinfo)) != ASN1_SUCCESS)
818 gnutls_assert ();
819 return _gnutls_asn2err (result);
822 result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
823 if (result != ASN1_SUCCESS)
825 gnutls_assert ();
826 asn1_delete_structure (&dinfo);
827 return _gnutls_asn2err (result);
830 len = sizeof (str) - 1;
831 result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
832 if (result != ASN1_SUCCESS)
834 gnutls_assert ();
835 asn1_delete_structure (&dinfo);
836 return _gnutls_asn2err (result);
839 *hash = _gnutls_x509_oid_to_digest (str);
841 if (*hash == GNUTLS_DIG_UNKNOWN)
844 _gnutls_debug_log ("verify.c: HASH OID: %s\n", str);
846 gnutls_assert ();
847 asn1_delete_structure (&dinfo);
848 return GNUTLS_E_UNKNOWN_ALGORITHM;
851 len = sizeof (str) - 1;
852 result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
853 /* To avoid permitting garbage in the parameters field, either the
854 parameters field is not present, or it contains 0x05 0x00. */
855 if (!(result == ASN1_ELEMENT_NOT_FOUND ||
856 (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
857 memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
859 gnutls_assert ();
860 asn1_delete_structure (&dinfo);
861 return GNUTLS_E_ASN1_GENERIC_ERROR;
864 len = *digest_size;
865 result = asn1_read_value (dinfo, "digest", digest, &len);
867 if (result != ASN1_SUCCESS)
869 gnutls_assert ();
870 *digest_size = len;
871 asn1_delete_structure (&dinfo);
872 return _gnutls_asn2err (result);
875 *digest_size = len;
876 asn1_delete_structure (&dinfo);
878 return 0;
881 /* Writes the digest information and the digest in a DER encoded
882 * structure. The digest info is allocated and stored into the info structure.
884 static int
885 encode_ber_digest_info (gnutls_digest_algorithm_t hash,
886 const gnutls_datum_t * digest,
887 gnutls_datum_t * output)
889 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
890 int result;
891 const char *algo;
892 uint8_t *tmp_output;
893 int tmp_output_size;
895 algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
896 if (algo == NULL)
898 gnutls_assert ();
899 _gnutls_debug_log ("Hash algorithm: %d has no OID\n", hash);
900 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
903 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
904 "GNUTLS.DigestInfo",
905 &dinfo)) != ASN1_SUCCESS)
907 gnutls_assert ();
908 return _gnutls_asn2err (result);
911 result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
912 if (result != ASN1_SUCCESS)
914 gnutls_assert ();
915 asn1_delete_structure (&dinfo);
916 return _gnutls_asn2err (result);
919 /* Write an ASN.1 NULL in the parameters field. This matches RFC
920 3279 and RFC 4055, although is arguable incorrect from a historic
921 perspective (see those documents for more information).
922 Regardless of what is correct, this appears to be what most
923 implementations do. */
924 result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
925 ASN1_NULL, ASN1_NULL_SIZE);
926 if (result != ASN1_SUCCESS)
928 gnutls_assert ();
929 asn1_delete_structure (&dinfo);
930 return _gnutls_asn2err (result);
933 result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
934 if (result != ASN1_SUCCESS)
936 gnutls_assert ();
937 asn1_delete_structure (&dinfo);
938 return _gnutls_asn2err (result);
941 tmp_output_size = 0;
942 asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
944 tmp_output = gnutls_malloc (tmp_output_size);
945 if (tmp_output == NULL)
947 gnutls_assert ();
948 asn1_delete_structure (&dinfo);
949 return GNUTLS_E_MEMORY_ERROR;
952 result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
953 if (result != ASN1_SUCCESS)
955 gnutls_assert ();
956 asn1_delete_structure (&dinfo);
957 return _gnutls_asn2err (result);
960 asn1_delete_structure (&dinfo);
962 output->size = tmp_output_size;
963 output->data = tmp_output;
965 return 0;