openssl / openssl

TLS/SSL and crypto library

Home Page:https://www.openssl.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support FIPS-compliant PKCS#12 files and create them by default in FIPS mode

tomato42 opened this issue · comments

The PKCS12KDF is not FIPS approved, so it's missing from the fips provider. Therefore it's not possible to create a PKCS #12 file that only uses FIPS approved algorithms in currently released versions of OpenSSL.

I've just published RFC 9579 that documents how to use PBMAC1 and therefore the FIPS approved PBKDF2 for the purpose of whole file integrity check.

I'd like to ask for:

  • support for RFC 9579 (PBMAC1 in PKCS #12)
  • use of it by default when OpenSSL is operating in FIPS mode

Related:

use of it by default when OpenSSL is operating in FIPS mode

Current upstream approach doesn't check FIPS mode so I doubt

There still is the the default property of fips=yes which causes the current export to fail when it's set. It would lead to better user experience if that was taken into account when PKCS#12 file is created.

At least in the command line utility we could try to fetch PKCS12KDF and if the fetch fails we could try PBMAC1.

Apologies for derailing this completely, @tomato42 - is this headed for Java JCE PKCS12 KeyStore in any form? Interop between Java and OpenSSL is important for me.

@space88man no, I haven't filed a bug against Java to have it implemented there. If you have a need for interoperability with Java in FIPS mode I think it would be better for you to file that issue.

@tomato42 - this part of the RFC

However, just as with PBES1 and PBES2 when used in the context of PKCS #12 objects, all
passwords used with PBMAC1 MUST be created from BMPStrings with a NULL terminator.

is not clear to me: in the examples in appendix A where the password is "1234": the bytes passed to PBKDF2 seem to be "\x31\x32\x33\x34" and not "\x00\0x31\0x00\x32\x00\0x33\0x00\0x34\0x00\0x00" - is this correct?

IOW: I could validate the files if I used the 4-byte input to PBKDF2 and not the 10-byte version (which would be used with legacy PKCS#12 KDF).

@space88man that would be rather unfortunate... at the same time, there are implementations of this algorithm in GnuTLS and in NSS that do read those test vectors so would be surprising if all three implementations didn't notice it and got it wrong when implementing...

@beldmit could you double check?

Yes, the passed bytes are "\x31\x32\x33\x34"
See https://openssl.org/docs/manmaster/man7/passphrase-encoding.html for more details

@tomato42 - thanks, that was fast!

With PBES2 Java's SunJCE is already using UTF-8 without NULL terminator. Since these PKCS#12 keystores are compatible with OpenSSL, I presume OpenSSL is doing the same.

Can you consider the following wording instead? It also comports with R Relyea's response to your errata email.

As documented in Appendix B.1 of [RFC7292], the handling of password
encoding in the underlying standards is underspecified. However,
unlike with PBES1 when used in the context of PKCS #12
objects, all passwords used with PBMAC1 MUST be created from
UTF-8 encoding without a NULL terminator or Byte Order Mark (BOM).

(This makes the password encoding of PBMAC1 identical to PBES2 as used for encryption.)

@space88man I think you are supposed to use BMPStrings even with PBES2, it's just that so many implementations get this wrong that basically everybody has a fallback where they try both UTF-16 and UTF-8. But I haven't looked at that code.