Hi,

I need to verify a X.509 certificate against a self-signed X.509 CA, both 
certificates are in PEM-format. Doing this on the command line works so far:
openssl verify -CAfile caCertificate.pem certificate.pem
certificate.pem: OK
The version of OpenSSL is: 1.0.0j-fips 10 May 2012.

Right now I am working on a small piece of code that is supposed to do the same 
from C++ using the X509_verify_cert function.

The problem is: The verification always fails with error code 7 (“signature 
invalid”). I already tried three different attempts (documented in the attached 
cpp file) to build the trust chain, with the same result.

The relevant source code (certificates as char arrays included in the cpp) and 
both certificates are attached. I would be very grateful if you could give me a 
hint. Right now I am a little lost.

Thanks in advance & Best regards,

Arthur
________________________________

Dipl.-Math. Arthur Spitzer, Software Architect
Phone: +49.89.45 23 47 - 260


jambit Software Development & Management GmbH
Erika-Mann-Str. 63, 80636 München
Phone: +49.89.45 23 47-0 Fax: +49.89.45 23 47-70

http://www.jambit.com where innovation works

Geschäftsführer: Peter F. Fellinger, Markus Hartinger
Sitz: München; Registergericht: München, HRB 129139
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509_vfy.h>
#include <openssl/bio.h>

#include <cstring>
#include <string>
#include <iostream>


#define nullptr 0

const char* certificateAsPem = "-----BEGIN CERTIFICATE-----\n"
"MIIGyDCCBLCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCREUx\n"
"EzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTEVMBMGA1UE\n"
"CgwMU29tZSBDb21wYW55MRgwFgYDVQQLDA9Tb21lT2ZmaWNlIFVuaXQxEzARBgNV\n"
"BAMMClRydXN0IFJvb3QxHzAdBgkqhkiG9w0BCQEWEG1haWxAZXhhbXBsZS5jb20w\n"
"HhcNMTIwNjA0MTUxMTQ2WhcNMzIwNjA0MTUxMTQ2WjCBpjELMAkGA1UEBhMCREUx\n"
"EzARBgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVNvbWUtQ2l0eTEVMBMGA1UE\n"
"CgwMU29tZSBDb21wYW55MRgwFgYDVQQLDA9Tb21lT2ZmaWNlIFVuaXQxHDAaBgNV\n"
"BAMME0RldmljZSBNYW51ZmFjdHVyZXIxHzAdBgkqhkiG9w0BCQEWEG1haWxAZXhh\n"
"bXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/s2Hnww8o\n"
"wtqvj5zrU9R5vmERsOrwMblHBwgD8PXOnAxSVTFYX13hn2NLLksnFdjwK3nsokj/\n"
"Y8Mg1hVX/iHy9gzt5wBnfu5EqUAY8d+8Du4leHM0AT3Q5RFkLlKukEM8/Ct2HnJa\n"
"P8KKeI80oy/xEZsE7KkLWb6I9BLnIvh8eHggylPJdbAamnxMUQAwddSIvSbZ+uTx\n"
"FCWgr/S0oNxByfc5BEKQF5O+GWti9FzgkpOoKG8LtMhPUL0srkY/5gJNJLFZa799\n"
"murYwHbqw0/m8CE58/sssVSu9DyiuX1SCf4tI69+tzNqs5OJCjQw5yM6XsqikCAu\n"
"OUdpJ6UdVev+BwNYkZxaohVkFF0jNIJj8PFJS3b7F/eZCOFWajFo9rEC9cVlfjtH\n"
"KeA4NwS2raeR619N5Zjs2uujb5/hM25dLBErKHokUd/PTF+VUaZhnt0aPtXasxoW\n"
"/+o1v2dHf/wdKFtVMKS4uLT40/RMJy24XTi4HKotgf/hna9j8eDQhEixyoRfAtHF\n"
"ojWZ/kPlmm0RNLHB/kcOVMuR54IVxoF8CoF/R6N8GinycY/WUKog4R0GoRlvkQ03\n"
"gHdPLayQObZ+v7ctCsJAjdLnOVGk5vd/byJJykOrZFZoPPEH8nXnaZa2JjX925eB\n"
"8dHK7irm4dATypFT61LNTuUGLzK87PJJJwIDAQABo4IBBjCCAQIwHQYDVR0OBBYE\n"
"FKSNp9W2sRGrSQV44dm2Ohf5fK+WMIHSBgNVHSMEgcowgceAFHsLSJuDRmeHPGuq\n"
"LZeOm4/lUXZtoYGjpIGgMIGdMQswCQYDVQQGEwJERTETMBEGA1UECAwKU29tZS1T\n"
"dGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5MRUwEwYDVQQKDAxTb21lIENvbXBhbnkx\n"
"GDAWBgNVBAsMD1NvbWVPZmZpY2UgVW5pdDETMBEGA1UEAwwKVHJ1c3QgUm9vdDEf\n"
"MB0GCSqGSIb3DQEJARYQbWFpbEBleGFtcGxlLmNvbYIJAKOelaQzPSd1MAwGA1Ud\n"
"EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggIBAIXKXsrv9xbU87H5J0z+PRWUwYHh\n"
"jd1NxmjxT31UT3BhSGbGurNK62q5Z9GFQNci7ceHidlS6+eeLOyAyQyDnnwBUt4H\n"
"llJeO1RD8KL2J5pc5DfOnrQrMA+jbQlOtdkyCynWm0wvz25oPFNNDPir0vD/epqe\n"
"px12oDW6DO3F+z6nuIWNlO9t9096KT3SAfMkGt9Linl364FDgXkbWRZiActCAj0/\n"
"sY7WOpqJVG8Yz+34VKaZRLMalDnopMSf9PZgNK37vwSJHtptZ0+IvuIQJ1tBRO3B\n"
"zS2rqmrvTZ4bDExtzYI4T2+moACC6pO8Fkolfs9otm/8iWhPHZEAreGHOPx+0kC8\n"
"MONtbcnNAhjXUGVruYhKMUhjIMETZpFI7eCB54FJ7+jyOZ/l9Lojh/GNgPzY1ZwD\n"
"RDCCbbQB3tv5EPHqtKLVKVqidmTiNvRcBJ6OxDxBOI4uK3IUFDUkiwlGfkT0I1tL\n"
"leTo65zFHbAnOHgEhTzJtroqjWSI/slK7U0gcmI52K6BvlI6xLuOgTtpwLBWdvLg\n"
"Z79WeJuoPpwhCQDScZTVw4ox++1v7KcVxJxaoF8+KNCMN1wVGTEgNLKFuHXamCSF\n"
"ekOi0E31PxclHe95hQXNFAxcdlPrIxyTzKPKbKl8ePKOagAIRv/CXkCfFjJ4P/rr\n"
"+rWi1kvr4B5x3UF3\n"
"-----END CERTIFICATE-----\n";

