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; }
certificate.pem
Description: certificate.pem
caCertificate.pem
Description: caCertificate.pem