Closed Bug 1346748 Opened 8 years ago Closed 7 years ago

Support TLS 1.3 servers with RSA-PSS keys/certificates

Categories

(NSS :: Libraries, defect, P1)

3.28.2
defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: hkario, Assigned: ueno)

References

(Blocks 1 open bug)

Details

Attachments

(1 file)

Steps to Reproduce:
1. Setup server with attached server/key.pem and server/cert.pem
2. Create nssdb with ca/cert.pem certificate marked as trusted
3. tstclnt -d sql:./nssdb/ -h 127.0.0.1 -p 4433

Actual results:
tstclnt: authentication of server cert failed: SEC_ERROR_INADEQUATE_KEY_USAGE: Certificate key usage inadequate for attempted operation.

Expected results:
Connection established


When run with option -o, the tool prints:

Bad server certificate: -8102, Certificate key usage inadequate for attempted operation.
subject DN: CN=localhost
issuer  DN: O=Example CA
0 cache hits; 1 cache misses, 0 cache not reusable
0 stateless resumes
Received 0 Cert Status items (OCSP stapled data)

Additional info:
the server certificate is as follows:

Certificate:                                                                                                                        
    Data:                                                                                                                           
        Version: 3 (0x2)                                                                                                            
        Serial Number: 2 (0x2)                                                                                                      
    Signature Algorithm: rsassaPss                                                                                                  
         Hash Algorithm: sha256                                                                                                     
         Mask Algorithm: mgf1 with sha256                                                                                           
          Salt Length: 0xDE                                                                                                         
         Trailer Field: 0xBC (default)                                                                                              
        Issuer: O = Example CA
        Validity
            Not Before: Mar 10 17:04:10 2017 GMT
            Not After : Mar 10 17:04:10 2018 GMT
        Subject: CN = localhost
        Subject Public Key Info:
            Public Key Algorithm: rsassaPss
                RSA-PSS Public-Key: (2048 bit)
                Modulus:
                    00:bd:24:30:c6:f9:7e:a2:6c:cd:75:ac:c2:1a:2c:
                    0c:ab:1b:c7:ff:77:62:71:2a:e1:02:f1:eb:2e:42:
                    9f:42:47:90:78:99:5a:03:40:7b:4f:7d:6c:58:cc:
                    3b:9b:c5:e5:24:d7:0e:57:4d:ff:65:23:89:53:98:
                    56:7e:8e:b5:e0:74:cb:13:e3:d5:62:51:c9:cb:3d:
                    a8:a6:d6:72:8a:3c:32:a5:f1:b9:cb:95:96:2f:fb:
                    77:8c:93:d1:a9:5e:c4:6d:5d:6e:c9:d3:19:ea:2f:
                    e8:2e:7b:bb:51:49:aa:12:31:74:94:23:58:32:fe:
                    9d:14:1e:7a:86:4c:c4:c8:d8:04:79:6f:7c:af:fb:
                    93:87:da:e5:98:f5:bf:e9:1b:6a:18:6b:a1:43:f1:
                    d1:e9:1f:6b:f7:3a:04:59:69:a8:a9:c0:d9:ae:61:
                    4d:50:4f:61:23:d4:02:47:bf:d0:77:56:82:d4:a5:
                    a0:b5:04:d4:37:2e:60:76:e1:d6:1c:44:5a:f3:c5:
                    9a:59:1c:63:03:a0:da:05:9f:44:11:58:4b:2b:e1:
                    8b:3f:0b:b4:58:01:27:fd:93:a7:7b:b8:99:8e:d3:
                    e8:16:0c:26:b2:98:91:32:a1:f5:2b:81:42:93:4e:
                    46:75:fe:a7:e1:77:2a:94:bd:9f:92:38:8b:bd:ce:
                    91:bb
                Exponent: 65537 (0x10001)
                No PSS parameter restrictions
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Key Agreement
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Subject Key Identifier: 
                22:00:7A:95:7C:E8:54:EA:3A:7C:9A:68:EA:7A:F1:96:5C:E9:51:18
            X509v3 Authority Key Identifier: 
                keyid:BB:C1:AF:72:73:BB:0F:BB:DF:37:72:F6:FE:DB:5B:04:BD:B7:23:7B
                DirName:/O=Example CA
                serial:01

    Signature Algorithm: rsassaPss         
         Hash Algorithm: sha256
         Mask Algorithm: mgf1 with sha256
          Salt Length: 0xDE
         Trailer Field: 0xBC (default)

         85:59:e5:bf:71:17:97:ab:40:3d:b1:d9:b1:8f:58:6b:ca:fe:
         74:6b:a4:94:94:89:01:eb:38:d4:b9:3e:c5:db:6f:50:7d:71:
         e3:3f:69:4a:40:0d:47:05:f8:61:51:25:c5:4b:f6:df:b1:2a:
         ee:73:ae:e7:c0:8a:52:9c:1c:82:ae:c9:e1:59:7d:13:ff:92:
         7c:fd:87:f7:3c:0c:ae:dc:11:54:fc:f7:5a:b4:8a:39:38:5f:
         5a:7f:2f:68:4b:d4:b7:94:7e:93:35:2b:6a:05:1c:e4:b2:d2:
         dd:21:9d:66:62:0e:30:d1:03:90:20:13:b8:73:cc:e0:15:fc:
         b6:a3:9f:1a:c7:cd:5a:0e:2e:13:0a:60:fd:52:1f:e5:b1:e1:
         eb:90:c8:bf:55:6b:9f:8a:53:8f:36:1e:d5:0f:50:1d:a3:81:
         15:c1:cd:4d:0b:7e:b6:c5:96:cc:e2:d1:91:36:b3:0b:09:02:
         ae:9f:81:f1:67:c0:f2:2c:a3:eb:94:94:35:96:9f:3a:7a:46:
         1a:8c:34:6b:34:1b:53:72:a5:a1:81:57:57:5a:16:1e:2c:47:
         df:37:9e:e6:6c:cb:e7:9e:39:04:5e:aa:47:71:ac:4d:49:29:
         68:13:c2:e9:16:59:98:a4:05:24:53:aa:8a:75:98:5d:3d:91:
         ee:16:97:c3
