RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1759335 - OpenJDK keytool is broken in FIPS mode
Summary: OpenJDK keytool is broken in FIPS mode
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: java-1.8.0-openjdk
Version: 8.1
Hardware: Unspecified
OS: Unspecified
unspecified
high
Target Milestone: rc
: 8.0
Assignee: Martin Balao
QA Contact: OpenJDK QA
URL:
Whiteboard:
: 1908876 (view as bug list)
Depends On:
Blocks: 1760850
TreeView+ depends on / blocked
 
Reported: 2019-10-07 20:53 UTC by Alex Scheel
Modified: 2024-12-20 18:54 UTC (History)
12 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-08-06 19:14:17 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Alex Scheel 2019-10-07 20:53:16 UTC
Description of problem:

keytool is broken on RHEL 8.1 with FIPS mode enabled.

Version-Release number of selected component (if applicable):

readlink $(readlink /usr/bin/keytool)
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.222.b10-3.el8.x86_64/jre/bin/keytool

[root@pki tpm]# rpm -qa | grep -i openjdk
java-1.8.0-openjdk-1.8.0.222.b10-3.el8.x86_64
java-1.8.0-openjdk-devel-1.8.0.222.b10-3.el8.x86_64
java-1.8.0-openjdk-headless-1.8.0.222.b10-3.el8.x86_64



How reproducible:

Very


Steps to Reproduce:

1. Grab two RHEL 8.1 VMs
2. Enable FIPS mode on one of them.
3. The following two commands work outside of FIPS mode, but both fail if FIPS mode is enabled:

1: 

> keytool -genkeypair \
>   -keystore keystore.jks \
>   -storepass Secret.123 \
>   -alias "sslserver" \
>   -dname "CN=$HOSTNAME" \
>   -keyalg RSA \
>   -keypass Secret.123

2:

> keytool -genkeypair \
>   -keystore keystore.p12 \
>   -storetype pkcs12 \
>   -storepass Secret.123 \
>   -alias "sslserver" \
>   -dname "CN=$HOSTNAME" \
>   -keyalg RSA \
>   -keypass Secret.123

Actual results:

1. keytool error: java.security.KeyStoreException: Cannot get key bytes, not PKCS#8 encoded
2. keytool error: java.security.KeyStoreException: Key protection  algorithm not found: java.lang.NullPointerException

Neither creates a working JKS/PKCS12 database. 


Expected results:

1. Warning: The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".
2. No CLI output; just creates the databases. 


Additional info:

I'm guessing this is a result of the tighter crypto-policies integration.

Comment 2 Martin Balao 2019-10-08 16:08:37 UTC
OpenJDK is not expected to handle file-based keystores (such as PKCS12 or JKS) while in FIPS mode. The reason is that private keys must never be extracted in plain out of the security token; they can be extracted wrapped by a different key located in the token (but that wouldn't be useful for the purpose of a keystore).

Comment 3 Simo Sorce 2019-10-08 16:21:13 UTC
mbalao is this a technical limitation, or a choice made by the openJDK maintainers ?

If it is a technical limitation can you explain wherein lies the issue ?

If it is a choice can you justify it? There is nothing in FIPS really that dictates the kind of storage that needs to be used, only that it needs to be protected (note that file permissions is considered sufficient protection on a system where processes are separate by different user identities like on a Linux system).

Comment 4 Alex Scheel 2019-10-08 16:42:37 UTC
Also, where is documentation for all of these JDK FIPS mode changes located? Considering how invasive they are, I'd appreciate a link. :)

Comment 6 Martin Balao 2019-10-08 17:43:28 UTC
Our goal when configuring OpenJDK in FIPS mode is to setup an environment in which all crypto primitives and key management are performed inside an NSS software token, which is the only FIPS certified piece here. To achieve this goal, and help the application to avoid mistakes, there are a few things we do: 1) set SunPKCS11 + NSS-FIPS as the 1st priority security provider; 2) configure SunJSSE provider (TLS engine) in FIPS mode; and, 3) minimize the number of enabled security providers. Keep in mind that this is just a guidance intended to avoid mistakes, not an absolute enforcement: an application can still break the guidelines.

