static VALUE ossl_x509stctx_set_trust(VALUE self, VALUE trust) { X509_STORE_CTX *store; long t = NUM2LONG(trust); GetX509StCtx(self, store); X509_STORE_CTX_set_trust(store, t); return trust; }
// 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; }