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 /* While this is currently equal to the length of RSA/SHA512
50 * signature, it should also be sufficient for DSS signature and any
51 * other RSA signatures including one with the old MD5/SHA1-combined
54 #define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
56 /* Generates a signature of all the random data and the parameters.
57 * Used in DHE_* ciphersuites.
60 _gnutls_handshake_sign_data (gnutls_session_t session
, gnutls_pcert_st
* cert
,
61 gnutls_privkey_t pkey
, gnutls_datum_t
* params
,
62 gnutls_datum_t
* signature
,
63 gnutls_sign_algorithm_t
* sign_algo
)
65 gnutls_datum_t dconcat
;
68 uint8_t concat
[MAX_SIG_SIZE
];
69 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
70 gnutls_digest_algorithm_t hash_algo
;
73 _gnutls_session_get_sign_algo (session
, cert
);
74 if (*sign_algo
== GNUTLS_SIGN_UNKNOWN
)
77 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
80 gnutls_sign_algorithm_set(session
, *sign_algo
);
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
);
94 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
96 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
98 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
100 switch (gnutls_privkey_get_pk_algorithm(pkey
, NULL
))
103 if (!_gnutls_version_has_selectable_sighash (ver
))
107 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
114 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
116 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
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
;
129 _gnutls_hash_deinit (&td_sha
, concat
);
131 dconcat
.data
= concat
;
132 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
137 _gnutls_hash_deinit (&td_sha
, concat
);
139 if (!IS_SHA(hash_algo
))
142 return GNUTLS_E_INTERNAL_ERROR
;
144 dconcat
.data
= concat
;
145 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
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
);
164 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
165 * Cert is the certificate of the corresponding private key. It is only checked if
166 * it supports signing.
169 sign_tls_hash (gnutls_session_t session
, gnutls_digest_algorithm_t hash_algo
,
170 gnutls_pcert_st
* cert
, gnutls_privkey_t pkey
,
171 const gnutls_datum_t
* hash_concat
,
172 gnutls_datum_t
* signature
)
174 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
175 unsigned int key_usage
= 0;
176 /* If our certificate supports signing
181 gnutls_pubkey_get_key_usage(cert
->pubkey
, &key_usage
);
184 if (!(key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
))
187 if (session
->internals
.priorities
.allow_key_usage_violation
== 0)
188 return GNUTLS_E_KEY_USAGE_VIOLATION
;
190 _gnutls_audit_log(session
, "Key usage violation was detected (ignored).\n");
193 /* External signing. Deprecated. To be removed. */
198 if (!session
->internals
.sign_func
)
199 return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS
);
201 if (!_gnutls_version_has_selectable_sighash (ver
))
202 return (*session
->internals
.sign_func
)
203 (session
, session
->internals
.sign_func_userdata
,
204 cert
->type
, &cert
->cert
, hash_concat
, signature
);
207 gnutls_datum_t digest
;
209 ret
= _gnutls_set_datum(&digest
, hash_concat
->data
, hash_concat
->size
);
211 return gnutls_assert_val(ret
);
213 ret
= pk_prepare_hash (gnutls_privkey_get_pk_algorithm(pkey
, NULL
), hash_algo
, &digest
);
220 ret
= (*session
->internals
.sign_func
)
221 (session
, session
->internals
.sign_func_userdata
,
222 cert
->type
, &cert
->cert
, &digest
, signature
);
224 gnutls_free(digest
.data
);
231 if (!_gnutls_version_has_selectable_sighash (ver
))
232 return _gnutls_privkey_sign_hash (pkey
, hash_concat
, signature
);
234 return gnutls_privkey_sign_hash (pkey
, hash_algo
, 0, hash_concat
, signature
);
238 verify_tls_hash (gnutls_session_t session
,
239 gnutls_protocol_t ver
, gnutls_pcert_st
* cert
,
240 const gnutls_datum_t
* hash_concat
,
241 gnutls_datum_t
* signature
, size_t sha1pos
,
242 gnutls_sign_algorithm_t sign_algo
,
243 gnutls_pk_algorithm_t pk_algo
)
246 gnutls_datum_t vdata
;
247 unsigned int key_usage
= 0, flags
;
252 return GNUTLS_E_CERTIFICATE_ERROR
;
255 gnutls_pubkey_get_key_usage(cert
->pubkey
, &key_usage
);
257 /* If the certificate supports signing continue.
260 if (!(key_usage
& GNUTLS_KEY_DIGITAL_SIGNATURE
))
263 if (session
->internals
.priorities
.allow_key_usage_violation
== 0)
264 return GNUTLS_E_KEY_USAGE_VIOLATION
;
266 _gnutls_audit_log(session
, "Key usage violation was detected (ignored).\n");
269 if (pk_algo
== GNUTLS_PK_UNKNOWN
)
270 pk_algo
= gnutls_pubkey_get_pk_algorithm(cert
->pubkey
, NULL
);
275 vdata
.data
= hash_concat
->data
;
276 vdata
.size
= hash_concat
->size
;
278 /* verify signature */
279 if (!_gnutls_version_has_selectable_sighash (ver
))
280 flags
= GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA
;
286 vdata
.data
= &hash_concat
->data
[sha1pos
];
287 vdata
.size
= hash_concat
->size
- sha1pos
;
294 return GNUTLS_E_INTERNAL_ERROR
;
297 ret
= gnutls_pubkey_verify_hash2(cert
->pubkey
, sign_algo
, flags
,
301 return gnutls_assert_val(ret
);
308 /* Generates a signature of all the random data and the parameters.
309 * Used in DHE_* ciphersuites.
312 _gnutls_handshake_verify_data (gnutls_session_t session
, gnutls_pcert_st
* cert
,
313 const gnutls_datum_t
* params
,
314 gnutls_datum_t
* signature
,
315 gnutls_sign_algorithm_t sign_algo
)
317 gnutls_datum_t dconcat
;
321 uint8_t concat
[MAX_SIG_SIZE
];
322 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
323 gnutls_digest_algorithm_t hash_algo
;
325 if (_gnutls_version_has_selectable_sighash (ver
))
327 _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
328 session
, gnutls_sign_algorithm_get_name (sign_algo
));
330 ret
= _gnutls_pubkey_compatible_with_sig(session
, cert
->pubkey
, ver
, sign_algo
);
332 return gnutls_assert_val(ret
);
334 ret
= _gnutls_session_sign_algo_enabled (session
, sign_algo
);
336 return gnutls_assert_val(ret
);
338 hash_algo
= gnutls_sign_get_hash_algorithm (sign_algo
);
342 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
349 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
351 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
353 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
355 hash_algo
= GNUTLS_DIG_SHA1
;
358 ret
= _gnutls_hash_init (&td_sha
, hash_algo
);
362 if (!_gnutls_version_has_selectable_sighash (ver
))
363 _gnutls_hash_deinit (&td_md5
, NULL
);
367 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
369 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
371 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
373 if (!_gnutls_version_has_selectable_sighash (ver
))
375 _gnutls_hash_deinit (&td_md5
, concat
);
376 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
377 dconcat
.data
= concat
;
382 _gnutls_hash_deinit (&td_sha
, concat
);
384 dconcat
.data
= concat
;
385 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
388 ret
= verify_tls_hash (session
, ver
, cert
, &dconcat
, signature
,
389 dconcat
.size
- _gnutls_hash_get_algo_len (hash_algo
),
390 sign_algo
, gnutls_sign_get_pk_algorithm (sign_algo
));
401 /* Client certificate verify calculations
404 /* this is _gnutls_handshake_verify_crt_vrfy for TLS 1.2
407 _gnutls_handshake_verify_crt_vrfy12 (gnutls_session_t session
,
408 gnutls_pcert_st
* cert
,
409 gnutls_datum_t
* signature
,
410 gnutls_sign_algorithm_t sign_algo
)
413 uint8_t concat
[MAX_HASH_SIZE
];
414 gnutls_datum_t dconcat
;
415 gnutls_digest_algorithm_t hash_algo
;
416 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
417 gnutls_pk_algorithm_t pk
= gnutls_pubkey_get_pk_algorithm(cert
->pubkey
, NULL
);
419 ret
= _gnutls_session_sign_algo_enabled(session
, sign_algo
);
421 return gnutls_assert_val(ret
);
423 hash_algo
= gnutls_sign_get_hash_algorithm(sign_algo
);
425 ret
= _gnutls_hash_fast(hash_algo
, session
->internals
.handshake_hash_buffer
.data
,
426 session
->internals
.handshake_hash_buffer_prev_len
,
429 return gnutls_assert_val(ret
);
431 dconcat
.data
= concat
;
432 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
435 verify_tls_hash (session
, ver
, cert
, &dconcat
, signature
, 0, sign_algo
, pk
);
446 /* Verifies a TLS signature (like the one in the client certificate
450 _gnutls_handshake_verify_crt_vrfy (gnutls_session_t session
,
451 gnutls_pcert_st
*cert
,
452 gnutls_datum_t
* signature
,
453 gnutls_sign_algorithm_t sign_algo
)
456 uint8_t concat
[MAX_SIG_SIZE
];
459 gnutls_datum_t dconcat
;
460 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
462 _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
463 session
, gnutls_sign_algorithm_get_name (sign_algo
));
466 if (_gnutls_version_has_selectable_sighash(ver
))
467 return _gnutls_handshake_verify_crt_vrfy12 (session
, cert
, signature
,
471 _gnutls_hash_init (&td_md5
, GNUTLS_DIG_MD5
);
479 _gnutls_hash_init (&td_sha
, GNUTLS_DIG_SHA1
);
483 _gnutls_hash_deinit (&td_md5
, NULL
);
484 return GNUTLS_E_HASH_FAILED
;
487 _gnutls_hash(&td_sha
, session
->internals
.handshake_hash_buffer
.data
, session
->internals
.handshake_hash_buffer_prev_len
);
488 _gnutls_hash(&td_md5
, session
->internals
.handshake_hash_buffer
.data
, session
->internals
.handshake_hash_buffer_prev_len
);
490 if (ver
== GNUTLS_SSL3
)
492 ret
= _gnutls_generate_master (session
, 1);
495 _gnutls_hash_deinit (&td_md5
, NULL
);
496 _gnutls_hash_deinit (&td_sha
, NULL
);
497 return gnutls_assert_val(ret
);
500 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
502 security_parameters
.master_secret
,
506 _gnutls_hash_deinit (&td_sha
, NULL
);
507 return gnutls_assert_val(ret
);
510 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
512 security_parameters
.master_secret
,
516 return gnutls_assert_val(ret
);
521 _gnutls_hash_deinit (&td_md5
, concat
);
522 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
525 dconcat
.data
= concat
;
526 dconcat
.size
= 20 + 16; /* md5+ sha */
529 verify_tls_hash (session
, ver
, cert
, &dconcat
, signature
, 16,
531 gnutls_pubkey_get_pk_algorithm(cert
->pubkey
, NULL
));
542 /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2
545 _gnutls_handshake_sign_crt_vrfy12 (gnutls_session_t session
,
546 gnutls_pcert_st
* cert
, gnutls_privkey_t pkey
,
547 gnutls_datum_t
* signature
)
549 gnutls_datum_t dconcat
;
551 uint8_t concat
[MAX_SIG_SIZE
];
552 gnutls_sign_algorithm_t sign_algo
;
553 gnutls_digest_algorithm_t hash_algo
;
556 _gnutls_session_get_sign_algo (session
, cert
);
557 if (sign_algo
== GNUTLS_SIGN_UNKNOWN
)
560 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
563 gnutls_sign_algorithm_set(session
, sign_algo
);
565 hash_algo
= gnutls_sign_get_hash_algorithm (sign_algo
);
567 _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
568 gnutls_sign_algorithm_get_name (sign_algo
),
569 gnutls_mac_get_name ((gnutls_mac_algorithm_t
)hash_algo
));
571 ret
= _gnutls_hash_fast (hash_algo
, session
->internals
.handshake_hash_buffer
.data
,
572 session
->internals
.handshake_hash_buffer
.length
,
575 return gnutls_assert_val(ret
);
577 dconcat
.data
= concat
;
578 dconcat
.size
= _gnutls_hash_get_algo_len (hash_algo
);
580 ret
= sign_tls_hash (session
, hash_algo
, cert
, pkey
, &dconcat
, signature
);
591 /* Generates a signature of all the previous sent packets in the
592 * handshake procedure.
593 * 20040227: now it works for SSL 3.0 as well
594 * 20091031: works for TLS 1.2 too!
596 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
597 * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
600 _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session
,
601 gnutls_pcert_st
* cert
, gnutls_privkey_t pkey
,
602 gnutls_datum_t
* signature
)
604 gnutls_datum_t dconcat
;
606 uint8_t concat
[MAX_SIG_SIZE
];
609 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
610 gnutls_pk_algorithm_t pk
= gnutls_privkey_get_pk_algorithm(pkey
, NULL
);
612 if (_gnutls_version_has_selectable_sighash(ver
))
613 return _gnutls_handshake_sign_crt_vrfy12 (session
, cert
, pkey
,
617 _gnutls_hash_init (&td_sha
, GNUTLS_DIG_SHA1
);
624 _gnutls_hash(&td_sha
, session
->internals
.handshake_hash_buffer
.data
, session
->internals
.handshake_hash_buffer
.length
);
626 if (ver
== GNUTLS_SSL3
)
628 ret
= _gnutls_generate_master (session
, 1);
632 _gnutls_hash_deinit (&td_sha
, NULL
);
636 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
638 security_parameters
.master_secret
,
641 return gnutls_assert_val(ret
);
644 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
646 /* ensure 1024 bit DSA keys are used */
647 ret
= _gnutls_pubkey_compatible_with_sig(session
, cert
->pubkey
, ver
, GNUTLS_SIGN_UNKNOWN
);
649 return gnutls_assert_val(ret
);
655 _gnutls_hash_init (&td_md5
, GNUTLS_DIG_MD5
);
657 return gnutls_assert_val(ret
);
659 _gnutls_hash(&td_md5
, session
->internals
.handshake_hash_buffer
.data
, session
->internals
.handshake_hash_buffer
.length
);
661 if (ver
== GNUTLS_SSL3
)
663 ret
= _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
665 security_parameters
.master_secret
,
668 return gnutls_assert_val(ret
);
671 _gnutls_hash_deinit (&td_md5
, concat
);
673 dconcat
.data
= concat
;
679 dconcat
.data
= &concat
[16];
684 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR
);
686 ret
= sign_tls_hash (session
, GNUTLS_DIG_NULL
, cert
, pkey
, &dconcat
, signature
);
696 pk_hash_data (gnutls_pk_algorithm_t pk
, gnutls_digest_algorithm_t hash
,
697 gnutls_pk_params_st
* params
,
698 const gnutls_datum_t
* data
, gnutls_datum_t
* digest
)
702 digest
->size
= _gnutls_hash_get_algo_len (hash
);
703 digest
->data
= gnutls_malloc (digest
->size
);
704 if (digest
->data
== NULL
)
707 return GNUTLS_E_MEMORY_ERROR
;
710 ret
= _gnutls_hash_fast (hash
, data
->data
, data
->size
, digest
->data
);
720 gnutls_free (digest
->data
);
726 * This function will do RSA PKCS #1 1.5 encoding
727 * on the given digest. The given digest must be allocated
728 * and will be freed if replacement is required.
731 pk_prepare_hash (gnutls_pk_algorithm_t pk
,
732 gnutls_digest_algorithm_t hash
, gnutls_datum_t
* digest
)
735 gnutls_datum_t old_digest
= { digest
->data
, digest
->size
};
740 /* Encode the digest as a DigestInfo
742 if ((ret
= encode_ber_digest_info (hash
, &old_digest
, digest
)) != 0)
748 _gnutls_free_datum (&old_digest
);
755 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;