A comment on #3 first. If we enable all the security providers and an algorithm is not supported by SunPKCS11, we will easily end-up using a non-FIPS crypto implementation without even noticing it. We prefer an algorithm not found error instead of a non-FIPS certified implementation. This is what you've seen with PBE algorithms. It's in fact undesirable that we had to enable SUN and SunEC providers in our FIPS configuration, but we needed support for X.509 format and we cannot introduce such a fundamental change to JDK 7, 8 and 11 at this point.

When generating keys in FIPS mode, NSS sets the CKA_SENSITIVE key attribute to TRUE [1] [2] [3]. As a result, and assuming CKA_EXTRACTABLE is TRUE -no constraints on that-, generated keys can only be extracted if wrapped. In OpenJDK this means that you cannot see the encoded plain key from a P11Key object, or convert it to be used in a different security provider. This helps to avoid errors.

When a KeyManager instance is created and SunJSSE is configured in FIPS mode, the KeyStore provider has to be the same than used for SunJSSE (that is SunPKCS11). As a result, JKS and PKCS12 keystores cannot be used for the TLS engine. Again, this helps to avoid errors: if we get a key from a JKS provider and we establish a TLS connection, we hadn't used NSS certified FIPS crypto for that.

Please note that there are PKCS11 keystores enabled for read-use. We are considering a future enhancement to make them the default choice (in FIPS mode) and enabling them for write-mode(*).

Going back to the discussion, supporting file-based keystores would mean: managing non-SunPKCS11-NSS keys, enabling more security providers and potentially using non-FIPS-certified crypto primitives. These keys won't be allowed for SunJSSE for the reasons previously said.


(*) We took a conservative choice here because this is a global resource and write-mode would mean only one process having access at a time.
--
[1] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c#l1366
[2] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c#l1397
[3] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c#l1483
[4] - http://hg.openjdk.java.net/jdk-updates/jdk11u/file/3bf13d471753/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java#l64
[5] - http://hg.openjdk.java.net/jdk-updates/jdk11u/file/3bf13d471753/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java#l94

Comment 7 Alex Scheel 2019-10-08 19:35:29 UTC
The portion I'm disagreeing with is not allowing existing KeyManager/TrustManagers to be utilized with the SunPKCS11-NSS-FIPS implementation. You can easily convert non-NSS-backed keys into NSS-backed keys, even in FIPS mode, and allow NSS-backed certificates to be accessible to non-NSS-backed TM implementations for certificate validation.

Not doing so **breaks** existing applications and these changes **should** be reverted until RHEL 8.2 release where all affected parties have more time to discuss these changes and approve them. IMO it should never have been introduced so late into the RHEL 8.1 release cycle, especially since we received zero notification about these changes until they've already shipped.


But to respond:

For working with certificates:

