2 * Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library 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 2.1 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
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
28 #include <auth_cert.h>
29 #include <gnutls_algorithms.h>
30 #include <gnutls_cert.h>
31 #include <gnutls_datum.h>
32 #include <gnutls_mpi.h>
33 #include <gnutls_global.h>
34 #include <gnutls_pk.h>
36 #include <gnutls_buffers.h>
37 #include <gnutls_sig.h>
38 #include <gnutls_kx.h>
41 _gnutls_tls_sign (gnutls_session_t session
,
42 gnutls_cert
* cert
, gnutls_privkey
* pkey
,
43 const gnutls_datum_t
* hash_concat
,
44 gnutls_datum_t
* signature
);
47 /* Generates a signature of all the previous sent packets in the
48 * handshake procedure. (20040227: now it works for SSL 3.0 as well)
51 _gnutls_tls_sign_hdata (gnutls_session_t session
,
52 gnutls_cert
* cert
, gnutls_privkey
* pkey
,
53 gnutls_datum_t
* signature
)
55 gnutls_datum_t dconcat
;
60 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
63 _gnutls_hash_copy (&td_sha
, &session
->internals
.handshake_mac_handle_sha
);
70 if (ver
== GNUTLS_SSL3
)
72 ret
= _gnutls_generate_master (session
, 1);
79 _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
80 session
->security_parameters
.
81 master_secret
, GNUTLS_MASTER_SIZE
);
84 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
86 switch (cert
->subject_pk_algorithm
)
90 _gnutls_hash_copy (&td_md5
,
91 &session
->internals
.handshake_mac_handle_md5
);
98 if (ver
== GNUTLS_SSL3
)
99 _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
100 session
->security_parameters
.
101 master_secret
, GNUTLS_MASTER_SIZE
);
103 _gnutls_hash_deinit (&td_md5
, concat
);
105 dconcat
.data
= concat
;
109 dconcat
.data
= &concat
[16];
115 return GNUTLS_E_INTERNAL_ERROR
;
117 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);
127 /* Generates a signature of all the random data and the parameters.
128 * Used in DHE_* ciphersuites.
131 _gnutls_tls_sign_params (gnutls_session_t session
, gnutls_cert
* cert
,
132 gnutls_privkey
* pkey
, gnutls_datum_t
* params
,
133 gnutls_datum_t
* signature
)
135 gnutls_datum_t dconcat
;
139 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
141 ret
= _gnutls_hash_init (&td_sha
, GNUTLS_MAC_SHA1
);
148 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
150 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
152 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
154 switch (cert
->subject_pk_algorithm
)
157 if (!_gnutls_version_has_selectable_prf (ver
))
161 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
168 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
170 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
172 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
174 _gnutls_hash_deinit (&td_md5
, concat
);
175 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
182 /* Use NULL parameters. */
184 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
186 _gnutls_hash_deinit (&td_sha
, &concat
[15]);
189 /* No parameters field. */
191 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
192 _gnutls_hash_deinit (&td_sha
, &concat
[13]);
196 dconcat
.data
= concat
;
199 _gnutls_hash_deinit (&td_sha
, concat
);
200 dconcat
.data
= concat
;
206 _gnutls_hash_deinit (&td_sha
, NULL
);
207 return GNUTLS_E_INTERNAL_ERROR
;
209 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);
220 /* This will create a PKCS1 or DSA signature, using the given parameters, and the
221 * given data. The output will be allocated and be put in signature.
224 _gnutls_sign (gnutls_pk_algorithm_t algo
, bigint_t
* params
,
225 int params_size
, const gnutls_datum_t
* data
,
226 gnutls_datum_t
* signature
)
234 if ((ret
= _gnutls_pkcs1_rsa_encrypt (signature
, data
, params
,
235 params_size
, 1)) < 0)
244 if ((ret
= _gnutls_dsa_sign (signature
, data
, params
, params_size
)) < 0)
252 return GNUTLS_E_INTERNAL_ERROR
;
259 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
260 * Cert is the certificate of the corresponding private key. It is only checked if
261 * it supports signing.
264 _gnutls_tls_sign (gnutls_session_t session
,
265 gnutls_cert
* cert
, gnutls_privkey
* pkey
,
266 const gnutls_datum_t
* hash_concat
,
267 gnutls_datum_t
* signature
)
270 /* If our certificate supports signing
275 if (cert
->key_usage
!= 0)
276 if (!(cert
->key_usage
& KEY_DIGITAL_SIGNATURE
))
279 return GNUTLS_E_KEY_USAGE_VIOLATION
;
282 /* External signing. */
283 if (!pkey
|| pkey
->params_size
== 0)
285 if (!session
->internals
.sign_func
)
286 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
288 return (*session
->internals
.sign_func
)
289 (session
, session
->internals
.sign_func_userdata
,
290 cert
->cert_type
, &cert
->raw
, hash_concat
, signature
);
294 return _gnutls_sign (pkey
->pk_algorithm
, pkey
->params
,
295 pkey
->params_size
, hash_concat
, signature
);
299 _gnutls_verify_sig (gnutls_cert
* cert
,
300 const gnutls_datum_t
* hash_concat
,
301 gnutls_datum_t
* signature
, size_t sha1pos
)
304 gnutls_datum_t vdata
;
306 if (cert
->version
== 0 || cert
== NULL
)
307 { /* this is the only way to check
308 * if it is initialized
311 return GNUTLS_E_CERTIFICATE_ERROR
;
314 /* If the certificate supports signing continue.
317 if (cert
->key_usage
!= 0)
318 if (!(cert
->key_usage
& KEY_DIGITAL_SIGNATURE
))
321 return GNUTLS_E_KEY_USAGE_VIOLATION
;
324 switch (cert
->subject_pk_algorithm
)
328 vdata
.data
= hash_concat
->data
;
329 vdata
.size
= hash_concat
->size
;
331 /* verify signature */
332 if ((ret
= _gnutls_rsa_verify (&vdata
, signature
, cert
->params
,
333 cert
->params_size
, 1)) < 0)
342 vdata
.data
= &hash_concat
->data
[sha1pos
];
343 vdata
.size
= 20; /* sha1 */
345 /* verify signature */
346 if ((ret
= _gnutls_dsa_verify (&vdata
, signature
, cert
->params
,
347 cert
->params_size
)) < 0)
357 return GNUTLS_E_INTERNAL_ERROR
;
366 /* Verifies a TLS signature (like the one in the client certificate
370 _gnutls_verify_sig_hdata (gnutls_session_t session
, gnutls_cert
* cert
,
371 gnutls_datum_t
* signature
)
377 gnutls_datum_t dconcat
;
378 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
381 _gnutls_hash_copy (&td_md5
, &session
->internals
.handshake_mac_handle_md5
);
389 _gnutls_hash_copy (&td_sha
, &session
->internals
.handshake_mac_handle_sha
);
393 _gnutls_hash_deinit (&td_md5
, NULL
);
394 return GNUTLS_E_HASH_FAILED
;
397 if (ver
== GNUTLS_SSL3
)
399 ret
= _gnutls_generate_master (session
, 1);
406 _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
407 session
->security_parameters
.
408 master_secret
, GNUTLS_MASTER_SIZE
);
409 _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
410 session
->security_parameters
.
411 master_secret
, GNUTLS_MASTER_SIZE
);
415 _gnutls_hash_deinit (&td_md5
, concat
);
416 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
419 dconcat
.data
= concat
;
420 dconcat
.size
= 20 + 16; /* md5+ sha */
422 ret
= _gnutls_verify_sig (cert
, &dconcat
, signature
, 16);
433 /* Generates a signature of all the random data and the parameters.
434 * Used in DHE_* ciphersuites.
437 _gnutls_verify_sig_params (gnutls_session_t session
, gnutls_cert
* cert
,
438 const gnutls_datum_t
* params
,
439 gnutls_datum_t
* signature
)
441 gnutls_datum_t dconcat
;
446 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
448 if (!_gnutls_version_has_selectable_prf (ver
))
450 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
457 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
459 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
461 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
464 ret
= _gnutls_hash_init (&td_sha
, GNUTLS_MAC_SHA1
);
468 if (!_gnutls_version_has_selectable_prf (ver
))
469 _gnutls_hash_deinit (&td_md5
, NULL
);
473 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
475 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
477 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
479 if (!_gnutls_version_has_selectable_prf (ver
))
481 _gnutls_hash_deinit (&td_md5
, concat
);
482 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
488 /* Use NULL parameters. */
490 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
492 _gnutls_hash_deinit (&td_sha
, &concat
[15]);
495 /* No parameters field. */
497 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
498 _gnutls_hash_deinit (&td_sha
, &concat
[13]);
503 dconcat
.data
= concat
;
505 ret
= _gnutls_verify_sig (cert
, &dconcat
, signature
, dconcat
.size
- 20);