diff options
author | kn <> | 2022-07-17 17:00:44 +0000 |
---|---|---|
committer | kn <> | 2022-07-17 17:00:44 +0000 |
commit | 1f0b3b022cc983380c8af99bd43237db4deaa00a (patch) | |
tree | f730610d652050d411a902fe97d9faa735f8b70a /src/lib | |
parent | fcc47951fedaa68bf2527bded733b6c4019db61d (diff) | |
download | openbsd-1f0b3b022cc983380c8af99bd43237db4deaa00a.tar.gz openbsd-1f0b3b022cc983380c8af99bd43237db4deaa00a.tar.bz2 openbsd-1f0b3b022cc983380c8af99bd43237db4deaa00a.zip |
Add initial support for ESSCertIDv2 verification
Based on OpenSSL commit f0ef20bf386b5c37ba5a4ce5c1de9a819bbeffb2
"Added support for ESSCertIDv2".
This makes TS validation work in the new security/libdigidocpp port.
Input OK tb
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/ts/ts_rsp_verify.c | 118 |
1 files changed, 99 insertions, 19 deletions
diff --git a/src/lib/libcrypto/ts/ts_rsp_verify.c b/src/lib/libcrypto/ts/ts_rsp_verify.c index 24a7055177..ba916434b5 100644 --- a/src/lib/libcrypto/ts/ts_rsp_verify.c +++ b/src/lib/libcrypto/ts/ts_rsp_verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ts_rsp_verify.c,v 1.25 2022/07/16 16:42:58 kn Exp $ */ | 1 | /* $OpenBSD: ts_rsp_verify.c,v 1.26 2022/07/17 17:00:44 kn Exp $ */ |
2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL | 2 | /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL |
3 | * project 2002. | 3 | * project 2002. |
4 | */ | 4 | */ |
@@ -74,6 +74,8 @@ static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, | |||
74 | static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); | 74 | static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); |
75 | static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); | 75 | static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); |
76 | static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); | 76 | static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); |
77 | static ESS_SIGNING_CERT_V2 *ESS_get_signing_cert_v2(PKCS7_SIGNER_INFO *si); | ||
78 | static int TS_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert); | ||
77 | static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); | 79 | static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); |
78 | static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, | 80 | static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, |
79 | PKCS7 *token, TS_TST_INFO *tst_info); | 81 | PKCS7 *token, TS_TST_INFO *tst_info); |
@@ -272,36 +274,67 @@ err: | |||
272 | static int | 274 | static int |
273 | TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) | 275 | TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) |
274 | { | 276 | { |
275 | ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); | 277 | ESS_SIGNING_CERT *ss = NULL; |
276 | STACK_OF(ESS_CERT_ID) *cert_ids = NULL; | 278 | STACK_OF(ESS_CERT_ID) *cert_ids; |
279 | ESS_SIGNING_CERT_V2 *ssv2 = NULL; | ||
280 | STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2; | ||
277 | X509 *cert; | 281 | X509 *cert; |
278 | int i = 0; | 282 | int i = 0; |
279 | int ret = 0; | 283 | int ret = 0; |
280 | 284 | ||
281 | if (!ss) | 285 | if ((ss = ESS_get_signing_cert(si)) != NULL) { |
282 | goto err; | 286 | cert_ids = ss->cert_ids; |
283 | cert_ids = ss->cert_ids; | 287 | /* The signer certificate must be the first in cert_ids. */ |
284 | /* The signer certificate must be the first in cert_ids. */ | 288 | cert = sk_X509_value(chain, 0); |
285 | cert = sk_X509_value(chain, 0); | 289 | |
286 | if (TS_find_cert(cert_ids, cert) != 0) | 290 | if (TS_find_cert(cert_ids, cert) != 0) |
287 | goto err; | 291 | goto err; |
288 | 292 | ||
289 | /* Check the other certificates of the chain if there are more | 293 | /* |
290 | than one certificate ids in cert_ids. */ | 294 | * Check the other certificates of the chain if there are more |
291 | if (sk_ESS_CERT_ID_num(cert_ids) > 1) { | 295 | * than one certificate ids in cert_ids. |
292 | /* All the certificates of the chain must be in cert_ids. */ | 296 | */ |
293 | for (i = 1; i < sk_X509_num(chain); ++i) { | 297 | if (sk_ESS_CERT_ID_num(cert_ids) > 1) { |
294 | cert = sk_X509_value(chain, i); | 298 | /* All the certificates of the chain must be in cert_ids. */ |
295 | if (TS_find_cert(cert_ids, cert) < 0) | 299 | for (i = 1; i < sk_X509_num(chain); i++) { |
296 | goto err; | 300 | cert = sk_X509_value(chain, i); |
301 | |||
302 | if (TS_find_cert(cert_ids, cert) < 0) | ||
303 | goto err; | ||
304 | } | ||
297 | } | 305 | } |
298 | } | 306 | } |
307 | |||
308 | if ((ssv2 = ESS_get_signing_cert_v2(si)) != NULL) { | ||
309 | cert_ids_v2 = ssv2->cert_ids; | ||
310 | /* The signer certificate must be the first in cert_ids_v2. */ | ||
311 | cert = sk_X509_value(chain, 0); | ||
312 | |||
313 | if (TS_find_cert_v2(cert_ids_v2, cert) != 0) | ||
314 | goto err; | ||
315 | |||
316 | /* | ||
317 | * Check the other certificates of the chain if there are more | ||
318 | * than one certificate ids in cert_ids_v2. | ||
319 | */ | ||
320 | if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { | ||
321 | /* All the certificates of the chain must be in cert_ids_v2. */ | ||
322 | for (i = 1; i < sk_X509_num(chain); i++) { | ||
323 | cert = sk_X509_value(chain, i); | ||
324 | |||
325 | if (TS_find_cert_v2(cert_ids_v2, cert) < 0) | ||
326 | goto err; | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | |||
299 | ret = 1; | 331 | ret = 1; |
300 | 332 | ||
301 | err: | 333 | err: |
302 | if (!ret) | 334 | if (!ret) |
303 | TSerror(TS_R_ESS_SIGNING_CERTIFICATE_ERROR); | 335 | TSerror(TS_R_ESS_SIGNING_CERTIFICATE_ERROR); |
304 | ESS_SIGNING_CERT_free(ss); | 336 | ESS_SIGNING_CERT_free(ss); |
337 | ESS_SIGNING_CERT_V2_free(ssv2); | ||
305 | return ret; | 338 | return ret; |
306 | } | 339 | } |
307 | 340 | ||
@@ -321,6 +354,19 @@ ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) | |||
321 | return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); | 354 | return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); |
322 | } | 355 | } |
323 | 356 | ||
357 | static ESS_SIGNING_CERT_V2 * | ||
358 | ESS_get_signing_cert_v2(PKCS7_SIGNER_INFO *si) | ||
359 | { | ||
360 | ASN1_TYPE *attr; | ||
361 | const unsigned char *p; | ||
362 | |||
363 | attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2); | ||
364 | if (attr == NULL) | ||
365 | return NULL; | ||
366 | p = attr->value.sequence->data; | ||
367 | return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length); | ||
368 | } | ||
369 | |||
324 | /* Returns < 0 if certificate is not found, certificate index otherwise. */ | 370 | /* Returns < 0 if certificate is not found, certificate index otherwise. */ |
325 | static int | 371 | static int |
326 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | 372 | TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) |
@@ -346,7 +392,41 @@ TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) | |||
346 | cert_hash, TS_HASH_LEN)) { | 392 | cert_hash, TS_HASH_LEN)) { |
347 | /* Check the issuer/serial as well if specified. */ | 393 | /* Check the issuer/serial as well if specified. */ |
348 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | 394 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; |
349 | if (is == NULL || !TS_issuer_serial_cmp(is, cert)) | 395 | |
396 | if (is == NULL || TS_issuer_serial_cmp(is, cert) == 0) | ||
397 | return i; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | return -1; | ||
402 | } | ||
403 | |||
404 | /* Returns < 0 if certificate is not found, certificate index otherwise. */ | ||
405 | static int | ||
406 | TS_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert) | ||
407 | { | ||
408 | int i; | ||
409 | unsigned char cert_digest[EVP_MAX_MD_SIZE]; | ||
410 | unsigned int len; | ||
411 | |||
412 | /* Look for cert in the cert_ids vector. */ | ||
413 | for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) { | ||
414 | ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i); | ||
415 | const EVP_MD *md = EVP_sha256(); | ||
416 | |||
417 | if (cid->hash_alg != NULL) | ||
418 | md = EVP_get_digestbyobj(cid->hash_alg->algorithm); | ||
419 | |||
420 | if (!X509_digest(cert, md, cert_digest, &len)) | ||
421 | return -1; | ||
422 | |||
423 | if ((unsigned int)cid->hash->length != len) | ||
424 | return -1; | ||
425 | |||
426 | if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) { | ||
427 | ESS_ISSUER_SERIAL *is = cid->issuer_serial; | ||
428 | |||
429 | if (is == NULL || TS_issuer_serial_cmp(is, cert) == 0) | ||
350 | return i; | 430 | return i; |
351 | } | 431 | } |
352 | } | 432 | } |