The first call you need is CERT_ImportCerts(...) [0][1]. On receiving a non-NSS-backed certificate from another portion of the JDK (say, a PKCS#12 file or otherwise), you can easily import it into the NSS DB with temporary scope, which I believe should work even in read-only mode. But Bob Relyea would know. This lets you utilize the certificate for TLS. If you need to access it from PKCS#11, you'll then have to use PK11_ImportCert(...) [2][3] on the CERTCertificate from CERT_ImportCerts(...). 

Or you could use PK11_ImportDerCert(...) [4][5] and bypass that dance. 

For working with public keys:

First use SECKEY_DecodeDERSubjectPublicKeyInfo(...) [6][7] to decode the header, which you can pass to SECKEY_ExtractPublicKey(...) [8][9] to get a SECKEYPublicKey object. This is what the NSS test suite does [10]. You can then pass to PK11_ImportPublicKey(...) [11][12] to do with as you like from the PKCS#11 layer.

You could also bypass that dance and use PK11_ImportDERPublicKey(...) [13][14], but it doesn't appear to be tested so I'm not sure if it works.

For working with private keys: 

I'll skip the dance and point to to PK11_ImportDERPrivateKeyInfo(...) [15][16] and PK11_ImportDERPrivateKeyInfoAndReturnKey(...) [17][18]. I'm sure there's other ways to do this that dance around the import more and give you more control over flags and such.

For working with symmetric keys:

PK11_ImportSymKey(...) [19][20] lets you directly import binary symmetric keys just fine. I've used it in my test for CMAC upstream. [21]. 

For encoding certificates to their DER form from a NSS handle: 

CERT_GetCertificateDer(...) [22][23] lets you export a CERTCertificate * back to DER for decoding in Java and passing to any TrustManager. 

In short, I think its perfectly reasonable to assume it isn't a technical limitation in NSS that prohibits this and was instead an unreasonable design choice on the part of the JDK. 



Now we're onto the other part of the conversation... 

 1) NSS still lets you use older,  prohibited algorithms in FIPS mode anyways, via its PKCS#11 API. In NSS's opinion, it is up to the caller to comply with FIPS.
 2) You could, if you so chose, leave the implementations necessary for compatibility with older JDKs (RC2...), not expose them via the provider mechanism, and only let them be used internally from the JDK. This would let you retain full support for existing mechanisms.
 3) But like Simo said, nothing in FIPS prohibits you from using file based key storage. So **please**, add support back in, even if only for using modern algorithms. You're throwing the baby out with the bathwater. I'm fine having RC2 encrypted PKCS#12 blobs created by keyutil being rejected. I'm not fine with _all_ PKCS#12 files being rejected, even ones that use AES-128-CBC. Same goes for unencrypted PKCS#8 certificates and keys. I have no idea what JKS uses or can use, so I'll leave that choice up to you.


In short, its entirely reasonable to expect that *most* things will still work. At most you should just need to upgrade to newer algorithms. This change needs to be thought out a bit more.


Point being, I care about, in order of importance:

 1) Using my own KeyManager / TrustManager,
 2) Being able to use FIPS-compliant encrypted PKCS#12 blobs or unencrypted PKCS#8 blobs through the existing, standard KM/TM interfaces. 
 3) Making keytool work.



Note: line numbers might've shifted slightly due to using an older NSS checkout. 

[0]: header: https://github.com/nss-dev/nss/blob/master/lib/certdb/cert.h#L1091
[1]: impl: https://github.com/nss-dev/nss/blob/master/lib/certdb/certdb.c#L2441
[2]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L649
[3]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11skey.c#L469
[4]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L652
[5]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11cert.c#L1146
[6]: header: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/keyhi.h#L119
[7]: impl: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/seckey.c#L1541
[8]: header: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/keyhi.h#L133
[9]: impl: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/seckey.c#L680
[10]: test: https://github.com/nss-dev/nss/blob/master/gtests/pk11_gtest/pk11_signature_test.h#L61
[11]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L292
[12]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11akey.c#L63
[13]: header: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/keyhi.h#L207
[14]: impl: https://github.com/nss-dev/nss/blob/master/lib/cryptohi/seckey.c#L1817
[15]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L571
[16]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pk12.c#L250
[17]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L575
[18]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pk12.c#L261
[19]: header: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11pub.h#L270
[20]: impl: https://github.com/nss-dev/nss/blob/master/lib/pk11wrap/pk11skey.c#L469
[21]: test: https://github.com/nss-dev/nss/blob/master/gtests/pk11_gtest/pk11_aes_cmac_unittest.cc#L30
[22]: header: https://github.com/nss-dev/nss/blob/master/lib/certdb/cert.h#L222
[23]: impl: https://github.com/nss-dev/nss/blob/master/lib/certdb/certdb.c#L1277

