[openssl-users] Problems verifying OCSP signatures
Richard Moore
richmoore44 at gmail.com
Sun Dec 28 16:42:48 UTC 2014
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/20141228/a116b024/attachment.html>
More information about the openssl-users
mailing list