[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