Comment 8 Martin Balao 2019-11-12 20:21:14 UTC
(In reply to Alex Scheel from comment #7)
> You can easily convert non-NSS-backed keys into NSS-backed
> keys, even in FIPS mode,

You cannot in FIPS mode as far as I know, unless you implement some kind of hack/workaround to circumvent explicit checks against that or you use NSS in non-FIPS mode. See links below.

> 
> Not doing so **breaks** existing applications and these changes **should**
> be reverted until RHEL 8.2 release where all affected parties have more time
> to discuss these changes and approve them. IMO it should never have been
> introduced so late into the RHEL 8.1 release cycle, especially since we
> received zero notification about these changes until they've already shipped.
> 

SunJSSE security provider in OpenJDK has had "Experimental FIPS mode" since the very beginning (in 2007). It used to be documented until its removal in JDK-12 [1]. The goal was to make sure that all the crypto primitives for the SSL/TLS engine came from a single FIPS-compliant provider. It's not the root cause for the issues we have found though: removing KeyStore checks in SunJSSE or initializing SunJSSE in default (non-FIPS) mode would have caused the same trouble (see below).

OpenJDK has always supported NSS as a PKCS#11 backend and FIPS mode configuration has always been documented [2]. NSS, when configured in "fips" mode, cannot create private keys from raw-key material [3]. That's the reason why removing SunJSSE FIPS-mode KeyStore checks wouldn't have been enough. Even though the NSS software token is not an 'official' way of providing FIPS support in OpenJDK, that is what we have always offered to our customers and documented in RHEL [4].

What I mean with this recap is that nothing is new or has changed here in regards to how we configure OpenJDK in FIPS mode, so all this was a bit surprising to me. I agree that we should have integrated this change before. With that said, the patch and discussions have been available for a long time (see RH-1655466 [5]).

I can take from the crypto-team that there isn't a compliance reason to disallow the handling of keys out of the token -as long as they are protected in some way-. I don't really know the reason why the NSS software token enforces that in FIPS mode. What I can say, though, is that fundamentally changing the way we offer FIPS support in OpenJDK (i.e.: not using NSS as a software backend) won't happen in the short term (before RHEL 8.2).

> 
> But to respond:
> 
> For working with certificates:
> 
> The first call you need is CERT_ImportCerts(...) [0][1]. On receiving a
> non-NSS-backed certificate from another portion of the JDK (say, a PKCS#12
> file or otherwise), you can easily import it into the NSS DB with temporary
> scope, which I believe should work even in read-only mode. But Bob Relyea
> would know. This lets you utilize the certificate for TLS. If you need to
> access it from PKCS#11, you'll then have to use PK11_ImportCert(...) [2][3]
> on the CERTCertificate from CERT_ImportCerts(...). 
> 
> Or you could use PK11_ImportDerCert(...) [4][5] and bypass that dance. 
> 
> For working with public keys:
> 
> First use SECKEY_DecodeDERSubjectPublicKeyInfo(...) [6][7] to decode the
> header, which you can pass to SECKEY_ExtractPublicKey(...) [8][9] to get a
> SECKEYPublicKey object. This is what the NSS test suite does [10]. You can
> then pass to PK11_ImportPublicKey(...) [11][12] to do with as you like from
> the PKCS#11 layer.
> 
> You could also bypass that dance and use PK11_ImportDERPublicKey(...)
> [13][14], but it doesn't appear to be tested so I'm not sure if it works.
> 
> For working with private keys: 
> 
> I'll skip the dance and point to to PK11_ImportDERPrivateKeyInfo(...)
> [15][16] and PK11_ImportDERPrivateKeyInfoAndReturnKey(...) [17][18]. I'm
> sure there's other ways to do this that dance around the import more and
> give you more control over flags and such.
> 
> For working with symmetric keys:
> 
> PK11_ImportSymKey(...) [19][20] lets you directly import binary symmetric
> keys just fine. I've used it in my test for CMAC upstream. [21]. 
> 
> For encoding certificates to their DER form from a NSS handle: 
> 
> CERT_GetCertificateDer(...) [22][23] lets you export a CERTCertificate *
> back to DER for decoding in Java and passing to any TrustManager. 
> 

Ok, you've shared a bunch of links to an NSS PKCS#11 wrapper library. In OpenJDK we have our own wrapper library [6][7] and perform all these actions. That's how PKCS11 keystores work importing and exporting certificates, keys, etc. When it comes to importing a private key, for instance, it boils down to calling C_CreateObject with specific arguments.

> In short, I think its perfectly reasonable to assume it isn't a technical
> limitation in NSS that prohibits this and was instead an unreasonable design
> choice on the part of the JDK. 
> 

Can you please elaborate on that and why you say OpenJDK offers an 'unreasonable design choice'?

> 
> Now we're onto the other part of the conversation... 
> 
>  1) NSS still lets you use older,  prohibited algorithms in FIPS mode
> anyways, via its PKCS#11 API. In NSS's opinion, it is up to the caller to
> comply with FIPS.
>  2) You could, if you so chose, leave the implementations necessary for
> compatibility with older JDKs (RC2...), not expose them via the provider
> mechanism, and only let them be used internally from the JDK. This would let
> you retain full support for existing mechanisms.

