Fix use of deprecated types, for now and the future.
[gnutls.git] / lib / gnutls_sig.c
blobbcc4412ce49dde8f74730b22ad25831b6483bd6c
1 /*
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,
21 * USA
25 #include <gnutls_int.h>
26 #include <gnutls_errors.h>
27 #include <x509_b64.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>
35 #include <debug.h>
36 #include <gnutls_buffers.h>
37 #include <gnutls_sig.h>
38 #include <gnutls_kx.h>
40 static int
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)
50 int
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;
56 int ret;
57 opaque concat[36];
58 digest_hd_st td_md5;
59 digest_hd_st td_sha;
60 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
62 ret =
63 _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
64 if (ret < 0)
66 gnutls_assert ();
67 return ret;
70 if (ver == GNUTLS_SSL3)
72 ret = _gnutls_generate_master (session, 1);
73 if (ret < 0)
75 gnutls_assert ();
76 return ret;
79 _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
80 session->security_parameters.
81 master_secret, GNUTLS_MASTER_SIZE);
83 else
84 _gnutls_hash_deinit (&td_sha, &concat[16]);
86 switch (cert->subject_pk_algorithm)
88 case GNUTLS_PK_RSA:
89 ret =
90 _gnutls_hash_copy (&td_md5,
91 &session->internals.handshake_mac_handle_md5);
92 if (ret < 0)
94 gnutls_assert ();
95 return ret;
98 if (ver == GNUTLS_SSL3)
99 _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
100 session->security_parameters.
101 master_secret, GNUTLS_MASTER_SIZE);
102 else
103 _gnutls_hash_deinit (&td_md5, concat);
105 dconcat.data = concat;
106 dconcat.size = 36;
107 break;
108 case GNUTLS_PK_DSA:
109 dconcat.data = &concat[16];
110 dconcat.size = 20;
111 break;
113 default:
114 gnutls_assert ();
115 return GNUTLS_E_INTERNAL_ERROR;
117 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
118 if (ret < 0)
120 gnutls_assert ();
123 return ret;
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;
136 int ret;
137 digest_hd_st td_sha;
138 opaque concat[36];
139 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
141 ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
142 if (ret < 0)
144 gnutls_assert ();
145 return ret;
148 _gnutls_hash (&td_sha, session->security_parameters.client_random,
149 GNUTLS_RANDOM_SIZE);
150 _gnutls_hash (&td_sha, session->security_parameters.server_random,
151 GNUTLS_RANDOM_SIZE);
152 _gnutls_hash (&td_sha, params->data, params->size);
154 switch (cert->subject_pk_algorithm)
156 case GNUTLS_PK_RSA:
157 if (!_gnutls_version_has_selectable_prf (ver))
159 digest_hd_st td_md5;
161 ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
162 if (ret < 0)
164 gnutls_assert ();
165 return ret;
168 _gnutls_hash (&td_md5, session->security_parameters.client_random,
169 GNUTLS_RANDOM_SIZE);
170 _gnutls_hash (&td_md5, session->security_parameters.server_random,
171 GNUTLS_RANDOM_SIZE);
172 _gnutls_hash (&td_md5, params->data, params->size);
174 _gnutls_hash_deinit (&td_md5, concat);
175 _gnutls_hash_deinit (&td_sha, &concat[16]);
177 dconcat.size = 36;
179 else
181 #if 1
182 /* Use NULL parameters. */
183 memcpy (concat,
184 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
185 15);
186 _gnutls_hash_deinit (&td_sha, &concat[15]);
187 dconcat.size = 35;
188 #else
189 /* No parameters field. */
190 memcpy (concat,
191 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
192 _gnutls_hash_deinit (&td_sha, &concat[13]);
193 dconcat.size = 33;
194 #endif
196 dconcat.data = concat;
197 break;
198 case GNUTLS_PK_DSA:
199 _gnutls_hash_deinit (&td_sha, concat);
200 dconcat.data = concat;
201 dconcat.size = 20;
202 break;
204 default:
205 gnutls_assert ();
206 _gnutls_hash_deinit (&td_sha, NULL);
207 return GNUTLS_E_INTERNAL_ERROR;
209 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
210 if (ret < 0)
212 gnutls_assert ();
215 return ret;
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)
228 int ret;
230 switch (algo)
232 case GNUTLS_PK_RSA:
233 /* encrypt */
234 if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params,
235 params_size, 1)) < 0)
237 gnutls_assert ();
238 return ret;
241 break;
242 case GNUTLS_PK_DSA:
243 /* sign */
244 if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0)
246 gnutls_assert ();
247 return ret;
249 break;
250 default:
251 gnutls_assert ();
252 return GNUTLS_E_INTERNAL_ERROR;
253 break;
256 return 0;
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.
263 static int
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
273 if (cert != NULL)
275 if (cert->key_usage != 0)
276 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
278 gnutls_assert ();
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);
298 static int
299 _gnutls_verify_sig (gnutls_cert * cert,
300 const gnutls_datum_t * hash_concat,
301 gnutls_datum_t * signature, size_t sha1pos)
303 int ret;
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
310 gnutls_assert ();
311 return GNUTLS_E_CERTIFICATE_ERROR;
314 /* If the certificate supports signing continue.
316 if (cert != NULL)
317 if (cert->key_usage != 0)
318 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
320 gnutls_assert ();
321 return GNUTLS_E_KEY_USAGE_VIOLATION;
324 switch (cert->subject_pk_algorithm)
326 case GNUTLS_PK_RSA:
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)
335 gnutls_assert ();
336 return ret;
339 break;
340 case GNUTLS_PK_DSA:
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)
349 gnutls_assert ();
350 return ret;
353 break;
355 default:
356 gnutls_assert ();
357 return GNUTLS_E_INTERNAL_ERROR;
362 return 0;
366 /* Verifies a TLS signature (like the one in the client certificate
367 * verify message).
370 _gnutls_verify_sig_hdata (gnutls_session_t session, gnutls_cert * cert,
371 gnutls_datum_t * signature)
373 int ret;
374 opaque concat[36];
375 digest_hd_st td_md5;
376 digest_hd_st td_sha;
377 gnutls_datum_t dconcat;
378 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
380 ret =
381 _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
382 if (ret < 0)
384 gnutls_assert ();
385 return ret;
388 ret =
389 _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
390 if (ret < 0)
392 gnutls_assert ();
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);
400 if (ret < 0)
402 gnutls_assert ();
403 return ret;
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);
413 else
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);
423 if (ret < 0)
425 gnutls_assert ();
426 return ret;
429 return ret;
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;
442 int ret;
443 digest_hd_st td_md5;
444 digest_hd_st td_sha;
445 opaque concat[36];
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);
451 if (ret < 0)
453 gnutls_assert ();
454 return ret;
457 _gnutls_hash (&td_md5, session->security_parameters.client_random,
458 GNUTLS_RANDOM_SIZE);
459 _gnutls_hash (&td_md5, session->security_parameters.server_random,
460 GNUTLS_RANDOM_SIZE);
461 _gnutls_hash (&td_md5, params->data, params->size);
464 ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
465 if (ret < 0)
467 gnutls_assert ();
468 if (!_gnutls_version_has_selectable_prf (ver))
469 _gnutls_hash_deinit (&td_md5, NULL);
470 return ret;
473 _gnutls_hash (&td_sha, session->security_parameters.client_random,
474 GNUTLS_RANDOM_SIZE);
475 _gnutls_hash (&td_sha, session->security_parameters.server_random,
476 GNUTLS_RANDOM_SIZE);
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]);
483 dconcat.size = 36;
485 else
487 #if 1
488 /* Use NULL parameters. */
489 memcpy (concat,
490 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
491 15);
492 _gnutls_hash_deinit (&td_sha, &concat[15]);
493 dconcat.size = 35;
494 #else
495 /* No parameters field. */
496 memcpy (concat,
497 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
498 _gnutls_hash_deinit (&td_sha, &concat[13]);
499 dconcat.size = 33;
500 #endif
503 dconcat.data = concat;
505 ret = _gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
506 if (ret < 0)
508 gnutls_assert ();
509 return ret;
512 return ret;