Bug 703658 - lib crmf uses a hard-coded maximum size of 2048 for wrapped private keys
Summary: lib crmf uses a hard-coded maximum size of 2048 for wrapped private keys
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: nss
Version: 6.2
Hardware: Unspecified
OS: Unspecified
high
medium
Target Milestone: rc
: ---
Assignee: Elio Maldonado Batiz
QA Contact: Aleš Mareček
URL:
Whiteboard:
Depends On: 703656
Blocks: 704595 705120 757917
TreeView+ depends on / blocked
 
Reported: 2011-05-11 00:22 UTC by Elio Maldonado Batiz
Modified: 2011-12-06 12:10 UTC (History)
7 users (show)

Fixed In Version: nss-3.12.9-11.el6
Doc Type: Bug Fix
Doc Text:
Clone Of: 703656
: 704595 (view as bug list)
Environment:
Last Closed: 2011-12-06 12:10:38 UTC
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2011:1584 0 normal SHIPPED_LIVE nspr, nss, nss-softokn and nss-util bug fix and enhancement update 2011-12-06 00:38:51 UTC

Description Elio Maldonado Batiz 2011-05-11 00:22:58 UTC
+++ This bug was initially created as a clone of Bug #703656 +++

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 2 Elio Maldonado Batiz 2011-05-11 00:59:03 UTC
This is also a RHEL 5.6 issue which affects the Certificate System, Andrew Wnuck, the original reporter informs us that CS 8.1 targets RHEL 5.6.

Comment 3 RHEL Program Management 2011-05-11 06:00:35 UTC
Since RHEL 6.1 External Beta has begun, and this bug remains
unresolved, it has been rejected as it is not proposed as
exception or blocker.

Red Hat invites you to ask your support representative to
propose this request, if appropriate and relevant, in the
next release of Red Hat Enterprise Linux.

Comment 12 errata-xmlrpc 2011-12-06 12:10:38 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2011-1584.html


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