Are you suggesting not to initialize the NSS software token in FIPS mode?

In case the answer is 'yes', does the crypto-team agree with not using any of the FIPS wrappers in NSS's fipstokn [8]? What should we care about to be FIPS compliant while using the NSS software token in non-FIPS mode?

In case the answer is 'no', how exactly are you suggesting to import keys to NSS DB while in FIPS mode [3]?

--
[1] - https://bugs.openjdk.java.net/browse/JDK-8217907
[2] - https://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.html#NSS
[3] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c#l805
[4] - https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/6.2/html/administration_and_configuration_guide/enable_fips_140-2_cryptography_for_ssl_on_red_hat_enterprise_linux_6
[5] - https://bugzilla.redhat.com/show_bug.cgi?id=1655466
[6] - http://hg.openjdk.java.net/jdk/jdk/file/3d2575331a41/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java
[7] - http://hg.openjdk.java.net/jdk/jdk/file/3d2575331a41/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c
[8] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c

Comment 9 Alicja Kario 2019-11-13 14:24:19 UTC
(In reply to mbalao from comment #8)
> (In reply to Alex Scheel from comment #7)
> > You can easily convert non-NSS-backed keys into NSS-backed
> > keys, even in FIPS mode,
> 
> You cannot in FIPS mode as far as I know, unless you implement some kind of
> hack/workaround to circumvent explicit checks against that or you use NSS in
> non-FIPS mode. See links below.
> 
> > 
> > Not doing so **breaks** existing applications and these changes **should**
> > be reverted until RHEL 8.2 release where all affected parties have more time
> > to discuss these changes and approve them. IMO it should never have been
> > introduced so late into the RHEL 8.1 release cycle, especially since we
> > received zero notification about these changes until they've already shipped.
> > 
> 
> SunJSSE security provider in OpenJDK has had "Experimental FIPS mode" since
> the very beginning (in 2007). It used to be documented until its removal in
> JDK-12 [1]. The goal was to make sure that all the crypto primitives for the
> SSL/TLS engine came from a single FIPS-compliant provider. It's not the root
> cause for the issues we have found though: removing KeyStore checks in
> SunJSSE or initializing SunJSSE in default (non-FIPS) mode would have caused
> the same trouble (see below).
> 
> OpenJDK has always supported NSS as a PKCS#11 backend and FIPS mode
> configuration has always been documented [2]. NSS, when configured in "fips"
> mode, cannot create private keys from raw-key material [3]. That's the
> reason why removing SunJSSE FIPS-mode KeyStore checks wouldn't have been
> enough. Even though the NSS software token is not an 'official' way of
> providing FIPS support in OpenJDK, that is what we have always offered to
> our customers and documented in RHEL [4].
> 
> What I mean with this recap is that nothing is new or has changed here in
> regards to how we configure OpenJDK in FIPS mode, so all this was a bit
> surprising to me. I agree that we should have integrated this change before.
> With that said, the patch and discussions have been available for a long
> time (see RH-1655466 [5]).

BTW, how are the individual keys stored in java databse? is the whole DB encrypted, or are the keys individually encrypted? If the latter, maybe NSS could handle the decryption as part of import?
 
> I can take from the crypto-team that there isn't a compliance reason to
> disallow the handling of keys out of the token -as long as they are
> protected in some way-. I don't really know the reason why the NSS software
> token enforces that in FIPS mode.

so importing unprotected keys in FIPS mode being disallowed is purely NSS thing, as you can quickly check with OpenSSL, it will allow creation of PKCS#12 files without encryption (`-certpbe NONE -keypbe NONE` are the lucky options) when system is working in FIPS mode

it's a long standing policy in NSS for this behaviour, so it's unlikely we will be able to remove it – in the past it likely was used because the NSS (Netscape and later Firefox) were considered standalone components (the "FIPS module), in RHEL we consider the machine to be the FIPS module, thus the different behaviour of OpenSSL.

> What I can say, though, is that
> fundamentally changing the way we offer FIPS support in OpenJDK (i.e.: not
> using NSS as a software backend) won't happen in the short term (before RHEL
> 8.2).

it's not something we would like to see: we want to have as few FIPS certified modules as possible, and have all the software we ship use those few FIPS certified modules in way consistent with their security policy (IOW have software we ship FIPS compliant)

> > But to respond:
> > 
> > For working with certificates:
> > 
> > The first call you need is CERT_ImportCerts(...) [0][1]. On receiving a
> > non-NSS-backed certificate from another portion of the JDK (say, a PKCS#12
> > file or otherwise), you can easily import it into the NSS DB with temporary
> > scope, which I believe should work even in read-only mode. But Bob Relyea
> > would know. This lets you utilize the certificate for TLS. If you need to
> > access it from PKCS#11, you'll then have to use PK11_ImportCert(...) [2][3]
> > on the CERTCertificate from CERT_ImportCerts(...). 
> > 
> > Or you could use PK11_ImportDerCert(...) [4][5] and bypass that dance. 
> > 
> > For working with public keys:
> > 
> > First use SECKEY_DecodeDERSubjectPublicKeyInfo(...) [6][7] to decode the
> > header, which you can pass to SECKEY_ExtractPublicKey(...) [8][9] to get a
> > SECKEYPublicKey object. This is what the NSS test suite does [10]. You can
> > then pass to PK11_ImportPublicKey(...) [11][12] to do with as you like from
> > the PKCS#11 layer.
> > 
> > You could also bypass that dance and use PK11_ImportDERPublicKey(...)
> > [13][14], but it doesn't appear to be tested so I'm not sure if it works.
> > 
> > For working with private keys: 
> > 
> > I'll skip the dance and point to to PK11_ImportDERPrivateKeyInfo(...)
> > [15][16] and PK11_ImportDERPrivateKeyInfoAndReturnKey(...) [17][18]. I'm
> > sure there's other ways to do this that dance around the import more and
> > give you more control over flags and such.
> > 
> > For working with symmetric keys:
> > 
> > PK11_ImportSymKey(...) [19][20] lets you directly import binary symmetric
> > keys just fine. I've used it in my test for CMAC upstream. [21]. 
> > 
> > For encoding certificates to their DER form from a NSS handle: 
> > 
> > CERT_GetCertificateDer(...) [22][23] lets you export a CERTCertificate *
> > back to DER for decoding in Java and passing to any TrustManager. 
> > 
> 
> Ok, you've shared a bunch of links to an NSS PKCS#11 wrapper library. In
> OpenJDK we have our own wrapper library [6][7] and perform all these
> actions. That's how PKCS11 keystores work importing and exporting
> certificates, keys, etc. When it comes to importing a private key, for
> instance, it boils down to calling C_CreateObject with specific arguments.
> 
> > In short, I think its perfectly reasonable to assume it isn't a technical
> > limitation in NSS that prohibits this and was instead an unreasonable design
> > choice on the part of the JDK. 
> > 
> 
> Can you please elaborate on that and why you say OpenJDK offers an
> 'unreasonable design choice'?

yes, I think there's a bit of confusion here: AFAIK NSS will refuse to import non-encrypted key to the database in FIPS mode...

> > 
> > Now we're onto the other part of the conversation... 
> > 
> >  1) NSS still lets you use older,  prohibited algorithms in FIPS mode
> > anyways, via its PKCS#11 API. In NSS's opinion, it is up to the caller to
> > comply with FIPS.
> >  2) You could, if you so chose, leave the implementations necessary for
> > compatibility with older JDKs (RC2...), not expose them via the provider
> > mechanism, and only let them be used internally from the JDK. This would let
> > you retain full support for existing mechanisms.
> 
> Are you suggesting not to initialize the NSS software token in FIPS mode?

