Bug #4450
closed
macOS Keychain does not support PKCS8 keys created with a PBKDF2 PRF other than HMAC-SHA1 (was: Security/Tpm/TestBackEnd/ImportExport fails with openssl 1.1)
Added by Davide Pesavento almost 7 years ago.
Updated 12 months ago.
Description
macOS 10.12, OpenSSL 1.1.0g, https://travis-ci.org/named-data/ndn-cxx/jobs/326925215
../tests/unit-tests/security/tpm/back-end.t.cpp:178: Entering test case "ImportExport<ndn__security__tpm__tests__BackEndWrapperOsx>"
../src/security/tpm/back-end-osx.cpp:509: fatal error: in "virtual void ndn::security::tpm::BackEndOsx::doImportKey(const ndn::Name &, const uint8_t *, size_t, const char *, size_t)": boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<ndn::security::tpm::BackEndOsx::Error> >: Cannot import the private key
../tests/unit-tests/security/tpm/back-end.t.cpp:212: last checkpoint
../tests/unit-tests/security/tpm/back-end.t.cpp:178: Leaving test case "ImportExport<ndn__security__tpm__tests__BackEndWrapperOsx>"; testing time: 24876us
- Subject changed from Security/Tpm/TestBackEnd/ImportExport fails with openssl 1.1 to macOS Keychain does not support PKCS8-encoded keys with .. other than SHA-1 (was: Security/Tpm/TestBackEnd/ImportExport fails with openssl 1.1)
- Status changed from New to In Progress
- Assignee set to Davide Pesavento
- Target version set to v0.7
- % Done changed from 0 to 30
I analyzed the ASN.1 structure produced by our PKCS #8 encoding (PrivateKey::toPkcs8
), which is then fed to macOS's SecItemImport
, and I discovered that openssl 1.1 and later defaults to HMAC-SHA256 as the underlying PRF for PBKDF2, while earlier versions used HMAC-SHA1(*). Sadly, macOS doesn't seem to support anything other than HMAC-SHA1, so it fails to import a private key encrypted by a recent openssl with default settings.
(*) In fact, older openssl generates an ASN.1 encoding without a "prf" object under "PBKDF2-params". According to RFC 8018, if a "prf" value is not specified, the default is algid-hmacWithSHA1
.
- Subject changed from macOS Keychain does not support PKCS8-encoded keys with .. other than SHA-1 (was: Security/Tpm/TestBackEnd/ImportExport fails with openssl 1.1) to macOS Keychain does not support PKCS8 keys created with a PBKDF2 PRF other than HMAC-SHA1 (was: Security/Tpm/TestBackEnd/ImportExport fails with openssl 1.1)
Davide Pesavento wrote:
Sadly, macOS doesn't seem to support anything other than HMAC-SHA1, so it fails to import a private key encrypted by a recent openssl with default settings.
I just realized that Apple's Security library is open source, so I looked directly at the code, which confirmed my previous analysis.
From https://opensource.apple.com/source/Security/Security-58286.41.2/OSX/libsecurity_keychain/lib/SecImportExportPkcs8.cpp.auto.html
/* prf optional, but if it's there it better be CSSMOID_PKCS5_HMAC_SHA1 */
if(pbkdf2Params.prf.Data) {
if(!nssCompareCssmData(&pbkdf2Params.prf, &CSSMOID_PKCS5_HMAC_SHA1)) {
SecPkcs8Dbg("PKCS8: PKCS5 v2 unexpected prf OID");
return errSecUnknownFormat;
}
}
prf = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
Later in the same function, we can also see that Apple support only DES, DES_EDE3, RC2, and RC5 as encryption algorithms for the key :(
I see two ways to resolve this:
- In
transform::PrivateKey::toPkcs8
, force the usage of HMAC-SHA1 as PRF, restoring compatibility with macOS's SecItemImport
. This can be done by using a combination of 3 low(er)-level (and undocumented) openssl functions instead of i2d_PKCS8PrivateKey_bio
.
- Keep using the (more secure) openssl default, but change
tpm::BackEndOsx::doImportKey
to unwrap and decrypt the key using openssl functions before importing it into macOS keychain.
I'm not sure which way is best. I've tried (1) and it seems to work. On the other hand, (2) would give us more flexibility in the long run, because we're not constrained by what macOS does or does not support, and would also allow us to switch key encryption to AES (which isn't supported by macOS) from the current 3DES.
I am leaning towards option 2, if it is feasible to implement and implementation complexity is reasonable.
- Status changed from In Progress to Code review
- % Done changed from 30 to 100
- Status changed from Code review to Closed
- Tags set to macOS, security
- Tags changed from macOS, security to macOS, security, openssl
Also available in: Atom
PDF