int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si) { PKCS7_ISSUER_AND_SERIAL *ias; int ret = 0, i; STACK_OF(X509) *cert; X509 *x509; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); return 0; } if (PKCS7_type_is_signed(p7)) { cert = p7->d.sign->cert; } else if (PKCS7_type_is_signedAndEnveloped(p7)) { cert = p7->d.signed_and_enveloped->cert; } else { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); goto err; } /* XXXX */ ias = si->issuer_and_serial; x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); /* were we able to find the cert in passed to us */ if (x509 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); goto err; } /* Lets verify */ if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); goto err; } X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); i = X509_verify_cert(ctx); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); X509_STORE_CTX_cleanup(ctx); goto err; } X509_STORE_CTX_cleanup(ctx); return PKCS7_signatureVerify(bio, p7, si, x509); err: return ret; }
static VALUE ossl_x509stctx_set_purpose(VALUE self, VALUE purpose) { X509_STORE_CTX *store; long p = NUM2LONG(purpose); GetX509StCtx(self, store); X509_STORE_CTX_set_purpose(store, p); return purpose; }
// VerifyChain verifies the certificate chain in chain // according to the verification options given as opts. bool X509VerifierPrivate::VerifyChain(std::vector<X509Certificate> chain, const X509VerifierOptions &opts) { bool status = false; X509_STORE_CTX *ctx = X509_STORE_CTX_new(); STACK_OF(X509) *untrusted = sk_X509_new_null(); // Ensure that we have a chain to check on. if (chain.empty()) { goto out; } // If we've been passed a DNS name in opts, // we should check whether the leaf certificate // matches that before doing the more expensive // checks. if (!opts.dns_name.empty()) { if (!X509HostnameVerifier::VerifyHostname(chain.at(0), opts.dns_name)) { std::cerr << "X509VerifierPrivate - hostname verification failed" << std::endl; goto out; } } // Extract our chain into the format that OpenSSL // expects for verification. for (X509Certificate &cert : chain) { X509 *cur = cert.dptr_->AsOpenSSLX509(); sk_X509_push(untrusted, cur); } // Set up the X509_STORE_CTX to verify according to opts. X509_STORE_CTX_init(ctx, store_, sk_X509_value(untrusted, 0), untrusted); // If a time is not specified in opts, use the current system time. if (opts.time == 0) { X509_STORE_CTX_set_time(ctx, 0, std::time(nullptr)); } else { X509_STORE_CTX_set_time(ctx, 0, opts.time); } // If a dns_name is specified in opts, use the SSL server policy. if (!opts.dns_name.empty()) { X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SSL_SERVER); X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER); } if (X509_verify_cert(ctx) == 1) { status = true; } else { std::cerr << "X509VerifierPrivate - verification error: " << X509_verify_cert_error_string(ctx->error) << std::endl; } out: sk_X509_pop_free(untrusted, X509_free); X509_STORE_CTX_free(ctx); return status; }