summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorkn <>2022-07-17 17:00:44 +0000
committerkn <>2022-07-17 17:00:44 +0000
commit1f0b3b022cc983380c8af99bd43237db4deaa00a (patch)
treef730610d652050d411a902fe97d9faa735f8b70a /src/lib
parentfcc47951fedaa68bf2527bded733b6c4019db61d (diff)
downloadopenbsd-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.c118
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,
74static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); 74static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
75static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); 75static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
76static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); 76static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
77static ESS_SIGNING_CERT_V2 *ESS_get_signing_cert_v2(PKCS7_SIGNER_INFO *si);
78static int TS_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert);
77static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); 79static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert);
78static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, 80static 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:
272static int 274static int
273TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain) 275TS_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
301err: 333err:
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
357static ESS_SIGNING_CERT_V2 *
358ESS_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. */
325static int 371static int
326TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) 372TS_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. */
405static int
406TS_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 }