+
+ /* If we trust the signer, we don't need to build a chain.
+ * (If the signer is a root certificate, X509_verify_cert()
+ * would fail anyway!)
+ */
+ if (chain == certs) goto verified_chain;
+
+ /* If we trust some "other" certificates, mark them as
+ * explicitly trusted (because some of them might be
+ * Intermediate CA Certificates), put them in a store and
+ * attempt to build a trusted chain.
+ */
+ if ((flags & OCSP_TRUSTOTHER) && (certs != NULL))
+ {
+ ASN1_OBJECT *objtmp = OBJ_nid2obj(NID_OCSP_sign);
+ tmpstore = X509_STORE_new();
+ if (!tmpstore)
+ {
+ ret = -1;
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+ for (i = 0; i < sk_X509_num(certs); i++)
+ {
+ X509 *xother = sk_X509_value(certs, i);
+ X509_add1_trust_object(xother, objtmp);
+ if (!X509_STORE_add_cert(tmpstore, xother))
+ {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ init_res = X509_STORE_CTX_init(&ctx, tmpstore, signer, NULL);
+ if (!init_res)
+ {
+ ret = -1;
+ OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
+ goto end;
+ }
+ X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
+ ret = X509_verify_cert(&ctx);
+ if (ret == 1)
+ {
+ chain = tmpchain = X509_STORE_CTX_get1_chain(&ctx);
+ X509_STORE_CTX_cleanup(&ctx);
+ goto verified_chain;
+ }
+ X509_STORE_CTX_cleanup(&ctx);
+ }
+
+ /* Attempt to build a chain up to a Root Certificate in the
+ * trust store provided by the caller.
+ */