no, you can use MD5, RC2, etc. in NSS working in FIPS mode

it's application's responsibility to ensure it's not used for protection of user data, NSS does not enforce that

(side note: OpenSSL does allow something similar too, but there it requires an explicit call to tell OpenSSL that it will not be used for protection of user data)
 
> In case the answer is 'yes', does the crypto-team agree with not using any
> of the FIPS wrappers in NSS's fipstokn [8]? What should we care about to be
> FIPS compliant while using the NSS software token in non-FIPS mode?

FIPS is concerned only with _protection_ of user data, if, say, a hash like MD5 is used for integrity protection of a web download, then FIPS is totally fine with that (especially if the alternative is use of CRC32 or something similarly weak).

> In case the answer is 'no', how exactly are you suggesting to import keys to
> NSS DB while in FIPS mode [3]?

requiring and supporting use of PKCS#12 files as input?
 
> --
> [1] - https://bugs.openjdk.java.net/browse/JDK-8217907
> [2] -
> https://docs.oracle.com/javase/8/docs/technotes/guides/security/p11guide.
> html#NSS
> [3] -
> https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c#l805
> [4] -
> https://access.redhat.com/documentation/en-us/
> jboss_enterprise_application_platform/6.2/html/
> administration_and_configuration_guide/enable_fips_140-
> 2_cryptography_for_ssl_on_red_hat_enterprise_linux_6
> [5] - https://bugzilla.redhat.com/show_bug.cgi?id=1655466
> [6] -
> http://hg.openjdk.java.net/jdk/jdk/file/3d2575331a41/src/jdk.crypto.cryptoki/
> share/classes/sun/security/pkcs11/P11KeyStore.java
> [7] -
> http://hg.openjdk.java.net/jdk/jdk/file/3d2575331a41/src/jdk.crypto.cryptoki/
> share/native/libj2pkcs11/p11_objmgmt.c
> [8] - https://hg.mozilla.org/projects/nss/file/tip/lib/softoken/fipstokn.c