Status: UNCONFIRMED → NEW
Ever confirmed: true
This patch fixes the SEC_ERROR_INADEQUATE_KEY_USAGE, 

@@ -1188,16 +1188,17 @@ CERT_CheckKeyUsage(CERTCertificate *cert
         /* turn off the special bit */
         requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT);
 
         switch (keyType) {
             case rsaKey:
                 requiredUsage |= KU_KEY_ENCIPHERMENT;
                 break;
             case dsaKey:
+            case rsaPssKey:
                 requiredUsage |= KU_DIGITAL_SIGNATURE;
                 break;
             case dhKey:
                 requiredUsage |= KU_KEY_AGREEMENT;
                 break;
             case ecKey:
                 /* Accept either signature or agreement. */
                 if (!(cert->keyUsage &

but then we get SEC_ERROR_BAD_SIGNATURE, probably the same as in bug 1432142.

Breakpoint 2, vfy_CreateContext (key=0x685ad0, sig=0x7fffffffc520, encAlg=SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg=SEC_OID_UNKNOWN, hash=0x7fffffffc51c, wincx=0x61b8a0 <pwdata>) at secvfy.c:449
449	                PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
(gdb) bt
#0  vfy_CreateContext (key=0x685ad0, sig=0x7fffffffc520, encAlg=SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg=SEC_OID_UNKNOWN, hash=0x7fffffffc51c, wincx=0x61b8a0 <pwdata>) at secvfy.c:449
#1  0x00007ffff6d6cf8d in vfy_VerifyData (
    buf=0x67cba4 "0\202\002F\240\003\002\001\002\002\001\002\060>\006\t*\206H\206\367\r\001\001\n01\240\r0\v\006\t`\206H\001e\003\004\002\001\241\032\060\030\006\t*\206H\206\367\r\001\001\b0\v\006\t`\206H\001e\003\004\002\001\242\004\002\002", len=586, key=0x685ad0, sig=0x7fffffffc520, encAlg=SEC_OID_PKCS1_RSA_PSS_SIGNATURE, hashAlg=SEC_OID_UNKNOWN, hash=0x7fffffffc51c, wincx=0x61b8a0 <pwdata>) at secvfy.c:730
#2  0x00007ffff6d6d153 in VFY_VerifyDataWithAlgorithmID (
    buf=0x67cba4 "0\202\002F\240\003\002\001\002\002\001\002\060>\006\t*\206H\206\367\r\001\001\n01\240\r0\v\006\t`\206H\001e\003\004\002\001\241\032\060\030\006\t*\206H\206\367\r\001\001\b0\v\006\t`\206H\001e\003\004\002\001\242\004\002\002", len=586, key=0x685ad0, sig=0x7fffffffc520, sigAlgorithm=0x67c8e0, hash=0x7fffffffc51c, wincx=0x61b8a0 <pwdata>) at secvfy.c:780
#3  0x00007ffff6d619a4 in CERT_VerifySignedDataWithPublicKey (sd=0x67c8c8, pubKey=0x685ad0, wincx=0x61b8a0 <pwdata>) at certvfy.c:150
#4  0x00007ffff6d61afb in CERT_VerifySignedData (sd=0x67c8c8, cert=0x684050, t=1501246838694854, wincx=0x61b8a0 <pwdata>) at certvfy.c:211
#5  0x00007ffff6d624b8 in cert_VerifyCertChainOld (handle=0x656e90, cert=0x67c8b0, checkSig=1, sigerror=0x0, certUsage=certUsageSSLServer, t=1501246838694854, wincx=0x61b8a0 <pwdata>, log=0x0, revoked=0x0) at certvfy.c:692
#6  0x00007ffff6d62e02 in cert_VerifyCertChain (handle=0x656e90, cert=0x67c8b0, checkSig=1, sigerror=0x0, certUsage=certUsageSSLServer, t=1501246838694854, wincx=0x61b8a0 <pwdata>, log=0x0, revoked=0x0) at certvfy.c:943
#7  0x00007ffff6d62e57 in CERT_VerifyCertChain (handle=0x656e90, cert=0x67c8b0, checkSig=1, certUsage=certUsageSSLServer, t=1501246838694854, wincx=0x61b8a0 <pwdata>, log=0x0) at certvfy.c:952
#8  0x00007ffff6d63e9a in cert_VerifyCertWithFlags (handle=0x656e90, cert=0x67c8b0, checkSig=1, certUsage=certUsageSSLServer, t=1501246838694854, flags=0, wincx=0x61b8a0 <pwdata>, log=0x0) at certvfy.c:1570
#9  0x00007ffff6d63be7 in CERT_VerifyCert (handle=0x656e90, cert=0x67c8b0, checkSig=1, certUsage=certUsageSSLServer, t=1501246838694854, wincx=0x61b8a0 <pwdata>, log=0x0) at certvfy.c:1481
#10 0x00007ffff72fb8f6 in SSL_AuthCertificate (arg=0x656e90, fd=0x65e4b0, checkSig=1, isServer=0) at sslauth.c:273
#11 0x0000000000406c3c in restartHandshakeAfterServerCertIfNeeded (fd=0x65e4b0, serverCertAuth=0x61c5c0 <serverCertAuth>, override=0) at tstclnt.c:860
#12 0x0000000000407e28 in run_client () at tstclnt.c:1328
#13 0x00000000004091b8 in main (argc=7, argv=0x7fffffffdaa8) at tstclnt.c:1887

vfy_CreateContext doesn't handle the rsaPssKey type yet.
Summary: RSA-PSS certificate rejected with SEC_ERROR_INADEQUATE_KEY_USAGE. → Support TLS 1.3 servers with RSA-PSS keys/certificates
Who is able to suggest how to extend vfy_CreateContext to correctly handle the RSA-PSS scenario?

https://hg.mozilla.org/projects/nss/file/b7db147b471b/lib/cryptohi/secvfy.c#l398
Note that we have a test for this in our gtests, and the certificate includes the Key Usage extension.  I'm not sure how we avoid the problem Kai patched here, probably because the libssl code was updated, but the rest of the certificate handling was not.

certutil -d ~/ssl_gtests -L -n rsa_pss
...
    Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
...

This shows that we are OK if the EE key is PSS, but not if the chain contains PSS signatures, which is likely what is causing the problems here.

I see that Hubert opened bug 1341316 on the invalid RSA-PSS parameters, that's good.
Tim, can you answer comment 2?  Is this as simple as adding rsaPssKey to the rsaKey branch?
Flags: needinfo?(ttaubert)
I'm not sure, sorry. It's been quite a while since I touched that code... maybe someone should just give it a try and see how that goes?
Flags: needinfo?(ttaubert)
Priority: -- → P3
I think that we want to bump the priority of this one up a little.  We are going to be shipping a client that advertises support for PSS and we don't want to choke on certificates that are otherwise valid.
Priority: P3 → P1
Target Milestone: --- → 3.34
I have checked this with the patch attached to bug 1400844, and the problem seems to be fixed:

  $ tstclnt -d sql:nssdb -h localhost -p 4433           
  subject DN: CN=localhost
  issuer  DN: O=Example CA
  0 cache hits; 1 cache misses, 0 cache not reusable
  0 stateless resumes
  Received 0 Cert Status items (OCSP stapled data)

The patch was meant for fixing certutil verifying a certificate chain which contains any RSA-PSS signed certificates, but also includes the change from comment 1 and extension to VFY_VerifyDataWithAlgorithmID to actually respect RSA-PSS parameters.

I will add SSL tests (which is currently missing), if it makes sense.
See Also: → 1400844
That's great!

For SSL, I think that a gtest is easiest.  Here is what we would need:

A chain with PSS in the fixture.  We currently only create a "CA" in the test setup that uses plain RSA.

see https://searchfox.org/nss/rev/f5afb96d0b081983720469d0fc5fb9ea66837172/tests/ssl_gtests/ssl_gtests.sh#52-53,88-89

New constants:

see https://searchfox.org/nss/rev/f5afb96d0b081983720469d0fc5fb9ea66837172/gtests/ssl_gtest/tls_agent.h#69
and https://searchfox.org/nss/rev/f5afb96d0b081983720469d0fc5fb9ea66837172/gtests/ssl_gtest/tls_agent.cc#39

And a simple test.  

see for example https://searchfox.org/nss/rev/f5afb96d0b081983720469d0fc5fb9ea66837172/gtests/ssl_gtest/ssl_auth_unittest.cc#31-38

Checking that the EE is signed with a PSS signature might be worth doing, just because this is so new.

I'd be happy to review that patch.
Assignee: nobody → dueno
> We currently only create a "CA" in the test setup that uses plain RSA.

this is more of a problem for certificates with rsa-pss signatures (which not necessarily have to be made using rsa-pss keys)

EE certificate with RSA-PSS key can be signed with rsa-pkcs#1 v1.5 signature and it still needs to work.

So for the test cases I'd suggest something like this:
 - RSA-PKCS#1 CA -> RSA-PSS EE key/RSA-PKCS#1 signature
 - RSA-PKCS#1 CA -> RSA-PKCS#1 key/RSA-PSS signature
 - RSA-PKCS#1 CA -> RSA-PSS EE key/RSA-PSS signature
 - RSA-PSS CA -> RSA-PSS EE key and signature

For negative testing it would be good to have RSA-PSS CA certificate with limitations and EE certificate with signature that violates those limitations.
We could certainly add multiple.  I was recommending the minimal approach.

We currently only have RSA-PKCS#1 CA -> RSA-PKCS#1 EE and RSA-PKCS#1 CA -> RSA-PSS EE.
Thank you for the information.  I have added SSL tests and updated the patch at:
https://phabricator.services.mozilla.com/D66
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: