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>
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>
33 #include <gnutls_buffers.h>
34 #include <gnutls_sig.h>
35 #include <gnutls_kx.h>
37 #include <ext/signature.h>
38 #include <gnutls_state.h>
39 #include <x509/common.h>
40 #include <abstract_int.h>
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
);
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
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.
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
;
72 uint8_t concat
[MAX_SIG_SIZE
];
73 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
74 gnutls_digest_algorithm_t hash_algo
;
77 _gnutls_session_get_sign_algo (session
, cert
);
78 if (*sign_algo
== GNUTLS_SIGN_UNKNOWN
)
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
);
96 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
98 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
100 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
102 switch (gnutls_pubkey_get_pk_algorithm(cert
->pubkey
, NULL
))
105 if (!_gnutls_version_has_selectable_sighash (ver
))
109 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
116 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
118 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
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
;
131 _gnutls_hash_deinit (&td_sha
, concat
);
133 dconcat
.data
= concat
;
134 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
139 _gnutls_hash_deinit (&td_sha
, concat
);
141 if (!IS_SHA(hash_algo
))
144 return GNUTLS_E_INTERNAL_ERROR
;
146 dconcat
.data
= concat
;
147 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
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
);
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
)
181 if ((ret
= _gnutls_pkcs1_rsa_encrypt (signature
, data
, params
, 1)) < 0)
189 ret
= _gnutls_pk_sign( algo
, signature
, data
, params
);
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.
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
218 gnutls_pubkey_get_key_usage(cert
->pubkey
, &key_usage
);
221 if (!(key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
))
224 if (session
->internals
.priorities
.allow_key_usage_violation
== 0)
225 return GNUTLS_E_KEY_USAGE_VIOLATION
;
227 _gnutls_audit_log(session
, "Key usage violation was detected (ignored).\n");
230 /* External signing. Deprecated. To be removed. */
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
);
244 gnutls_datum_t digest
;
246 ret
= _gnutls_set_datum(&digest
, hash_concat
->data
, hash_concat
->size
);
248 return gnutls_assert_val(ret
);
250 ret
= pk_prepare_hash (gnutls_privkey_get_pk_algorithm(pkey
, NULL
), hash_algo
, &digest
);
257 ret
= (*session
->internals
.sign_func
)
258 (session
, session
->internals
.sign_func_userdata
,
259 cert
->type
, &cert
->cert
, &digest
, signature
);
261 gnutls_free(digest
.data
);
268 if (!_gnutls_version_has_selectable_sighash (ver
))
269 return _gnutls_privkey_sign_hash (pkey
, hash_concat
, signature
);
271 return gnutls_privkey_sign_hash (pkey
, hash_algo
, 0, hash_concat
, signature
);
275 verify_tls_hash (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
)
282 gnutls_datum_t vdata
;
283 unsigned int key_usage
= 0, flags
;
288 return GNUTLS_E_CERTIFICATE_ERROR
;
291 gnutls_pubkey_get_key_usage(cert
->pubkey
, &key_usage
);
293 /* If the certificate supports signing continue.
296 if (!(key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
))
299 if (session
->internals
.priorities
.allow_key_usage_violation
== 0)
300 return GNUTLS_E_KEY_USAGE_VIOLATION
;
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
);
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
;
325 vdata
.data
= &hash_concat
->data
[sha1pos
];
326 vdata
.size
= hash_concat
->size
- sha1pos
;
333 return GNUTLS_E_INTERNAL_ERROR
;
336 ret
= gnutls_pubkey_verify_hash2(cert
->pubkey
, sign_algo
, flags
,
340 return gnutls_assert_val(ret
);
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
;
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
);
371 return gnutls_assert_val(ret
);
373 ret
= _gnutls_session_sign_algo_enabled (session
, sign_algo
);
375 return gnutls_assert_val(ret
);
377 hash_algo
= _gnutls_sign_get_hash_algorithm (sign_algo
);
381 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
388 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
390 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
392 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
394 hash_algo
= GNUTLS_DIG_SHA1
;
397 ret
= _gnutls_hash_init (&td_sha
, hash_algo
);
401 if (!_gnutls_version_has_selectable_sighash (ver
))
402 _gnutls_hash_deinit (&td_md5
, NULL
);
406 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
408 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
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
;
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 (ver
, cert
, &dconcat
, signature
,
429 _gnutls_hash_get_algo_len (hash_algo
),
431 _gnutls_sign_get_pk_algorithm (sign_algo
));
442 /* Client certificate verify calculations
445 /* this is _gnutls_handshake_verify_crt_vrfy for TLS 1.2
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
)
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
);
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
,
470 return gnutls_assert_val(ret
);
472 dconcat
.data
= concat
;
473 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
476 verify_tls_hash (ver
, cert
, &dconcat
, signature
, 0, sign_algo
, pk
);
487 /* Verifies a TLS signature (like the one in the client certificate
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
)
497 uint8_t concat
[MAX_SIG_SIZE
];
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
,
512 _gnutls_hash_init (&td_md5
, GNUTLS_DIG_MD5
);
520 _gnutls_hash_init (&td_sha
, GNUTLS_DIG_SHA1
);
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);
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
,
543 security_parameters
.master_secret
,
547 _gnutls_hash_deinit (&td_sha
, NULL
);
548 return gnutls_assert_val(ret
);
551 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
553 security_parameters
.master_secret
,
557 return gnutls_assert_val(ret
);
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 */
570 verify_tls_hash (ver
, cert
, &dconcat
, signature
, 16,
572 gnutls_pubkey_get_pk_algorithm(cert
->pubkey
, NULL
));
583 /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2
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
;
592 uint8_t concat
[MAX_SIG_SIZE
];
593 gnutls_sign_algorithm_t sign_algo
;
594 gnutls_digest_algorithm_t hash_algo
;
597 _gnutls_session_get_sign_algo (session
, cert
);
598 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
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
,
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
);
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
;
645 uint8_t concat
[MAX_SIG_SIZE
];
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
,
656 _gnutls_hash_init (&td_sha
, GNUTLS_DIG_SHA1
);
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);
671 _gnutls_hash_deinit (&td_sha
, NULL
);
675 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
677 security_parameters
.master_secret
,
680 return gnutls_assert_val(ret
);
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
);
688 return gnutls_assert_val(ret
);
694 _gnutls_hash_init (&td_md5
, GNUTLS_DIG_MD5
);
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
,
704 security_parameters
.master_secret
,
707 return gnutls_assert_val(ret
);
710 _gnutls_hash_deinit (&td_md5
, concat
);
712 dconcat
.data
= concat
;
718 dconcat
.data
= &concat
[16];
723 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR
);
725 ret
= sign_tls_hash (session
, GNUTLS_DIG_NULL
, cert
, pkey
, &dconcat
, signature
);
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
)
741 digest
->size
= _gnutls_hash_get_algo_len (hash
);
742 digest
->data
= gnutls_malloc (digest
->size
);
743 if (digest
->data
== NULL
)
746 return GNUTLS_E_MEMORY_ERROR
;
749 ret
= _gnutls_hash_fast (hash
, data
->data
, data
->size
, digest
->data
);
759 gnutls_free (digest
->data
);
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
)
774 gnutls_datum_t old_digest
= { digest
->data
, digest
->size
};
779 /* Encode the digest as a DigestInfo
781 if ((ret
= encode_ber_digest_info (hash
, &old_digest
, digest
)) != 0)
787 _gnutls_free_datum (&old_digest
);
794 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
800 /* Reads the digest information.
801 * we use DER here, although we should use BER. It works fine
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
;
814 if ((result
= asn1_create_element (_gnutls_get_gnutls_asn (),
816 &dinfo
)) != ASN1_SUCCESS
)
819 return _gnutls_asn2err (result
);
822 result
= asn1_der_decoding (&dinfo
, info
->data
, info
->size
, NULL
);
823 if (result
!= ASN1_SUCCESS
)
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
)
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
);
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)))
860 asn1_delete_structure (&dinfo
);
861 return GNUTLS_E_ASN1_GENERIC_ERROR
;
865 result
= asn1_read_value (dinfo
, "digest", digest
, &len
);
867 if (result
!= ASN1_SUCCESS
)
871 asn1_delete_structure (&dinfo
);
872 return _gnutls_asn2err (result
);
876 asn1_delete_structure (&dinfo
);
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.
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
;
895 algo
= _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t
) hash
);
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 (),
905 &dinfo
)) != ASN1_SUCCESS
)
908 return _gnutls_asn2err (result
);
911 result
= asn1_write_value (dinfo
, "digestAlgorithm.algorithm", algo
, 1);
912 if (result
!= ASN1_SUCCESS
)
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
)
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
)
937 asn1_delete_structure (&dinfo
);
938 return _gnutls_asn2err (result
);
942 asn1_der_coding (dinfo
, "", NULL
, &tmp_output_size
, NULL
);
944 tmp_output
= gnutls_malloc (tmp_output_size
);
945 if (tmp_output
== NULL
)
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
)
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
;