diff options
Diffstat (limited to '')
| -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 | } |
