Line data Source code
1 : /*
2 : * Copyright (C) 2001-2012 Free Software Foundation, Inc.
3 : * Copyright (C) 2017 Red Hat, Inc.
4 : *
5 : * Author: Nikos Mavrogiannopoulos
6 : *
7 : * This file is part of GnuTLS.
8 : *
9 : * The GnuTLS 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.
13 : *
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.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : *
22 : */
23 :
24 : #include "gnutls_int.h"
25 : #include "errors.h"
26 : #include <x509_b64.h>
27 : #include <auth/cert.h>
28 : #include <algorithms.h>
29 : #include <datum.h>
30 : #include <mpi.h>
31 : #include <global.h>
32 : #include <pk.h>
33 : #include <debug.h>
34 : #include <buffers.h>
35 : #include <tls-sig.h>
36 : #include <kx.h>
37 : #include <libtasn1.h>
38 : #include <ext/signature.h>
39 : #include <state.h>
40 : #include <x509/common.h>
41 : #include <abstract_int.h>
42 :
43 9730 : int _gnutls_check_key_usage_for_sig(gnutls_session_t session, unsigned key_usage, unsigned our_cert)
44 : {
45 9730 : const char *lstr;
46 9730 : unsigned allow_key_usage_violation;
47 :
48 9730 : if (our_cert) {
49 7858 : lstr = "Local";
50 7858 : allow_key_usage_violation = session->internals.priorities->allow_server_key_usage_violation;
51 : } else {
52 1872 : lstr = "Peer's";
53 1872 : allow_key_usage_violation = session->internals.allow_key_usage_violation;
54 : }
55 :
56 9730 : if (key_usage != 0) {
57 3951 : if (!(key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) {
58 40 : gnutls_assert();
59 40 : if (likely(allow_key_usage_violation == 0)) {
60 37 : _gnutls_audit_log(session,
61 : "%s certificate does not allow digital signatures. Key usage violation detected.\n", lstr);
62 37 : return GNUTLS_E_KEY_USAGE_VIOLATION;
63 : } else {
64 3 : _gnutls_audit_log(session,
65 : "%s certificate does not allow digital signatures. Key usage violation detected (ignored).\n", lstr);
66 : }
67 : }
68 : }
69 : return 0;
70 : }
71 :
72 : /* Generates a signature of all the random data and the parameters.
73 : * Used in *DHE_* ciphersuites for TLS 1.2.
74 : */
75 : static int
76 2155 : _gnutls_handshake_sign_data12(gnutls_session_t session,
77 : gnutls_pcert_st * cert, gnutls_privkey_t pkey,
78 : gnutls_datum_t * params,
79 : gnutls_datum_t * signature,
80 : gnutls_sign_algorithm_t sign_algo)
81 : {
82 2155 : gnutls_datum_t dconcat;
83 2155 : int ret;
84 :
85 2155 : _gnutls_handshake_log
86 : ("HSK[%p]: signing TLS 1.2 handshake data: using %s\n", session,
87 : gnutls_sign_algorithm_get_name(sign_algo));
88 :
89 2155 : if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pkey->pk_algorithm) == 0))
90 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
91 :
92 2155 : dconcat.size = GNUTLS_RANDOM_SIZE*2 + params->size;
93 2155 : dconcat.data = gnutls_malloc(dconcat.size);
94 2155 : if (dconcat.data == NULL)
95 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
96 :
97 2155 : memcpy(dconcat.data, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
98 2155 : memcpy(dconcat.data+GNUTLS_RANDOM_SIZE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
99 2155 : memcpy(dconcat.data+GNUTLS_RANDOM_SIZE*2, params->data, params->size);
100 :
101 2155 : ret = gnutls_privkey_sign_data2(pkey, sign_algo,
102 : 0, &dconcat, signature);
103 2155 : if (ret < 0) {
104 0 : gnutls_assert();
105 : }
106 2155 : gnutls_free(dconcat.data);
107 :
108 2155 : return ret;
109 :
110 : }
111 :
112 : static int
113 1452 : _gnutls_handshake_sign_data10(gnutls_session_t session,
114 : gnutls_pcert_st * cert, gnutls_privkey_t pkey,
115 : gnutls_datum_t * params,
116 : gnutls_datum_t * signature,
117 : gnutls_sign_algorithm_t sign_algo)
118 : {
119 1452 : gnutls_datum_t dconcat;
120 1452 : int ret;
121 1452 : digest_hd_st td_sha;
122 1452 : uint8_t concat[MAX_SIG_SIZE];
123 1452 : const mac_entry_st *me;
124 1452 : gnutls_pk_algorithm_t pk_algo;
125 :
126 1452 : pk_algo = gnutls_privkey_get_pk_algorithm(pkey, NULL);
127 1452 : if (pk_algo == GNUTLS_PK_RSA)
128 1362 : me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
129 : else
130 90 : me = hash_to_entry(
131 : gnutls_sign_get_hash_algorithm(sign_algo));
132 1452 : if (me == NULL)
133 0 : return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
134 :
135 1452 : if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pk_algo) == 0))
136 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
137 :
138 1452 : pk_algo = gnutls_sign_get_pk_algorithm(sign_algo);
139 1452 : if (pk_algo == GNUTLS_PK_UNKNOWN)
140 0 : return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
141 :
142 1452 : _gnutls_handshake_log
143 : ("HSK[%p]: signing handshake data: using %s\n", session,
144 : gnutls_sign_algorithm_get_name(sign_algo));
145 :
146 1452 : ret = _gnutls_hash_init(&td_sha, me);
147 1452 : if (ret < 0) {
148 0 : gnutls_assert();
149 0 : return ret;
150 : }
151 :
152 1452 : _gnutls_hash(&td_sha, session->security_parameters.client_random,
153 : GNUTLS_RANDOM_SIZE);
154 1452 : _gnutls_hash(&td_sha, session->security_parameters.server_random,
155 : GNUTLS_RANDOM_SIZE);
156 1452 : _gnutls_hash(&td_sha, params->data, params->size);
157 :
158 1452 : _gnutls_hash_deinit(&td_sha, concat);
159 :
160 1452 : dconcat.data = concat;
161 1452 : dconcat.size = _gnutls_hash_get_algo_len(me);
162 :
163 1452 : ret = gnutls_privkey_sign_hash(pkey, MAC_TO_DIG(me->id), GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
164 : &dconcat, signature);
165 1452 : if (ret < 0) {
166 0 : gnutls_assert();
167 : }
168 :
169 : return ret;
170 : }
171 :
172 : /* Generates a signature of all the random data and the parameters.
173 : * Used in DHE_* ciphersuites.
174 : */
175 : int
176 3608 : _gnutls_handshake_sign_data(gnutls_session_t session,
177 : gnutls_pcert_st * cert, gnutls_privkey_t pkey,
178 : gnutls_datum_t * params,
179 : gnutls_datum_t * signature,
180 : gnutls_sign_algorithm_t * sign_algo)
181 : {
182 3608 : const version_entry_st *ver = get_version(session);
183 3608 : unsigned key_usage = 0;
184 3608 : int ret;
185 :
186 3608 : *sign_algo = session->security_parameters.server_sign_algo;
187 3608 : if (*sign_algo == GNUTLS_SIGN_UNKNOWN) {
188 1 : gnutls_assert();
189 1 : return GNUTLS_E_UNWANTED_ALGORITHM;
190 : }
191 :
192 3607 : gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
193 :
194 3607 : ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
195 3607 : if (ret < 0)
196 0 : return gnutls_assert_val(ret);
197 :
198 3607 : if (_gnutls_version_has_selectable_sighash(ver))
199 2155 : return _gnutls_handshake_sign_data12(session, cert, pkey, params, signature, *sign_algo);
200 : else
201 1452 : return _gnutls_handshake_sign_data10(session, cert, pkey, params, signature, *sign_algo);
202 : }
203 :
204 : /* Generates a signature of all the random data and the parameters.
205 : * Used in DHE_* ciphersuites.
206 : */
207 : static int
208 133 : _gnutls_handshake_verify_data10(gnutls_session_t session,
209 : unsigned verify_flags,
210 : gnutls_pcert_st * cert,
211 : const gnutls_datum_t * params,
212 : gnutls_datum_t * signature,
213 : gnutls_sign_algorithm_t sign_algo)
214 : {
215 133 : gnutls_datum_t dconcat;
216 133 : int ret;
217 133 : digest_hd_st td_sha;
218 133 : uint8_t concat[MAX_SIG_SIZE];
219 133 : gnutls_digest_algorithm_t hash_algo;
220 133 : const mac_entry_st *me;
221 133 : gnutls_pk_algorithm_t pk_algo;
222 :
223 133 : pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
224 133 : if (pk_algo == GNUTLS_PK_RSA) {
225 74 : hash_algo = GNUTLS_DIG_MD5_SHA1;
226 74 : verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
227 : } else {
228 59 : hash_algo = GNUTLS_DIG_SHA1;
229 59 : if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
230 59 : sign_algo = gnutls_pk_to_sign(pk_algo, hash_algo);
231 : }
232 : }
233 :
234 133 : me = hash_to_entry(hash_algo);
235 :
236 133 : ret = _gnutls_hash_init(&td_sha, me);
237 133 : if (ret < 0) {
238 0 : gnutls_assert();
239 0 : return ret;
240 : }
241 :
242 133 : _gnutls_hash(&td_sha, session->security_parameters.client_random,
243 : GNUTLS_RANDOM_SIZE);
244 133 : _gnutls_hash(&td_sha, session->security_parameters.server_random,
245 : GNUTLS_RANDOM_SIZE);
246 133 : _gnutls_hash(&td_sha, params->data, params->size);
247 :
248 133 : _gnutls_hash_deinit(&td_sha, concat);
249 :
250 133 : dconcat.data = concat;
251 133 : dconcat.size = _gnutls_hash_get_algo_len(me);
252 :
253 133 : ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
254 : GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
255 : &dconcat, signature);
256 133 : if (ret < 0)
257 5 : return gnutls_assert_val(ret);
258 :
259 : return ret;
260 : }
261 :
262 : static int
263 703 : _gnutls_handshake_verify_data12(gnutls_session_t session,
264 : unsigned verify_flags,
265 : gnutls_pcert_st * cert,
266 : const gnutls_datum_t * params,
267 : gnutls_datum_t * signature,
268 : gnutls_sign_algorithm_t sign_algo)
269 : {
270 703 : gnutls_datum_t dconcat;
271 703 : int ret;
272 703 : const version_entry_st *ver = get_version(session);
273 703 : const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign_algo);
274 :
275 703 : _gnutls_handshake_log
276 : ("HSK[%p]: verify TLS 1.2 handshake data: using %s\n", session,
277 : se->name);
278 :
279 703 : ret =
280 703 : _gnutls_pubkey_compatible_with_sig(session,
281 : cert->pubkey, ver,
282 : sign_algo);
283 703 : if (ret < 0)
284 3 : return gnutls_assert_val(ret);
285 :
286 1400 : if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) {
287 0 : _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n",
288 : session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name);
289 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
290 : }
291 :
292 700 : ret =
293 700 : _gnutls_session_sign_algo_enabled(session, sign_algo);
294 700 : if (ret < 0)
295 0 : return gnutls_assert_val(ret);
296 :
297 700 : dconcat.size = GNUTLS_RANDOM_SIZE*2+params->size;
298 700 : dconcat.data = gnutls_malloc(dconcat.size);
299 700 : if (dconcat.data == NULL)
300 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
301 :
302 700 : memcpy(dconcat.data, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
303 700 : memcpy(dconcat.data+GNUTLS_RANDOM_SIZE, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
304 700 : memcpy(dconcat.data+GNUTLS_RANDOM_SIZE*2, params->data, params->size);
305 :
306 : /* Here we intentionally enable flag GNUTLS_VERIFY_ALLOW_BROKEN
307 : * because we have checked whether the currently used signature
308 : * algorithm is allowed in the session. */
309 700 : ret = gnutls_pubkey_verify_data2(cert->pubkey, sign_algo, verify_flags|GNUTLS_VERIFY_ALLOW_BROKEN,
310 : &dconcat, signature);
311 700 : if (ret < 0)
312 19 : gnutls_assert();
313 :
314 700 : gnutls_free(dconcat.data);
315 :
316 700 : return ret;
317 : }
318 :
319 : int
320 840 : _gnutls_handshake_verify_data(gnutls_session_t session,
321 : unsigned verify_flags,
322 : gnutls_pcert_st * cert,
323 : const gnutls_datum_t * params,
324 : gnutls_datum_t * signature,
325 : gnutls_sign_algorithm_t sign_algo)
326 : {
327 840 : unsigned key_usage;
328 840 : int ret;
329 840 : const version_entry_st *ver = get_version(session);
330 :
331 840 : if (cert == NULL) {
332 0 : gnutls_assert();
333 0 : return GNUTLS_E_CERTIFICATE_ERROR;
334 : }
335 :
336 840 : gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
337 :
338 840 : ret = _gnutls_check_key_usage_for_sig(session, key_usage, 0);
339 840 : if (ret < 0)
340 4 : return gnutls_assert_val(ret);
341 :
342 836 : gnutls_sign_algorithm_set_server(session, sign_algo);
343 :
344 836 : if (_gnutls_version_has_selectable_sighash(ver))
345 703 : return _gnutls_handshake_verify_data12(session, verify_flags, cert, params, signature, sign_algo);
346 : else
347 133 : return _gnutls_handshake_verify_data10(session, verify_flags, cert, params, signature, sign_algo);
348 : }
349 :
350 :
351 : /* Client certificate verify calculations
352 : */
353 :
354 : static void
355 3 : _gnutls_reverse_datum(gnutls_datum_t * d)
356 : {
357 3 : unsigned i;
358 :
359 131 : for (i = 0; i < d->size / 2; i ++) {
360 128 : uint8_t t = d->data[i];
361 128 : d->data[i] = d->data[d->size - 1 - i];
362 128 : d->data[d->size - 1 - i] = t;
363 : }
364 3 : }
365 :
366 : static int
367 3 : _gnutls_create_reverse(const gnutls_datum_t *src, gnutls_datum_t *dst)
368 : {
369 3 : unsigned int i;
370 :
371 3 : dst->size = src->size;
372 3 : dst->data = gnutls_malloc(dst->size);
373 3 : if (!dst->data)
374 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
375 :
376 259 : for (i = 0; i < dst->size; i++)
377 256 : dst->data[i] = src->data[dst->size - 1 - i];
378 :
379 : return 0;
380 : }
381 :
382 : /* this is _gnutls_handshake_verify_crt_vrfy for TLS 1.2
383 : */
384 : static int
385 407 : _gnutls_handshake_verify_crt_vrfy12(gnutls_session_t session,
386 : unsigned verify_flags,
387 : gnutls_pcert_st * cert,
388 : gnutls_datum_t * signature,
389 : gnutls_sign_algorithm_t sign_algo)
390 : {
391 407 : int ret;
392 407 : gnutls_datum_t dconcat;
393 407 : const gnutls_sign_entry_st *se = _gnutls_sign_to_entry(sign_algo);
394 407 : gnutls_datum_t sig_rev = {NULL, 0};
395 :
396 407 : ret = _gnutls_session_sign_algo_enabled(session, sign_algo);
397 407 : if (ret < 0)
398 0 : return gnutls_assert_val(ret);
399 :
400 814 : if (unlikely(sign_supports_cert_pk_algorithm(se, cert->pubkey->params.algo) == 0)) {
401 8 : _gnutls_handshake_log("HSK[%p]: certificate of %s cannot be combined with %s sig\n",
402 : session, gnutls_pk_get_name(cert->pubkey->params.algo), se->name);
403 16 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
404 : }
405 :
406 399 : if (se->flags & GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE) {
407 3 : ret = _gnutls_create_reverse(signature, &sig_rev);
408 3 : if (ret < 0)
409 0 : return gnutls_assert_val(ret);
410 : }
411 :
412 399 : dconcat.data = session->internals.handshake_hash_buffer.data;
413 399 : dconcat.size = session->internals.handshake_hash_buffer_prev_len;
414 :
415 : /* Here we intentionally enable flag GNUTLS_VERIFY_ALLOW_BROKEN
416 : * because we have checked whether the currently used signature
417 : * algorithm is allowed in the session. */
418 399 : ret = gnutls_pubkey_verify_data2(cert->pubkey, sign_algo, verify_flags|GNUTLS_VERIFY_ALLOW_BROKEN,
419 : &dconcat,
420 399 : sig_rev.data ? &sig_rev : signature);
421 399 : _gnutls_free_datum(&sig_rev);
422 399 : if (ret < 0)
423 226 : gnutls_assert();
424 :
425 : return ret;
426 :
427 : }
428 :
429 : /* Verifies a SSL 3.0 signature (like the one in the client certificate
430 : * verify message).
431 : */
432 : #ifdef ENABLE_SSL3
433 : static int
434 : _gnutls_handshake_verify_crt_vrfy3(gnutls_session_t session,
435 : unsigned verify_flags,
436 : gnutls_pcert_st * cert,
437 : gnutls_datum_t * signature,
438 : gnutls_sign_algorithm_t sign_algo)
439 : {
440 : int ret;
441 : uint8_t concat[MAX_SIG_SIZE];
442 : digest_hd_st td_sha;
443 : gnutls_datum_t dconcat;
444 : gnutls_pk_algorithm_t pk =
445 : gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
446 :
447 : ret = _gnutls_generate_master(session, 1);
448 : if (ret < 0) {
449 : return gnutls_assert_val(ret);
450 : }
451 :
452 : dconcat.data = concat;
453 : dconcat.size = 0;
454 :
455 : if (pk == GNUTLS_PK_RSA) {
456 : digest_hd_st td_md5;
457 :
458 : ret = _gnutls_hash_init(&td_md5,
459 : hash_to_entry(GNUTLS_DIG_MD5));
460 : if (ret < 0)
461 : return gnutls_assert_val(ret);
462 :
463 : _gnutls_hash(&td_md5,
464 : session->internals.handshake_hash_buffer.data,
465 : session->internals.handshake_hash_buffer_prev_len);
466 :
467 : ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5, concat,
468 : session->security_parameters.
469 : master_secret,
470 : GNUTLS_MASTER_SIZE);
471 : if (ret < 0)
472 : return gnutls_assert_val(ret);
473 :
474 : verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
475 : dconcat.size = 16;
476 : }
477 :
478 : ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1));
479 : if (ret < 0) {
480 : gnutls_assert();
481 : return GNUTLS_E_HASH_FAILED;
482 : }
483 :
484 : _gnutls_hash(&td_sha,
485 : session->internals.handshake_hash_buffer.data,
486 : session->internals.handshake_hash_buffer_prev_len);
487 :
488 : ret =
489 : _gnutls_mac_deinit_ssl3_handshake(&td_sha,
490 : dconcat.data + dconcat.size,
491 : session->security_parameters.
492 : master_secret,
493 : GNUTLS_MASTER_SIZE);
494 : if (ret < 0) {
495 : return gnutls_assert_val(ret);
496 : }
497 :
498 : dconcat.size += 20;
499 :
500 : ret = gnutls_pubkey_verify_hash2(cert->pubkey, GNUTLS_SIGN_UNKNOWN,
501 : GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
502 : &dconcat, signature);
503 : if (ret < 0)
504 : return gnutls_assert_val(ret);
505 :
506 : return ret;
507 : }
508 : #endif
509 :
510 : static int
511 80 : _gnutls_handshake_verify_crt_vrfy10(gnutls_session_t session,
512 : unsigned verify_flags,
513 : gnutls_pcert_st * cert,
514 : gnutls_datum_t * signature,
515 : gnutls_sign_algorithm_t sign_algo)
516 : {
517 80 : int ret;
518 80 : uint8_t concat[MAX_SIG_SIZE];
519 80 : digest_hd_st td_sha;
520 80 : gnutls_datum_t dconcat;
521 80 : gnutls_pk_algorithm_t pk_algo;
522 80 : const mac_entry_st *me;
523 :
524 : /* TLS 1.0 and TLS 1.1 */
525 80 : pk_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
526 80 : if (pk_algo == GNUTLS_PK_RSA) {
527 58 : me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
528 58 : verify_flags |= GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA;
529 58 : sign_algo = GNUTLS_SIGN_UNKNOWN;
530 : } else {
531 22 : me = hash_to_entry(GNUTLS_DIG_SHA1);
532 22 : sign_algo = gnutls_pk_to_sign(pk_algo, GNUTLS_DIG_SHA1);
533 : }
534 80 : ret = _gnutls_hash_init(&td_sha, me);
535 80 : if (ret < 0) {
536 0 : gnutls_assert();
537 0 : return ret;
538 : }
539 :
540 160 : _gnutls_hash(&td_sha,
541 80 : session->internals.handshake_hash_buffer.data,
542 80 : session->internals.handshake_hash_buffer_prev_len);
543 :
544 80 : _gnutls_hash_deinit(&td_sha, concat);
545 :
546 80 : dconcat.data = concat;
547 80 : dconcat.size = _gnutls_hash_get_algo_len(me);
548 :
549 80 : ret = gnutls_pubkey_verify_hash2(cert->pubkey, sign_algo,
550 : GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1|verify_flags,
551 : &dconcat, signature);
552 80 : if (ret < 0)
553 0 : gnutls_assert();
554 :
555 : return ret;
556 : }
557 :
558 : /* Verifies a TLS signature (like the one in the client certificate
559 : * verify message).
560 : */
561 : int
562 488 : _gnutls_handshake_verify_crt_vrfy(gnutls_session_t session,
563 : unsigned verify_flags,
564 : gnutls_pcert_st * cert,
565 : gnutls_datum_t * signature,
566 : gnutls_sign_algorithm_t sign_algo)
567 : {
568 488 : int ret;
569 488 : const version_entry_st *ver = get_version(session);
570 488 : unsigned key_usage;
571 :
572 488 : if (cert == NULL) {
573 0 : gnutls_assert();
574 0 : return GNUTLS_E_CERTIFICATE_ERROR;
575 : }
576 :
577 488 : gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
578 :
579 488 : ret = _gnutls_check_key_usage_for_sig(session, key_usage, 0);
580 488 : if (ret < 0)
581 1 : return gnutls_assert_val(ret);
582 :
583 487 : _gnutls_handshake_log("HSK[%p]: verify cert vrfy: using %s\n",
584 : session,
585 : gnutls_sign_algorithm_get_name(sign_algo));
586 :
587 487 : if (unlikely(ver == NULL))
588 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
589 :
590 487 : gnutls_sign_algorithm_set_client(session, sign_algo);
591 :
592 : /* TLS 1.2 */
593 487 : if (_gnutls_version_has_selectable_sighash(ver))
594 407 : return _gnutls_handshake_verify_crt_vrfy12(session,
595 : verify_flags,
596 : cert,
597 : signature,
598 : sign_algo);
599 : #ifdef ENABLE_SSL3
600 : if (ver->id == GNUTLS_SSL3)
601 : return _gnutls_handshake_verify_crt_vrfy3(session,
602 : verify_flags,
603 : cert,
604 : signature,
605 : sign_algo);
606 : #endif
607 :
608 : /* TLS 1.0 and TLS 1.1 */
609 80 : return _gnutls_handshake_verify_crt_vrfy10(session,
610 : verify_flags,
611 : cert,
612 : signature,
613 : sign_algo);
614 : }
615 :
616 : /* the same as _gnutls_handshake_sign_crt_vrfy except that it is made for TLS 1.2.
617 : * Returns the used signature algorithm, or a negative error code.
618 : */
619 : static int
620 73 : _gnutls_handshake_sign_crt_vrfy12(gnutls_session_t session,
621 : gnutls_pcert_st * cert,
622 : gnutls_privkey_t pkey,
623 : gnutls_datum_t * signature)
624 : {
625 73 : gnutls_datum_t dconcat;
626 73 : gnutls_sign_algorithm_t sign_algo;
627 73 : const gnutls_sign_entry_st *se;
628 73 : int ret;
629 :
630 73 : sign_algo = _gnutls_session_get_sign_algo(session, cert, pkey, 1, GNUTLS_KX_UNKNOWN);
631 73 : if (sign_algo == GNUTLS_SIGN_UNKNOWN) {
632 1 : gnutls_assert();
633 1 : return GNUTLS_E_UNWANTED_ALGORITHM;
634 : }
635 :
636 72 : se = _gnutls_sign_to_entry(sign_algo);
637 72 : if (se == NULL)
638 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
639 :
640 72 : gnutls_sign_algorithm_set_client(session, sign_algo);
641 :
642 72 : if (unlikely(gnutls_sign_supports_pk_algorithm(sign_algo, pkey->pk_algorithm) == 0))
643 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
644 :
645 72 : _gnutls_debug_log("sign handshake cert vrfy: picked %s\n",
646 : gnutls_sign_algorithm_get_name(sign_algo));
647 :
648 72 : dconcat.data = session->internals.handshake_hash_buffer.data;
649 72 : dconcat.size = session->internals.handshake_hash_buffer.length;
650 :
651 72 : ret = gnutls_privkey_sign_data2(pkey, sign_algo,
652 : 0, &dconcat, signature);
653 72 : if (ret < 0) {
654 0 : gnutls_assert();
655 0 : return ret;
656 : }
657 :
658 72 : if (se->flags & GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE)
659 3 : _gnutls_reverse_datum(signature);
660 :
661 72 : return sign_algo;
662 : }
663 :
664 : #ifdef ENABLE_SSL3
665 : static int
666 : _gnutls_handshake_sign_crt_vrfy3(gnutls_session_t session,
667 : gnutls_pcert_st * cert,
668 : const version_entry_st *ver,
669 : gnutls_privkey_t pkey,
670 : gnutls_datum_t * signature)
671 : {
672 : gnutls_datum_t dconcat;
673 : int ret;
674 : uint8_t concat[MAX_SIG_SIZE];
675 : digest_hd_st td_sha;
676 : gnutls_pk_algorithm_t pk =
677 : gnutls_privkey_get_pk_algorithm(pkey, NULL);
678 :
679 : /* ensure 1024 bit DSA keys are used */
680 : ret =
681 : _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver,
682 : GNUTLS_SIGN_UNKNOWN);
683 : if (ret < 0)
684 : return gnutls_assert_val(ret);
685 :
686 : ret = _gnutls_generate_master(session, 1);
687 : if (ret < 0) {
688 : gnutls_assert();
689 : return ret;
690 : }
691 :
692 : dconcat.data = concat;
693 : dconcat.size = 0;
694 :
695 : if (pk == GNUTLS_PK_RSA) {
696 : digest_hd_st td_md5;
697 : ret =
698 : _gnutls_hash_init(&td_md5,
699 : hash_to_entry(GNUTLS_DIG_MD5));
700 : if (ret < 0)
701 : return gnutls_assert_val(ret);
702 :
703 : _gnutls_hash(&td_md5,
704 : session->internals.handshake_hash_buffer.data,
705 : session->internals.handshake_hash_buffer.
706 : length);
707 :
708 : ret = _gnutls_mac_deinit_ssl3_handshake(&td_md5,
709 : dconcat.data,
710 : session->security_parameters.
711 : master_secret,
712 : GNUTLS_MASTER_SIZE);
713 : if (ret < 0)
714 : return gnutls_assert_val(ret);
715 :
716 : dconcat.size = 16;
717 : }
718 :
719 : ret = _gnutls_hash_init(&td_sha, hash_to_entry(GNUTLS_DIG_SHA1));
720 : if (ret < 0) {
721 : gnutls_assert();
722 : return ret;
723 : }
724 :
725 : _gnutls_hash(&td_sha,
726 : session->internals.handshake_hash_buffer.data,
727 : session->internals.handshake_hash_buffer.length);
728 : ret =
729 : _gnutls_mac_deinit_ssl3_handshake(&td_sha,
730 : dconcat.data + dconcat.size,
731 : session->security_parameters.
732 : master_secret,
733 : GNUTLS_MASTER_SIZE);
734 : if (ret < 0)
735 : return gnutls_assert_val(ret);
736 :
737 : dconcat.size += 20;
738 :
739 : ret = gnutls_privkey_sign_hash(pkey, GNUTLS_DIG_SHA1,
740 : GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
741 : &dconcat, signature);
742 : if (ret < 0)
743 : return gnutls_assert_val(ret);
744 :
745 : return GNUTLS_SIGN_UNKNOWN;
746 : }
747 : #endif
748 :
749 : static int
750 58 : _gnutls_handshake_sign_crt_vrfy10(gnutls_session_t session,
751 : gnutls_pcert_st * cert,
752 : const version_entry_st *ver,
753 : gnutls_privkey_t pkey,
754 : gnutls_datum_t * signature)
755 : {
756 58 : gnutls_datum_t dconcat;
757 58 : int ret;
758 58 : uint8_t concat[MAX_SIG_SIZE];
759 58 : digest_hd_st td_sha;
760 116 : gnutls_pk_algorithm_t pk =
761 58 : gnutls_privkey_get_pk_algorithm(pkey, NULL);
762 58 : const mac_entry_st *me;
763 :
764 : /* ensure 1024 bit DSA keys are used */
765 58 : ret =
766 58 : _gnutls_pubkey_compatible_with_sig(session, cert->pubkey, ver,
767 : GNUTLS_SIGN_UNKNOWN);
768 58 : if (ret < 0)
769 2 : return gnutls_assert_val(ret);
770 :
771 56 : if (pk == GNUTLS_PK_RSA)
772 49 : me = hash_to_entry(GNUTLS_DIG_MD5_SHA1);
773 : else
774 7 : me = hash_to_entry(GNUTLS_DIG_SHA1);
775 :
776 56 : ret = _gnutls_hash_init(&td_sha, me);
777 56 : if (ret < 0) {
778 0 : gnutls_assert();
779 0 : return ret;
780 : }
781 :
782 112 : _gnutls_hash(&td_sha,
783 56 : session->internals.handshake_hash_buffer.data,
784 : session->internals.handshake_hash_buffer.length);
785 :
786 56 : _gnutls_hash_deinit(&td_sha, concat);
787 :
788 56 : dconcat.data = concat;
789 56 : dconcat.size = _gnutls_hash_get_algo_len(me);
790 :
791 56 : ret = gnutls_privkey_sign_hash(pkey, MAC_TO_DIG(me->id), GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
792 : &dconcat, signature);
793 56 : if (ret < 0) {
794 0 : gnutls_assert();
795 0 : return ret;
796 : }
797 :
798 : return GNUTLS_SIGN_UNKNOWN;
799 : }
800 :
801 : /* Generates a signature of all the previous sent packets in the
802 : * handshake procedure.
803 : * 20040227: now it works for SSL 3.0 as well
804 : * 20091031: works for TLS 1.2 too!
805 : *
806 : * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
807 : * For TLS1.2 returns the signature algorithm used on success, or a negative error code;
808 : *
809 : * Returns the used signature algorithm, or a negative error code.
810 : */
811 : int
812 131 : _gnutls_handshake_sign_crt_vrfy(gnutls_session_t session,
813 : gnutls_pcert_st * cert,
814 : gnutls_privkey_t pkey,
815 : gnutls_datum_t * signature)
816 : {
817 131 : int ret;
818 131 : const version_entry_st *ver = get_version(session);
819 131 : unsigned key_usage = 0;
820 :
821 131 : if (unlikely(ver == NULL))
822 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
823 :
824 131 : gnutls_pubkey_get_key_usage(cert->pubkey, &key_usage);
825 :
826 131 : ret = _gnutls_check_key_usage_for_sig(session, key_usage, 1);
827 131 : if (ret < 0)
828 0 : return gnutls_assert_val(ret);
829 :
830 : /* TLS 1.2 */
831 131 : if (_gnutls_version_has_selectable_sighash(ver))
832 73 : return _gnutls_handshake_sign_crt_vrfy12(session, cert,
833 : pkey, signature);
834 :
835 : /* TLS 1.1 or earlier */
836 : #ifdef ENABLE_SSL3
837 : if (ver->id == GNUTLS_SSL3)
838 : return _gnutls_handshake_sign_crt_vrfy3(session, cert, ver,
839 : pkey, signature);
840 : #endif
841 :
842 58 : return _gnutls_handshake_sign_crt_vrfy10(session, cert, ver,
843 : pkey, signature);
844 : }
|