Closed Bug 1471985 Opened Last year Closed Last year

RSA-PSS key from PKCS#12 file is unusable

Categories

(NSS :: Libraries, defect)

3.38
defect
Not set

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: hkario, Assigned: ueno)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

NSS selfserv will not start if the nickname is a RSA-PSS certificate imported from PKCS#12 file.

This is using c84a61acb17d (few commits after 3.38)

Using OpenSSL 1.1.1 generate a RSA-PSS key and certificate, import it to nssdb:
openssl req -x509 -newkey rsa-pss -pkeyopt rsa_keygen_bits:2048 \
-keyout /tmp/localhost-pss.key -out /tmp/localhost-pss.crt \
-subj /CN=localhost -nodes -batch
mkdir /tmp/nssdb
certutil -N -d sql:/tmp/nssdb --empty-password
openssl pkcs12 -export -passout pass: -out /tmp/localhost-pss.p12 \
-inkey /tmp/localhost-pss.key -in /tmp/localhost-pss.crt \
-name localhost
pk12util -i /tmp/localhost-pss.p12 -d sql:/tmp/nssdb -W ''

Try to start the nss server:
selfserv -d sql:/tmp/nssdb -p 4433 -V tls1.0: -H 1 -n localhost -u

Error is printed:
selfserv: SSL_ConfigServerCert returned error -8187:
security library: invalid arguments.
Blocks: 158750
I did try with the keys and certificates generated with NSS and they don't work either:

NSS_DIR="$(pwd)/dist/$(cat dist/latest)"
LD_LIBRARY_PATH="$NSS_DIR/lib" "$NSS_DIR/bin/certutil" -N -d sql:/tmp/nssdb/ --empty-password
dd if=/dev/urandom of=/tmp/random  bs=1 count=512
LD_LIBRARY_PATH="$NSS_DIR/lib" "$NSS_DIR/bin/certutil" -S -z /tmp/random -n rsaca -s 'cn=RSA Testing CA' -t 'C,C,C' -m 1000 -Z SHA256 -k rsa -g 2048 -x -v 12 -d sql:/tmp/nssdb --keyUsage digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,certSigning,crlSigning,critical -2
LD_LIBRARY_PATH="$NSS_DIR/lib" "$NSS_DIR/bin/certutil" -S -z /tmp/random -n rsapsssrv-uncos -s 'o=Unconstrained RSA-PSS Testing,cn=localhost' --pss -t 'u,u,u' -m 2002 -k rsa -g 2048 -c rsaca -v 12 -d sql:/tmp/nssdb/ --keyUsage digitalSignature,critical -2 -8 localhost


after starting the server:
LD_LIBRARY_PATH="$NSS_DIR/lib" "$NSS_DIR/bin/selfserv" -d sql:/tmp/nssdb -p 4433 -V tls1.0: -H 1 -n rsapsssrv-uncos

it prints:
selfserv: HDX PR_Read returned error -12153:
The peer used an unsupported combination of signature and hash algorithm.

While I verified with wireshark that the openssl presents all the rsa-pss mechanisms (rsa_pss_pss_*, rsa_pss_rsae_* and of course the rsa_pkcs1_*)
(In reply to Hubert Kario from comment #0)

> Error is printed:
> selfserv: SSL_ConfigServerCert returned error -8187:
> security library: invalid arguments.

This is because of the inconsistency between the return value of SECKEY_GetPublicKeyType() and SECKEY_GetPrivateKeyType().
In bug 1413596, we changed SECKEY_GetPrivateKeyType() to return rsaPssKey if the private key is restricted to RSA-PSS when imported, while SECKEY_GetPublicKeyType() still returns rsaKey, even when it is extracted from an RSA-PSS certificate.

I think there are two options:
- change SECKEY_GetPrivateKeyType() to return rsaPssKey as well, where appropriate, e.g., called after CERT_ExtractPublicKey()
- revert the fix in bug 1413596 and add a new function, e.g., SECKEY_GetPrivateKeyInfo() to let the caller determine whether a private key is restricted to RSA-PSS

The former approach affects many part of the NSS code and the behavior seems unpredictable, although there are already some code assuming it returns rsaPssKey.  The latter seems safer and less ambiguous, while it also requires a function to convert a certificate to KeyType (so two new functions are needed).
In bug 1413596, we changed SECKEY_GetPrivateKeyType() to return
rsaPssKey, if the private key is restricted to RSA-PSS when importing.
Although the intention of this change was to extend the certutil
output to provide more information about key types, it introduced
inconsistency with the existing code, as SECKEY_GetPublicKeyType()
still returns rsaKey.

This patch partially revert the change and determine the actual
(restricted) key type in a different way, using CERT_GetCertKeyType()
and PK11_GetCertFromPrivateKey().
Attachment #8989129 - Flags: review?(rrelyea)
Comment on attachment 8989129 [details]
Bug 1471985, make SECKEY_Get{Public,Private}KeyType consistent on RSA-PSS

r+ This implements what Daiki proposed in comment 3.

Let me not what this does: it means any key we create implicitly will be be type RSA, which means if you just pass a key to sign, it will sign with the RSA/PKCS#1 rather then PSS.

I've not followed how PSS has been integrated, so this may be OK (whenever we what PSS we explicitly ask for it, for instance).

It does mean that PSS enforcement needs to be at a pretty high level, but that makes sense since it's being treated as an attribute of the certificate (like key usage), so we should be find there.

bob
Attachment #8989129 - Flags: review?(rrelyea) → review+
Assignee: nobody → dueno
Target Milestone: --- → 3.39
Comment on attachment 8989129 [details]
Bug 1471985, make SECKEY_Get{Public,Private}KeyType consistent on RSA-PSS

Robert Relyea has been removed from the revision.

https://phabricator.services.mozilla.com/D1911
Attachment #8989129 - Flags: review+
Comment on attachment 8989129 [details]
Bug 1471985, make SECKEY_Get{Public,Private}KeyType consistent on RSA-PSS

Franziskus Kiefer [:fkiefer or :franziskus] has approved the revision.

https://phabricator.services.mozilla.com/D1911
Attachment #8989129 - Flags: review+
Landed as:
https://hg.mozilla.org/projects/nss/rev/45d04cb67cda
Status: NEW → RESOLVED
Closed: Last year
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.