2 * Copyright (C) 2001, 2004, 2005, 2006, 2007 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_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
);
62 ret
= _gnutls_hash_copy (&td_sha
, &session
->internals
.handshake_mac_handle_sha
);
69 if (ver
== GNUTLS_SSL3
)
71 ret
= _gnutls_generate_master (session
, 1);
78 _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
79 session
->security_parameters
.
80 master_secret
, TLS_MASTER_SIZE
);
83 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
85 switch (cert
->subject_pk_algorithm
)
88 ret
= _gnutls_hash_copy (&td_md5
, &session
->internals
.handshake_mac_handle_md5
);
95 if (ver
== GNUTLS_SSL3
)
96 _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
97 session
->security_parameters
.
98 master_secret
, TLS_MASTER_SIZE
);
100 _gnutls_hash_deinit (&td_md5
, concat
);
102 dconcat
.data
= concat
;
106 dconcat
.data
= &concat
[16];
112 return GNUTLS_E_INTERNAL_ERROR
;
114 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);
124 /* Generates a signature of all the random data and the parameters.
125 * Used in DHE_* ciphersuites.
128 _gnutls_tls_sign_params (gnutls_session_t session
, gnutls_cert
* cert
,
129 gnutls_privkey
* pkey
, gnutls_datum_t
* params
,
130 gnutls_datum_t
* signature
)
132 gnutls_datum_t dconcat
;
136 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
138 ret
= _gnutls_hash_init (&td_sha
, GNUTLS_MAC_SHA1
);
145 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
147 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
149 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
151 switch (cert
->subject_pk_algorithm
)
154 if (ver
< GNUTLS_TLS1_2
)
158 ret
=_gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
165 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
167 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
169 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
171 _gnutls_hash_deinit (&td_md5
, concat
);
172 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
179 /* Use NULL parameters. */
181 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
183 _gnutls_hash_deinit (&td_sha
, &concat
[15]);
186 /* No parameters field. */
188 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14",
190 _gnutls_hash_deinit (&td_sha
, &concat
[13]);
194 dconcat
.data
= concat
;
197 _gnutls_hash_deinit (&td_sha
, concat
);
198 dconcat
.data
= concat
;
204 _gnutls_hash_deinit (&td_sha
, NULL
);
205 return GNUTLS_E_INTERNAL_ERROR
;
207 ret
= _gnutls_tls_sign (session
, cert
, pkey
, &dconcat
, signature
);
218 /* This will create a PKCS1 or DSA signature, using the given parameters, and the
219 * given data. The output will be allocated and be put in signature.
222 _gnutls_sign (gnutls_pk_algorithm_t algo
, mpi_t
* params
,
223 int params_size
, const gnutls_datum_t
* data
,
224 gnutls_datum_t
* signature
)
232 if ((ret
= _gnutls_pkcs1_rsa_encrypt (signature
, data
, params
,
233 params_size
, 1)) < 0)
242 if ((ret
= _gnutls_dsa_sign (signature
, data
, params
, params_size
)) < 0)
250 return GNUTLS_E_INTERNAL_ERROR
;
257 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
258 * Cert is the certificate of the corresponding private key. It is only checked if
259 * it supports signing.
262 _gnutls_tls_sign (gnutls_session_t session
,
263 gnutls_cert
* cert
, gnutls_privkey
* pkey
,
264 const gnutls_datum_t
* hash_concat
,
265 gnutls_datum_t
* signature
)
268 /* If our certificate supports signing
272 if (cert
->key_usage
!= 0)
273 if (!(cert
->key_usage
& KEY_DIGITAL_SIGNATURE
))
276 return GNUTLS_E_KEY_USAGE_VIOLATION
;
279 /* External signing. */
280 if (!pkey
|| pkey
->params_size
== 0)
282 if (!session
->internals
.sign_func
)
283 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
285 return (*session
->internals
.sign_func
)
286 (session
, session
->internals
.sign_func_userdata
,
287 cert
->cert_type
, &cert
->raw
,
288 hash_concat
, signature
);
291 return _gnutls_sign (pkey
->pk_algorithm
, pkey
->params
,
292 pkey
->params_size
, hash_concat
, signature
);
296 _gnutls_verify_sig (gnutls_cert
* cert
,
297 const gnutls_datum_t
* hash_concat
,
298 gnutls_datum_t
* signature
,
302 gnutls_datum_t vdata
;
304 if (cert
->version
== 0 || cert
== NULL
)
305 { /* this is the only way to check
306 * if it is initialized
309 return GNUTLS_E_CERTIFICATE_ERROR
;
312 /* If the certificate supports signing continue.
315 if (cert
->key_usage
!= 0)
316 if (!(cert
->key_usage
& KEY_DIGITAL_SIGNATURE
))
319 return GNUTLS_E_KEY_USAGE_VIOLATION
;
322 switch (cert
->subject_pk_algorithm
)
326 vdata
.data
= hash_concat
->data
;
327 vdata
.size
= hash_concat
->size
;
329 /* verify signature */
330 if ((ret
= _gnutls_rsa_verify (&vdata
, signature
, cert
->params
,
331 cert
->params_size
, 1)) < 0)
340 vdata
.data
= &hash_concat
->data
[sha1pos
];
341 vdata
.size
= 20; /* sha1 */
343 /* verify signature */
344 if ((ret
= _gnutls_dsa_verify (&vdata
, signature
, cert
->params
,
345 cert
->params_size
)) < 0)
355 return GNUTLS_E_INTERNAL_ERROR
;
364 /* Verifies a TLS signature (like the one in the client certificate
368 _gnutls_verify_sig_hdata (gnutls_session_t session
, gnutls_cert
* cert
,
369 gnutls_datum_t
* signature
)
375 gnutls_datum_t dconcat
;
376 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
378 ret
= _gnutls_hash_copy (&td_md5
, &session
->internals
.handshake_mac_handle_md5
);
385 ret
= _gnutls_hash_copy (&td_sha
, &session
->internals
.handshake_mac_handle_sha
);
389 _gnutls_hash_deinit (&td_md5
, NULL
);
390 return GNUTLS_E_HASH_FAILED
;
393 if (ver
== GNUTLS_SSL3
)
395 ret
= _gnutls_generate_master (session
, 1);
402 _gnutls_mac_deinit_ssl3_handshake (&td_md5
, concat
,
403 session
->security_parameters
.
404 master_secret
, TLS_MASTER_SIZE
);
405 _gnutls_mac_deinit_ssl3_handshake (&td_sha
, &concat
[16],
406 session
->security_parameters
.
407 master_secret
, TLS_MASTER_SIZE
);
411 _gnutls_hash_deinit (&td_md5
, concat
);
412 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
415 dconcat
.data
= concat
;
416 dconcat
.size
= 20 + 16; /* md5+ sha */
418 ret
= _gnutls_verify_sig (cert
, &dconcat
, signature
, 16);
429 /* Generates a signature of all the random data and the parameters.
430 * Used in DHE_* ciphersuites.
433 _gnutls_verify_sig_params (gnutls_session_t session
, gnutls_cert
* cert
,
434 const gnutls_datum_t
* params
,
435 gnutls_datum_t
* signature
)
437 gnutls_datum_t dconcat
;
442 gnutls_protocol_t ver
= gnutls_protocol_get_version (session
);
444 if (ver
< GNUTLS_TLS1_2
)
446 ret
= _gnutls_hash_init (&td_md5
, GNUTLS_MAC_MD5
);
453 _gnutls_hash (&td_md5
, session
->security_parameters
.client_random
,
455 _gnutls_hash (&td_md5
, session
->security_parameters
.server_random
,
457 _gnutls_hash (&td_md5
, params
->data
, params
->size
);
460 ret
= _gnutls_hash_init (&td_sha
, GNUTLS_MAC_SHA1
);
464 if (ver
< GNUTLS_TLS1_2
)
465 _gnutls_hash_deinit (&td_md5
, NULL
);
469 _gnutls_hash (&td_sha
, session
->security_parameters
.client_random
,
471 _gnutls_hash (&td_sha
, session
->security_parameters
.server_random
,
473 _gnutls_hash (&td_sha
, params
->data
, params
->size
);
475 if (ver
< GNUTLS_TLS1_2
)
477 _gnutls_hash_deinit (&td_md5
, concat
);
478 _gnutls_hash_deinit (&td_sha
, &concat
[16]);
484 /* Use NULL parameters. */
486 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
488 _gnutls_hash_deinit (&td_sha
, &concat
[15]);
491 /* No parameters field. */
493 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14",
495 _gnutls_hash_deinit (&td_sha
, &concat
[13]);
500 dconcat
.data
= concat
;
502 ret
= _gnutls_verify_sig (cert
, &dconcat
, signature
, dconcat
.size
- 20);