Bug 703656

Summary: lib crmf uses a hard-coded maximum size of 2048 for wrapped private keys
Product: [Fedora] Fedora Reporter: Elio Maldonado Batiz <emaldona>
Component: nssAssignee: Elio Maldonado Batiz <emaldona>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: unspecified    
Version: 15CC: awnuk, emaldona, kdudka, kengert, rrelyea
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: nss-3.12.10-5.fc15 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 703658 (view as bug list) Environment:
Last Closed: 2011-08-05 23:57:27 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 703658, 704595, 705120, 757917    

Description Elio Maldonado Batiz 2011-05-11 00:18:22 UTC
Description of problem:
Kai Engert (:kaie) 2011-05-09 15:09:49 PDT

The crmf library uses a hardcoded maximum size of 2048 for wrapped private keys (MAX_WRAPPED_KEY_LEN)

We ran into a failure when trying to use generateCRMFRequest to produce a 4096 byte RSA key with a 1024 bit escrow cert.

Required output array is 2368.


#0  DES_Encrypt (cx=0xa4bbdd30, out=
    0xa4a0f800 "\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245"..., outLen=0xbfffb59c, maxOutLen=2048, in=0xa85f5000 "0\202\tB\002\001", inLen=2368) at desblapi.c:280
#1  0x04bd542b in DES_Encrypt (cx=0xa4bbdd30, output=
    0xa4a0f800 "\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245"..., outputLen=0xbfffb59c, maxOutputLen=2048, input=0xa85f5000 "0\202\tB\002\001", inputLen=2368) at loader.c:490
#2  0x04bb5230 in NSC_EncryptUpdate (hSession=16777217, pPart=0xa85f5000 "0\202\tB\002\001", ulPartLen=2368, pEncryptedPart=
    0xa4a0f800 "\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245"..., pulEncryptedPartLen=0xbfffb704) at pkcs11c.c:926
#3  0x04bb55cb in NSC_Encrypt (hSession=16777217, pData=0xa85f5000 "0\202\tB\002\001", ulDataLen=2374, pEncryptedData=
    0xa4a0f800 "\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245"..., pulEncryptedDataLen=0xbfffb704) at pkcs11c.c:1019
#4  0x04bbd107 in NSC_WrapKey (hSession=16777217, pMechanism=0xbfffb6f8, hWrappingKey=3, hKey=4120494076, pWrappedKey=
    0xa4a0f800 "\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245\245"..., pulWrappedKeyLen=0xbfffb704) at pkcs11c.c:4449
#5  0x03e316a5 in PK11_WrapPrivKey (slot=0xa6504800, wrappingKey=0xa4a423d0, privKey=0xa4a73810, wrapType=310, param=0xa4a4e050, wrappedKey=0xbfffb784, wincx=0x0) at pk11obj.c:1116
#6  0x02a2bcf4 in crmf_create_encrypted_value_wrapped_privkey (inPrivKey=0xa4a73810, inCAKey=0xa4a74810, destValue=0xa4a17100) at crmfcont.c:823
#7  0x02a2bf95 in CRMF_CreateEncryptedKeyWithEncryptedValue (inPrivKey=0xa4a73810, inCACert=0xa4bb0810) at crmfcont.c:908
#8  0x01fd9494 in nsSetEscrowAuthority (certReq=0xa4a74010, keyInfo=0xa4a160a0, wrappingCert=0xa4be9bc0) at /plaindata/moz/20/mozilla/security/manager/ssl/src/nsCrypto.cpp:982
#9  0x01fd9d9a in nsCreateSingleCertReq (keyInfo=0xa4a160a0, reqDN=0xa4b4e5a0 "CN=Kai Engert", regToken=0xb7d252bc "", authenticator=0xb7d252c2 "", wrappingCert=0xa4be9bc0) at /plaindata/moz/20/mozilla/security/manager/ssl/src/nsCrypto.cpp:1367
#10 0x01fda707 in nsCreateReqFromKeyPairs (keyids=0xa4a160a0, numRequests=1, reqDN=0xa4b4e5a0 "CN=Kai Engert", regToken=0xb7d252bc "", authenticator=0xb7d252c2 "", wrappingCert=0xa4be9bc0) at /plaindata/moz/20/mozilla/security/manager/ssl/src/nsCrypto.cpp:1764
#11 0x01fdbaf8 in nsCrypto::GenerateCRMFRequest (this=0xa4b4e130, aReturn=0xbfffbb68) at /plaindata/moz/20/mozilla/security/manager/ssl/src/nsCrypto.cpp:1978

Version-Release number of selected component (if applicable): nss 3.12.10 (also 3.12.9 and 3.12.8)

How reproducible: always


Steps to Reproduce:
1. use generateCRMFRequest to produce a 4096 byte RSA key with a 1024 bit escrow cert
  
Actual results: Request fails

Expected results: Request completes


Additional info:

Kai Engert (:kaie) 2011-05-09 15:17:22 PDT

Now the question is, should we

(a)
simply increase the limit

or

(b)
inside lib/crmf, could we query the desired output buffer size?

We're here:

CRMFEncryptedValue *
crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey   *inPrivKey,
					    SECKEYPublicKey    *inCAKey,
					    CRMFEncryptedValue *destValue)

[reply] [-] Comment 2 Elio Maldonado 2011-05-10 08:53:27 PDT

Wether we hard code ir or not, Could we have it defined in only one place?
http://mxr.mozilla.org/security/ident?i=MAX_WRAPPED_KEY_LEN
shows the constant difined in two places
* security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c (....)
  o line 60 -- #define MAX_WRAPPED_KEY_LEN 4096 
* security/nss/lib/crmf/crmfi.h (View CVS log or CVS annotations)
  o line 51 -- #define MAX_WRAPPED_KEY_LEN 2048

[reply] [-] Comment 3 Elio Maldonado 2011-05-10 10:49:54 PDT

Andrew, this change under discussion won't allow you to do 8092 keys as you aked. Perhaps #define MAX_WRAPPED_KEY_LEN 16384 would be a better value.

[reply] [-] Comment 4 Robert Relyea 2011-05-10 11:16:35 PDT

(sigh).

There's another define in blapi.h for the size of an RSA key in bits.

JSS should calculate MAX_WRAPPED_KEY_LEN (in bytes) from that (see below).

For now crmfi should also get max_wrapped key length from there, but really crmf should be written to be size independent. The rest of NSS handles any size RSA keys. (Only softoken limits the size of a key -- and that is just to prevent DOS attacks). crmf should malloc any data it needs to store and move the wrapped key.

NOTE: The definitions above hide the nature of and meaning of MAX_WRAPPED_KEY_LEN. I believe it is the maxium size of a fully wrapped RSA key in bytes, which is not necessarily the MAX_RSA_KEY_SIZE (in bits). Here is the calculation to needed to store a wrapped RSA key.

RSA Modulus (n): MAX_RSA_KEY_LENGTH_IN_BYTES + 3
RSA Public Exponent (e): 3 + 2
RSA Private Exponent (d): MAX_RSA_KEY_LENGTH_IN_BYTES +3
RSA Prime 1 (p): MAX_RSA_KEY_LENGTH_IN_BYTES/2 +3 
RSA Prime 2 (q): MAX_RSA_KEY_LENGTH_IN_BYTES/2 +3 
RSA Exponent 1 (d mod p-1): MAX_RSA_KEY_LENGTH_IN_BYTES/2 +3
RSA Exponent 2 (d mod p-2): MAX_RSA_KEY_LENGTH_IN_BYTES/2 +3
RSA Coefficent (q**-1 mod p): MAX_RSA_KEY_LENGTH_IN_BYTES/2 +3
Padding: up to 16 bytes.
RSA wrapped encryption key: MAX_RSA_KEY_LENGTH_IN_BYTES +3
Other DER overhead: order of 20 bytes

Total: MAX_RSA_KEY_LENGTH_IN_BYTES*5.5 + 65 (call it +100).
Now MAX_RSA_KEY_LENGTH_IN_BITS = MAX_RSA_KEY_LENGTH_IN_BYTES *8,

So if we take MAX_RSA_WRAPPED_KEY_LENGTH (in bytes) = MAX_RSA_KEY_LENGTH (in bits), then we should be OK, but we should outline that is what we are doing with a nice comment.

Comment 1 Fedora Update System 2011-07-22 17:34:53 UTC
nss-3.12.10-5.fc15 has been submitted as an update for Fedora 15.
https://admin.fedoraproject.org/updates/nss-3.12.10-5.fc15

Comment 2 Fedora Update System 2011-07-23 02:09:00 UTC
Package nss-3.12.10-5.fc15:
* should fix your issue,
* was pushed to the Fedora 15 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing nss-3.12.10-5.fc15'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/nss-3.12.10-5.fc15
then log in and leave karma (feedback).

Comment 3 Fedora Update System 2011-08-05 23:57:06 UTC
nss-3.12.10-5.fc15 has been pushed to the Fedora 15 stable repository.  If problems still persist, please make note of it in this bug report.