Comment 10 Simo Sorce 2019-11-13 14:30:23 UTC
(In reply to mbalao from comment #8)
> Are you suggesting not to initialize the NSS software token in FIPS mode?

No, I think what is being suggested is that even in FIPS mode the Java wrappers should still allow to use pem files.
The trik is to create a temporary database and import keys there, the keys will need to be wrapped if they are not, and that's may feel to you like a hack/workaround, but it is fine to do that in this case.

> In case the answer is 'yes', does the crypto-team agree with not using any
> of the FIPS wrappers in NSS's fipstokn [8]? What should we care about to be
> FIPS compliant while using the NSS software token in non-FIPS mode?

You should use the token in FIPS mode, just add code to be able to load keys from pem files to it.

> In case the answer is 'no', how exactly are you suggesting to import keys to
> NSS DB while in FIPS mode [3]?

See above, all that is needed is that keys are wrapped before you can import in FIPS mode, it should be a rather simple "workaround".

HTH,
Simo.

Comment 13 jiri vanek 2020-07-01 10:22:59 UTC
Automated reproducer pushed

Comment 20 Martin Balao 2021-04-08 22:02:36 UTC
*** Bug 1908876 has been marked as a duplicate of this bug. ***

Comment 21 Martin Balao 2021-08-06 19:14:17 UTC
I opened RH1991003 (https://bugzilla.redhat.com/show_bug.cgi?id=1991003) that should better reflect what we will be doing as a result of the discussion in the context of this ticket. In that regard, we will be allowing the import of private/secret keys into the NSS Software Token (while in FIPS mode) but not exporting them as the initial report here seems to imply. I'll close this bug as a WON'T FIX not to generate confusion.


Note You need to log in before you can comment on or make changes to this bug.