I've now got this working, though to do so I seem to have to take the certificates supplied in the OCSP response directly out of the certs field of the OCSP_BASICRESP and add these as intermediates for the verification too. It feels bad to directly access the internals of this struct but there doesn't seem to be another way (unless someone can enlighten me). Cheers Rich. On 28 December 2014 at 16:42, Richard Moore <richmoore44 at gmail.com> wrote: > Hi All, > > I'm trying to get some code to verify the signature of an OCSP response to > work properly and I'm hitting quite a few road blocks. I've also been > talking > to the curl developers who are having the same problems and I wondered if > anyone can help us. > > I've tried 3 different ways of handling the verification and none of them > seem > to work reliably. All 3 work properly for checking the OCSP status of > www.google.com, but they all fail when testing revoked.grc.com and > tn123.org. > I'm sure I must be doing something wrong, but I've no idea what and there > seems to be very little documentation in this area. I've put the 3 > approaches > I've tried below in case anyone has any ideas. Note that the reason all the > openssl symbols has a q_XXX prefix is just due to a dlopen shim and doesn't > change the behaviour of the functions at all. > > If anyone has any suggestions of what I'm doing wrong then please let me > know. > > Thanks > > Rich. > > /** > * This version takes the whole issuer chain, and adds them as > intermediates. > * It also sets up the CA store. > */ > bool QSslOcspReply::hasValidSignature1(const QList<QSslCertificate> > &issuers) const > { > // Create the certificate store > X509_STORE *certStore = q_X509_STORE_new(); > if (!certStore) { > qWarning() << "Unable to create certificate store"; > return false; > } > > // Build a stack to put the issuer in > STACK_OF(X509) *intermediates = 0; > intermediates = (STACK_OF(X509) *) q_sk_new_null(); > > if (!intermediates) { > q_X509_STORE_free(certStore); > return false; > } > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > foreach (const QSslCertificate &cert, issuers) > q_sk_push( (_STACK *)intermediates, reinterpret_cast<X509 > *>(cert.handle())); > #else > foreach (const QSslCertificate &cert, issuers) > q_sk_push( (STACK *)intermediates, reinterpret_cast<X509 > *>(cert.handle())); > #endif > > foreach (const QSslCertificate &caCertificate, > QSslSocket::defaultCaCertificates()) > q_X509_STORE_add_cert(certStore, (X509 *)caCertificate.handle()); > > int verifyResult = q_OCSP_basic_verify(d->basicresp, intermediates, > certStore, OCSP_TRUSTOTHER); > > // A verify result is a failure if it is 0 or less > if (verifyResult <= 0) { > unsigned long errnum = q_ERR_get_error(); > const char *error = q_ERR_error_string(errnum, 0); > > qDebug() << "OCSP response verification failed" << verifyResult; > qDebug() << "Error was: " << error; > // ### TODO: Fix mem leak > return false; > } > qDebug() << "OCSP response verification good"; > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > q_sk_free( (_STACK *) intermediates); > #else > q_sk_free( (STACK *) intermediates); > #endif > q_X509_STORE_free(certStore); > > return true; > } > > /** > * This version takes the whole issuer chain, and adds them as > intermediates. > * It does not set up any CAs. > */ > bool QSslOcspReply::hasValidSignature2(const QList<QSslCertificate> > &issuers) const > { > // Create the certificate store > X509_STORE *certStore = q_X509_STORE_new(); > if (!certStore) { > qWarning() << "Unable to create certificate store"; > return false; > } > > // Build a stack to put the issuer in > STACK_OF(X509) *intermediates = 0; > intermediates = (STACK_OF(X509) *) q_sk_new_null(); > > if (!intermediates) { > q_X509_STORE_free(certStore); > return false; > } > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > foreach (const QSslCertificate &cert, issuers) > q_sk_push( (_STACK *)intermediates, reinterpret_cast<X509 > *>(cert.handle())); > #else > foreach (const QSslCertificate &cert, issuers) > q_sk_push( (STACK *)intermediates, reinterpret_cast<X509 > *>(cert.handle())); > #endif > > int verifyResult = q_OCSP_basic_verify(d->basicresp, intermediates, > certStore, OCSP_TRUSTOTHER); > > // A verify result is a failure if it is 0 or less > if (verifyResult <= 0) { > unsigned long errnum = q_ERR_get_error(); > const char *error = q_ERR_error_string(errnum, 0); > > qDebug() << "OCSP response verification failed" << verifyResult; > qDebug() << "Error was: " << error; > // ### TODO: Fix mem leak > return false; > } > qDebug() << "OCSP response verification good"; > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > q_sk_free( (_STACK *) intermediates); > #else > q_sk_free( (STACK *) intermediates); > #endif > q_X509_STORE_free(certStore); > > return true; > } > > /** > * This version takes the just the actual issuer, and adds it as an > intermediate. > * It does not set up any CAs. > */ > bool QSslOcspReply::hasValidSignature3(const QSslCertificate &issuer) const > { > // Create the certificate store > X509_STORE *certStore = q_X509_STORE_new(); > if (!certStore) { > qWarning() << "Unable to create certificate store"; > return false; > } > > // Build a stack to put the issuer in > STACK_OF(X509) *intermediates = 0; > intermediates = (STACK_OF(X509) *) q_sk_new_null(); > > if (!intermediates) { > q_X509_STORE_free(certStore); > return false; > } > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > q_sk_push( (_STACK *)intermediates, reinterpret_cast<X509 > *>(issuer.handle())); > #else > q_sk_push( (STACK *)intermediates, reinterpret_cast<X509 > *>(issuer.handle())); > #endif > > int verifyResult = q_OCSP_basic_verify(d->basicresp, intermediates, > certStore, OCSP_TRUSTOTHER); > > // A verify result is a failure if it is 0 or less > if (verifyResult <= 0) { > unsigned long errnum = q_ERR_get_error(); > const char *error = q_ERR_error_string(errnum, 0); > > qDebug() << "OCSP response verification failed" << verifyResult; > qDebug() << "Error was: " << error; > // ### TODO: Fix mem leak > return false; > } > qDebug() << "OCSP response verification good"; > > #if OPENSSL_VERSION_NUMBER >= 0x10000000L > q_sk_free( (_STACK *) intermediates); > #else > q_sk_free( (STACK *) intermediates); > #endif > q_X509_STORE_free(certStore); > > return true; > } > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mta.opensslfoundation.net/pipermail/openssl-users/attachments/20150103/b32849be/attachment.html>