diff --git a/Crypto/include/Poco/Crypto/OpenSSLInitializer.h b/Crypto/include/Poco/Crypto/OpenSSLInitializer.h index 42c97ae46..9b511aa5d 100644 --- a/Crypto/include/Poco/Crypto/OpenSSLInitializer.h +++ b/Crypto/include/Poco/Crypto/OpenSSLInitializer.h @@ -22,7 +22,9 @@ #include "Poco/Mutex.h" #include "Poco/AtomicCounter.h" #include - +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif #if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L #include #endif @@ -50,10 +52,10 @@ class Crypto_API OpenSSLInitializer public: OpenSSLInitializer(); /// Automatically initialize OpenSSL on startup. - + ~OpenSSLInitializer(); /// Automatically shut down OpenSSL on exit. - + static void initialize(); /// Initializes the OpenSSL machinery. @@ -71,7 +73,7 @@ protected: { SEEDSIZE = 256 }; - + // OpenSSL multithreading support static void lock(int mode, int n, const char* file, int line); static unsigned long id(); @@ -82,6 +84,10 @@ protected: private: static Poco::FastMutex* _mutexes; static Poco::AtomicCounter _rc; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + static OSSL_PROVIDER* _defaultProvider; + static OSSL_PROVIDER* _legacyProvider; +#endif }; diff --git a/Crypto/src/CipherImpl.cpp b/Crypto/src/CipherImpl.cpp index 23ad40ed7..b3d77b883 100644 --- a/Crypto/src/CipherImpl.cpp +++ b/Crypto/src/CipherImpl.cpp @@ -98,20 +98,22 @@ namespace { #if OPENSSL_VERSION_NUMBER >= 0x10100000L _pContext = EVP_CIPHER_CTX_new(); - EVP_CipherInit( + if (!_pContext) throwError(); + int rc = EVP_CipherInit( _pContext, _pCipher, &_key[0], _iv.empty() ? 0 : &_iv[0], (dir == DIR_ENCRYPT) ? 1 : 0); #else - EVP_CipherInit( + int rc = EVP_CipherInit( &_context, _pCipher, &_key[0], _iv.empty() ? 0 : &_iv[0], (dir == DIR_ENCRYPT) ? 1 : 0); #endif + if (rc == 0) throwError(); #if OPENSSL_VERSION_NUMBER >= 0x10001000L if (_iv.size() != EVP_CIPHER_iv_length(_pCipher) && EVP_CIPHER_mode(_pCipher) == EVP_CIPH_GCM_MODE) diff --git a/Crypto/src/OpenSSLInitializer.cpp b/Crypto/src/OpenSSLInitializer.cpp index 47078302f..f52aabd8f 100644 --- a/Crypto/src/OpenSSLInitializer.cpp +++ b/Crypto/src/OpenSSLInitializer.cpp @@ -60,6 +60,10 @@ namespace Crypto { Poco::FastMutex* OpenSSLInitializer::_mutexes(0); Poco::AtomicCounter OpenSSLInitializer::_rc; +#if OPENSSL_VERSION_NUMBER >= 0x0907000L +OSSL_PROVIDER* OpenSSLInitializer::_defaultProvider(0); +OSSL_PROVIDER* OpenSSLInitializer::_legacyProvider(0); +#endif OpenSSLInitializer::OpenSSLInitializer() @@ -93,12 +97,17 @@ void OpenSSLInitializer::initialize() SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); - + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + _defaultProvider = OSSL_PROVIDER_load(NULL, "default"); + _legacyProvider = OSSL_PROVIDER_load(NULL, "legacy"); +#endif + char seed[SEEDSIZE]; RandomInputStream rnd; rnd.read(seed, sizeof(seed)); RAND_seed(seed, SEEDSIZE); - + int nMutexes = CRYPTO_num_locks(); _mutexes = new Poco::FastMutex[nMutexes]; CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); @@ -107,8 +116,8 @@ void OpenSSLInitializer::initialize() // https://sourceforge.net/p/poco/bugs/110/ // // From http://www.openssl.org/docs/crypto/threads.html : -// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(), -// then a default implementation is used - on Windows and BeOS this uses the system's +// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(), +// then a default implementation is used - on Windows and BeOS this uses the system's // default thread identifying APIs" CRYPTO_set_id_callback(&OpenSSLInitializer::id); #endif @@ -130,8 +139,13 @@ void OpenSSLInitializer::uninitialize() CRYPTO_set_id_callback(0); #endif delete [] _mutexes; - + CONF_modules_free(); + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PROVIDER_unload(_defaultProvider); + OSSL_PROVIDER_unload(_legacyProvider); +#endif } } diff --git a/Crypto/src/PKCS12Container.cpp b/Crypto/src/PKCS12Container.cpp index dfc411130..b15252b9b 100644 --- a/Crypto/src/PKCS12Container.cpp +++ b/Crypto/src/PKCS12Container.cpp @@ -171,7 +171,15 @@ void PKCS12Container::load(PKCS12* pPKCS12, const std::string& password) int certCount = sk_X509_num(pCA); for (int i = 0; i < certCount; ++i) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L X509* pX509 = sk_X509_value(pCA, i); +#else + // Cert order is reversed on OpenSSL < 3. + // https://github.com/openssl/openssl/issues/16421 + // https://github.com/openssl/openssl/pull/12641 + // https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162 + X509* pX509 = sk_X509_value(pCA, certCount - i - 1); +#endif if (pX509) { _caCertList.push_back(X509Certificate(pX509, true)); diff --git a/Crypto/testsuite/src/PKCS12ContainerTest.cpp b/Crypto/testsuite/src/PKCS12ContainerTest.cpp index c8d7a3e2a..78cba18b1 100644 --- a/Crypto/testsuite/src/PKCS12ContainerTest.cpp +++ b/Crypto/testsuite/src/PKCS12ContainerTest.cpp @@ -134,29 +134,29 @@ void PKCS12ContainerTest::fullList(const PKCS12Container::CAList& caList, assertTrue (caNamesList[certOrder[1]].empty()); } - assertTrue (caList[certOrder[0]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); + assertTrue (caList[certOrder[0]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Intermediate CA v3"); assertTrue (caList[certOrder[0]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); - assertTrue (caList[certOrder[0]].commonName() == "CV Root CA v3"); + assertTrue (caList[certOrder[0]].commonName() == "CV Intermediate CA v3"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[0]].serialNumber() == "C3ECA1FCEAA16055"); + assertTrue (caList[certOrder[0]].serialNumber() == "1000"); assertTrue (caList[certOrder[0]].version() == 3); assertTrue (caList[certOrder[0]].signatureAlgorithm() == "sha256WithRSAEncryption"); - assertTrue (caList[certOrder[1]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Intermediate CA v3"); + assertTrue (caList[certOrder[1]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); assertTrue (caList[certOrder[1]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); - assertTrue (caList[certOrder[1]].commonName() == "CV Intermediate CA v3"); + assertTrue (caList[certOrder[1]].commonName() == "CV Root CA v3"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[1]].serialNumber() == "1000"); + assertTrue (caList[certOrder[1]].serialNumber() == "C3ECA1FCEAA16055"); assertTrue (caList[certOrder[1]].version() == 3); assertTrue (caList[certOrder[1]].signatureAlgorithm() == "sha256WithRSAEncryption"); } @@ -200,36 +200,36 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList, if (caNamesList.size()) { - assertTrue (caNamesList[certOrder[0]].empty()); - assertTrue (caNamesList[certOrder[1]].empty()); + assertTrue (caNamesList[certOrder[0]] == "vally-ca"); + assertTrue (caNamesList[certOrder[1]] == "vally-ca"); assertTrue (caNamesList[certOrder[2]].empty()); - assertTrue (caNamesList[certOrder[3]] == "vally-ca"); - assertTrue (caNamesList[certOrder[4]] == "vally-ca"); + assertTrue (caNamesList[certOrder[3]].empty()); + assertTrue (caNamesList[certOrder[4]].empty()); } - assertTrue (caList[certOrder[0]].subjectName() == "C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3"); - assertTrue (caList[certOrder[0]].issuerName() == "C=US,O=Internet Security Research Group,CN=ISRG Root X1"); - assertTrue (caList[certOrder[0]].commonName() == "Let's Encrypt Authority X3"); - assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_COUNTRY) == "US"); + assertTrue (caList[certOrder[0]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Intermediate CA v3"); + assertTrue (caList[certOrder[0]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); + assertTrue (caList[certOrder[0]].commonName() == "CV Intermediate CA v3"); + assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); - assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE).empty()); - assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt"); + assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); + assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[0]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[0]].serialNumber() == "D3B17226342332DCF40528512AEC9C6A"); + assertTrue (caList[certOrder[0]].serialNumber()== "1000"); assertTrue (caList[certOrder[0]].version() == 3); assertTrue (caList[certOrder[0]].signatureAlgorithm() == "sha256WithRSAEncryption"); - assertTrue (caList[certOrder[1]].subjectName() == "C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3"); - assertTrue (caList[certOrder[1]].issuerName() == "O=Digital Signature Trust Co.,CN=DST Root CA X3"); - assertTrue (caList[certOrder[1]].commonName() == "Let's Encrypt Authority X3"); - assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_COUNTRY) == "US"); + assertTrue (caList[certOrder[1]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); + assertTrue (caList[certOrder[1]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); + assertTrue (caList[certOrder[1]].commonName() == "CV Root CA v3"); + assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); - assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE).empty()); - assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt"); + assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); + assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[1]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[1]].serialNumber() == "0A0141420000015385736A0B85ECA708"); + assertTrue (caList[certOrder[1]].serialNumber() == "C3ECA1FCEAA16055"); assertTrue (caList[certOrder[1]].version() == 3); assertTrue (caList[certOrder[1]].signatureAlgorithm() == "sha256WithRSAEncryption"); @@ -246,31 +246,32 @@ void PKCS12ContainerTest::certsOnlyList(const PKCS12Container::CAList& caList, assertTrue (caList[certOrder[2]].version() == 3); assertTrue (caList[certOrder[2]].signatureAlgorithm() == "sha256WithRSAEncryption"); - assertTrue (caList[certOrder[3]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); - assertTrue (caList[certOrder[3]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); - assertTrue (caList[certOrder[3]].commonName() == "CV Root CA v3"); - assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); + assertTrue (caList[certOrder[3]].subjectName() == "C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3"); + assertTrue (caList[certOrder[3]].issuerName() == "O=Digital Signature Trust Co.,CN=DST Root CA X3"); + assertTrue (caList[certOrder[3]].commonName() == "Let's Encrypt Authority X3"); + assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_COUNTRY) == "US"); assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); - assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); - assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); + assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE).empty()); + assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt"); assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[3]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[3]].serialNumber() == "C3ECA1FCEAA16055"); + assertTrue (caList[certOrder[3]].serialNumber() == "0A0141420000015385736A0B85ECA708"); assertTrue (caList[certOrder[3]].version() == 3); assertTrue (caList[certOrder[3]].signatureAlgorithm() == "sha256WithRSAEncryption"); - assertTrue (caList[certOrder[4]].subjectName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Intermediate CA v3"); - assertTrue (caList[certOrder[4]].issuerName() == "C=CH,ST=Zug,O=Crypto Vally,CN=CV Root CA v3"); - assertTrue (caList[certOrder[4]].commonName() == "CV Intermediate CA v3"); - assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_COUNTRY) == "CH"); + assertTrue (caList[certOrder[4]].subjectName() == "C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3"); + assertTrue (caList[certOrder[4]].issuerName() == "C=US,O=Internet Security Research Group,CN=ISRG Root X1"); + assertTrue (caList[certOrder[4]].commonName() == "Let's Encrypt Authority X3"); + assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_COUNTRY) == "US"); assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_LOCALITY_NAME).empty()); - assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE) == "Zug"); - assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Crypto Vally"); + assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_STATE_OR_PROVINCE).empty()); + assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_ORGANIZATION_NAME) == "Let's Encrypt"); assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_ORGANIZATION_UNIT_NAME).empty()); assertTrue (caList[certOrder[4]].subjectName(X509Certificate::NID_PKCS9_EMAIL_ADDRESS).empty()); - assertTrue (caList[certOrder[4]].serialNumber()== "1000"); + assertTrue (caList[certOrder[4]].serialNumber() == "D3B17226342332DCF40528512AEC9C6A"); assertTrue (caList[certOrder[4]].version() == 3); assertTrue (caList[certOrder[4]].signatureAlgorithm() == "sha256WithRSAEncryption"); + } @@ -281,9 +282,8 @@ void PKCS12ContainerTest::testPEMReadWrite() std::string file = getTestFilesPath("certs-only", "pem"); X509Certificate::List certsOnly = X509Certificate::readPEM(file); assertTrue (certsOnly.size() == 5); - // PEM is written by openssl in reverse order from p12 std::vector certOrder; - for(int i = (int)certsOnly.size() - 1; i >= 0; --i) certOrder.push_back(i); + for(int i = 0; i < certsOnly.size(); ++i) certOrder.push_back(i); certsOnlyList(certsOnly, PKCS12Container::CANameList(), certOrder); TemporaryFile tmpFile; @@ -301,7 +301,7 @@ void PKCS12ContainerTest::testPEMReadWrite() assertTrue (full.size() == 2); certOrder.clear(); - for(int i = (int)full.size() - 1; i >= 0; --i) certOrder.push_back(i); + for(int i = 0; i < full.size(); ++i) certOrder.push_back(i); fullList(full, PKCS12Container::CANameList(), certOrder); TemporaryFile tmpFile2;