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,
26 #include <gnutls_int.h>
27 #include <gnutls_errors.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>
37 #include <gnutls_buffers.h>
38 #include <gnutls_sig.h>
39 #include <gnutls_kx.h>
41 #include <ext_signature.h>
42 #include <gnutls_state.h>
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
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.
61 _gnutls_rsa_encode_sig (gnutls_mac_algorithm_t algo
,
62 const gnutls_datum_t
* hash
,
63 gnutls_datum_t
* signature
)
67 int result
, signature_size
;
69 oid
= _gnutls_x509_mac_to_oid (algo
);
73 return GNUTLS_E_UNKNOWN_HASH_ALGORITHM
;
76 if ((result
= asn1_create_element
77 (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &di
)) != ASN1_SUCCESS
)
80 return _gnutls_asn2err (result
);
83 if ((result
= asn1_write_value (di
, "digestAlgorithm.algorithm",
84 oid
, strlen (oid
))) != ASN1_SUCCESS
)
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
)
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
)
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
)
115 return _gnutls_asn2err (result
);
118 signature
->size
= signature_size
;
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
;
137 opaque concat
[MAX_SIG_SIZE
];
138 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
139 gnutls_digest_algorithm_t hash_algo
;
142 _gnutls_session_get_sign_algo (session
, cert
->subject_pk_algorithm
,
144 if (*sign_algo
== GNUTLS_SIGN_UNKNOWN
)
147 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
150 ret
= _gnutls_hash_init (&td_sha
, hash_algo
);
157 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
159 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
161 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
163 switch (cert
->subject_pk_algorithm
)
166 if (!_gnutls_version_has_selectable_prf (ver
))
170 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
177 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
179 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
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
;
193 _gnutls_hash_deinit (&td_sha
, 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
);
204 _gnutls_hash_deinit (&td_sha
, concat
);
206 if (hash_algo
!= GNUTLS_DIG_SHA1
)
209 return GNUTLS_E_INTERNAL_ERROR
;
211 dconcat
.data
= concat
;
217 _gnutls_hash_deinit (&td_sha
, NULL
);
218 return GNUTLS_E_INTERNAL_ERROR
;
220 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);
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
)
245 if ((ret
= _gnutls_pkcs1_rsa_encrypt (signature
, data
, params
,
246 params_size
, 1)) < 0)
255 if ((ret
= _gnutls_dsa_sign (signature
, data
, params
, params_size
)) < 0)
263 return GNUTLS_E_INTERNAL_ERROR
;
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.
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
286 if (cert
->key_usage
!= 0)
287 if (!(cert
->key_usage
& KEY_DIGITAL_SIGNATURE
))
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
);
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
)
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
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
))
332 return GNUTLS_E_KEY_USAGE_VIOLATION
;
335 if (pk_algo
== GNUTLS_PK_UNKNOWN
)
336 pk_algo
= cert
->subject_pk_algorithm
;
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)
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)
370 return GNUTLS_E_INTERNAL_ERROR
;
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
;
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
);
403 if (!_gnutls_version_has_selectable_prf (ver
))
405 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
412 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
414 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
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
);
426 if (!_gnutls_version_has_selectable_prf (ver
))
427 _gnutls_hash_deinit (&td_md5
, NULL
);
431 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
433 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
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
;
448 _gnutls_hash_deinit (&td_sha
, 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
,
460 _gnutls_hash_get_algo_len (hash_algo
),
461 _gnutls_sign_get_pk_algorithm (algo
));
472 /* Client certificate verify calculations
475 /* this is _gnutls_handshake_verify_cert_vrfy for TLS 1.2
478 _gnutls_handshake_verify_cert_vrfy12 (gnutls_session_t session
,
480 gnutls_datum_t
* signature
,
481 gnutls_sign_algorithm_t sign_algo
)
484 opaque concat
[MAX_SIG_SIZE
];
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
;
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
;
501 _gnutls_x509_pk_to_sign (cert
->subject_pk_algorithm
, hash_algo
);
502 if (sign_algo
!= _sign_algo
)
505 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
509 ret
= _gnutls_hash_copy (&td
, handshake_td
);
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
);
522 _gnutls_verify_sig (cert
, &dconcat
, signature
, 0,
523 cert
->subject_pk_algorithm
);
534 /* Verifies a TLS signature (like the one in the client certificate
538 _gnutls_handshake_verify_cert_vrfy (gnutls_session_t session
,
540 gnutls_datum_t
* signature
,
541 gnutls_sign_algorithm_t sign_algo
)
544 opaque concat
[MAX_SIG_SIZE
];
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
,
556 else if (session
->security_parameters
.handshake_mac_handle_type
!=
557 HANDSHAKE_MAC_TYPE_10
)
560 return GNUTLS_E_INTERNAL_ERROR
;
564 _gnutls_hash_copy (&td_md5
,
565 &session
->internals
.handshake_mac_handle
.tls10
.md5
);
573 _gnutls_hash_copy (&td_sha
,
574 &session
->internals
.handshake_mac_handle
.tls10
.sha
);
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);
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
);
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 */
608 _gnutls_verify_sig (cert
, &dconcat
, signature
, 16,
609 cert
->subject_pk_algorithm
);
620 /* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
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
;
629 opaque concat
[MAX_SIG_SIZE
];
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
;
649 _gnutls_x509_pk_to_sign (cert
->subject_pk_algorithm
, hash_algo
);
650 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
653 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM
;
656 ret
= _gnutls_session_sign_algo_requested (session
, sign_algo
);
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
));
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
);
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
);
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
;
710 opaque concat
[MAX_SIG_SIZE
];
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
,
721 else if (session
->security_parameters
.handshake_mac_handle_type
!=
722 HANDSHAKE_MAC_TYPE_10
)
725 return GNUTLS_E_INTERNAL_ERROR
;
729 _gnutls_hash_copy (&td_sha
,
730 &session
->internals
.handshake_mac_handle
.tls10
.sha
);
737 if (ver
== GNUTLS_SSL3
)
739 ret
= _gnutls_generate_master (session
, 1);
746 _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
747 session
->security_parameters
.
748 master_secret
, GNUTLS_MASTER_SIZE
);
751 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
753 switch (cert
->subject_pk_algorithm
)
757 _gnutls_hash_copy (&td_md5
,
758 &session
->internals
.handshake_mac_handle
.
766 if (ver
== GNUTLS_SSL3
)
767 _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
768 session
->security_parameters
.
769 master_secret
, GNUTLS_MASTER_SIZE
);
771 _gnutls_hash_deinit (&td_md5
, concat
);
773 dconcat
.data
= concat
;
777 dconcat
.data
= &concat
[16];
783 return GNUTLS_E_INTERNAL_ERROR
;
785 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);