const char* caCertificateAsPem = "-----BEGIN CERTIFICATE-----\n"
"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\n"
"L4UG+Hx7SMXPctw=\n"
"-----END CERTIFICATE-----\n";

bool getCertificateFromData(const char* inputData, size_t inputDataLength,
    X509** certificate)
{
    bool result = true;

    BIO* buffer = BIO_new(BIO_s_mem());

    size_t bytesWritten = BIO_write(buffer, inputData,
                    inputDataLength);

    if (bytesWritten != inputDataLength)
    {
        result = false;
    }
    else
    {
        if (PEM_read_bio_X509(buffer, certificate, 0, nullptr) == nullptr)
        {
            result = false;
        }
    }

    BIO_free(buffer);

    return result;
}

int main(int argc, char** argv)
{
    X509* certificate = nullptr;

    if (!getCertificateFromData(certificateAsPem, strlen(certificateAsPem),
            &certificate))
    {
        return false;
    }

    X509* caCertificate = nullptr;

    if (!getCertificateFromData(caCertificateAsPem, 
                strlen(caCertificateAsPem), 
                &caCertificate))
    {
        X509_free(certificate);
        return false;
    }

    X509_STORE* certificateStore = nullptr;
    X509_STORE_CTX* context = nullptr;

    certificateStore = X509_STORE_new();

    if (certificateStore == nullptr)
    {
        X509_free(certificate);
        X509_free(caCertificate);
        return false;
    }

    // first attempt: resulting in error code 7
    if (!X509_STORE_add_cert(certificateStore, caCertificate))
    {
        X509_free(certificate);
        X509_free(caCertificate);
        return false;
    }
    // end of first attempt

    bool result = false;

    context = X509_STORE_CTX_new();

    if (context != nullptr)
    {
        if (X509_STORE_CTX_init(context, certificateStore, certificate, nullptr) == 1)
        {
            // second attempt: resulting in error code 7
            // X509_STORE_CTX_set_cert(context, certificate);
            // end of second attempt

            // third attempt: resulting in error code 7
            // STACK_OF(X509)* trustedStack = sk_X509_new_null();
            // sk_X509_push(trustedStack, caCertificate);
            // X509_STORE_CTX_trusted_stack(context, trustedStack);
            // end of third attempt

            int resultCode = X509_verify_cert(context);

            // using the set flags also did not change anything
            // X509_STORE_set_flags(certificateStore, X509_V_FLAG_CRL_CHECK_ALL);

            if(resultCode != 1)
            {
                int errorCode = X509_STORE_CTX_get_error(context);

                const std::string errorString(X509_verify_cert_error_string(
                                                    errorCode));

                std::cout << "Verification failed with error '" << 
                        errorString << "'" << std::endl;
            }

            result = (resultCode == 1);
        }

        X509_STORE_CTX_free(context);
    }

    X509_STORE_free(certificateStore);
    X509_free(certificate);
    X509_free(caCertificate);
    return 0;
}

Attachment: certificate.pem
Description: certificate.pem

Attachment: caCertificate.pem
Description: caCertificate.pem

Reply via email to