FW: SFL bug with 512-bit DSA Certificates
"Colestock, Robert" <[email protected]> Tue, 16 Apr 2002 11:44:48 -0400
| Newsgroups | gmane.ietf.sfl |
|---|---|
| Message-ID | <[email protected]> |
FILES DELETED FOR GENERAL DISTRIBUTION! -----Original Message----- From: Colestock, Robert Sent: Monday, April 15, 2002 11:23 PM To: '[email protected]' Cc: '[email protected]' Subject: RE: SFL bug with 512-bit DSA Certificates Jim Craigie/John Stark: Some good news, some bad news. First please let me apologize for the inconvenience and thank you for your detailed response. Much of our inner crypto logic is hard-coded to specific lengths. Some of the logic was provided by outside sources, other logic is updated as necessary for specific customer requirements (some of it just plain learning on our part). Our focus is to provide SMIME processing and basic crypto. We will endeavor to correct any specific failures you encounter. 1.2.3.4.) ... DSAParam lengths not handled for 512 bit DSA keys ... At one time I had successfully tested verification of 512 bit DSA signatures. After testing with your private key (thank you for providing it), I discovered that the signature operations succeeded, but the verification failed using the sm_free3 CTIL. The Signing operation succeeds because the Private Key is properly formatted, there are no other references to the actual key length when signing. I am providing some source file changes to make the verification work correctly in the sm_free3 CTIL (so I suggest you rename your originals before replacing with these sources). These first, then I'll address the remainder of your issues. I am providing my current baseline sources, but they may not work with your version, so I will list the actual changes (minimal): <<<<<<<< in ./SMIME/libCtilMgr/src/sm_CtilCommon.cpp, around line16 in the constructor ... m_lParamLength = 128; // DEFAULT ... <<<<<<<< around line 90, for 64 byte DSA Decode ... m_lParamLength = paramLen; ... <<<<<<<< around line 141, for 128 byte DSA Decode ... m_lParamLength = SM_DSA_P_LEN; ... <<<<<<<< in ./SMIME/libCtilMgr/inc/sm_CtilCommon.h, around line 20 in the CSM_DSAParams class definition ... long m_lParamLength; ... <<<<<<<< in ./SMIME/alg_libs/sm_free3/sm_free3.cpp, around line 512 in the SMTI_VerifyDSA(...) method ... CSM_DSAParams dsaParameters; SME(dsaParameters.Decode(pParams)); pP = new Integer((const unsigned char *)dsaParameters.P, dsaParameters.m_lParamLength); pQ = new Integer((const unsigned char *)dsaParameters.Q, SM_DSA_Q_LEN); pG = new Integer((const unsigned char *)dsaParameters.G, dsaParameters.m_lParamLength); ... Now, onto your other comments. You are, of course, correct in your assertions. The library continues to improve as the need arises. The changes above will allow the sm_free3 CTIL to properly sign and verify 512 AND 1024 bit DSA keys. The internal CSM_Common::SMTI_VerifyInternalDSA(...) method executes a license un-encumbered source for DSA signature verification (true free-ware). At one time I had attempted to make this source handel 512 bit keys, but was unsuccessful (gave up after 12 hours work). If you looked at this code (./SMIME/libCtilMgr/src/fortezza.cpp), then you already know why it is difficult to modify ("C" written by someone I assume started life as an assembly programmer!). At this point we have no plans to update the internal DSA verify logic to handle 512 bit DSA keys. My solution was to upgrade the sm_free3 CTIL sources since the Crypto++ classes were much more flexible. The MS CAPI CTIL also works appropriately, since the CAPI interface handle all of the crypto details. 5.) ... CSM_DSAParams ... This method is only used by our test library for fixed length DSA keys (we do not have any customers that use 512 bit keys; all of our test utilities create 1024 bits DSA keys). One of the SetDSAParams(...) methods will handle variable length keys. I have updated the other to detect 512 or 1024 bit key lengths. Thank you. 6.) ... CSM_Free3::ExtractParams() ... Updated to recognize the integer length as 512 or 1024 bit keys. Thank you. <<<Incidentally, the sm_free3.cpp source makes similar assumptions that <<<Diffie-Hellman keys are 1024-bit. I have not listed these. This code will be left intact due to a lack of customer use/interest. If you encounter any problems, or wish to contibute any updatesd, you are welcome to do so, we will baseline any changes that keep backward compatibility. <<<Finally, here is a code snippet illustrating my statement that the <<<content-encryption algorithm key sizes for Triple-DES and RC2 are I did not realize that 3DES key lengths could be modified. I believe that the RC2 key generation length is specified in the SMIME RFCs, so our library only generates a specific key length. Up until now, no one has expressed any interest in allowing a variable RC2 encryption length. As to decryption, it is appropriately decoded from the RC2 parameter, not hard-coded. If you require such flexibility in encrypting, this could be added. Bob Colestock -----Original Message----- From: Jim Craigie To: Pawling, John Cc: [email protected] Sent: 4/11/2002 1:39 PM Subject: Re: SFL bug with 512-bit DSA Certificates John Stark writes: Here are some details of where I have found assumptions within the SFL 2.0.1 code that DSA keys are always 1024-bit. This list should not be regarded as definitive - there could be other code areas which I have not found that also require attention to fix the problem. The DSA/DSS spec can be found online at: http://www.itl.nist.gov/fipspubs/fip186.htm This indicates that DSA keys may be of any strength (== modulus size) in the range 512-1024 that is a multiple of 64. However it is conventional to use powers of two (i.e. 512 or 1024). SFL 2.0.1 file paths referred to below are relative to unpacked distribution. N.B. some of the line numbers could differ slightly in the original distribution since this information was taken from our source that has been ported to Solaris and had our own fixes applied. 1. SMIME/libCtilMgr/include/sm_apiCtilMgr.h, line 60: // Algorithm parameters oedefine SM_DSA_P_LEN 128 oedefine SM_DSA_Q_LEN 20 oedefine SM_DSA_G_LEN 128 In fact only Q is fixed at 20 bytes. Both P and G may vary between 64 and 128 bytes. 2. SMIME/libCtilMgr/include/sm_CtilCommon.h, line 12: class LIBCTILMGRDLL_API CSM_DSAParams { public: char *P; char *Q; char *G; CSM_DSAParams(); ~CSM_DSAParams(); SM_RET_VAL Decode(CSM_Buffer *pParams); }; This class has no data field to indicate the size of the P and G values. Where code elsewhere uses DSA parameters in this class, it has to assume the oedefined values referred to above. 3. SMIME/libCtilMgr/src/sm_CtilCommon.cpp, line 57 in CSM_DSAParams::Decode(): if (pSnaccV3CertParams->p.Len() <= 65) pParamSize = 64; // Smaller signature. else pParamSize = SM_DSA_P_LEN; // larger signature. This code seems to assume that the size may be either 512-bit or 1024-bit. Also pParamSize is a local variable that needs to be stored in the CSM_DSAParams class as described above. I have ignored the "V1 certificate" code that makes extensive use of the hardwired lengths. 4. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 509 in CSM_Free3::SMTI_VerifyDSA(): CSM_DSAParams dsaParameters; SME(dsaParameters.Decode(pParams)); pP = new Integer((const unsigned char *)dsaParameters.P, SM_DSA_P_LEN); pQ = new Integer((const unsigned char *)dsaParameters.Q, SM_DSA_Q_LEN); pG = new Integer((const unsigned char *)dsaParameters.G, SM_DSA_G_LEN); This is, I believe, the code that actually causes the problem we observe with our 512-bit certificates. Because dsaParameters doesn't contain the length, this code has to assume the defaults for 1024-bit. The Integers that are constructed end up padded with garbage. 5. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 2715 in CSM_Free3::SetDSAParams(): void CSM_Free3::SetDSAParams(AsnInt &P, AsnInt &Q, AsnInt &G) { CryptoPP::Integer *pTmpBI; pTmpBI = ComputeBigInteger(P, 128); m_DSAP = *pTmpBI; delete pTmpBI; pTmpBI = ComputeBigInteger(Q, 20); m_DSAQ = *pTmpBI; delete pTmpBI; pTmpBI = ComputeBigInteger(G, 128); m_DSAG = *pTmpBI; delete pTmpBI; } This assumes numeric constant parameter sizes, not even the oedefined values. 6. SMIME/alg_libs/sm_free3/sm_free3.cpp, line 3136 in CSM_Free3::ExtractParams(): else if (pAlgID->algorithm == id_dsa || pAlgID->algorithm == id_dsa_with_sha1) { //byte *pbyte; // ASN.1 decode pParams as DSA parameters // store them in m_DSAP, m_DSAQ, and m_DSAG FREE_DSAParameters snaccDSAParams; DECODE_ANY((&snaccDSAParams), (pAlgID->parameters)); // extract P Integer *pTmpBI; pTmpBI = ComputeBigInteger(snaccDSAParams.p, 128); //pbyte = (byte *)((char*)snaccDSAParams.p); m_DSAP = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.p.Len()); delete pTmpBI; // extract Q pTmpBI = ComputeBigInteger(snaccDSAParams.q, 20); //pbyte = (byte *)((char*)snaccDSAParams.q); m_DSAQ = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.q.Len()); delete pTmpBI; // extract G pTmpBI = ComputeBigInteger(snaccDSAParams.g, 128); //pbyte = (byte *)((char*)snaccDSAParams.g); m_DSAG = *pTmpBI; //RWC;.Decode(pbyte, snaccDSAParams.g.Len()); delete pTmpBI; } This similarly uses numeric constants for the parameter sizes. Incidentally, the sm_free3.cpp source makes similar assumptions that Diffie-Hellman keys are 1024-bit. I have not listed these. Finally, here is a code snippet illustrating my statement that the content-encryption algorithm key sizes for Triple-DES and RC2 are fixed: SMIME/alg_libs/sm_free3/sm_free3.cpp, line 849 in CSM_Free3::EncryptCryptoPP(): if (*pPreferredOID == des_ede3_cbc) { CBC_Length = SM_COMMON_3DES_BLOCKSIZE; CBC_KeyLength = SM_COMMON_3DES_KEYLEN; } else if (*pPreferredOID == rc2_cbc || *pPreferredOID == id_alg_CMSRC2wrap) { CBC_Length = SM_COMMON_RC2_BLOCKSIZE; // 8 CBC_KeyLength = SM_COMMON_RC2_KEYLEN; // byte count 16 } else if (*pPreferredOID == dES_CBC) { CBC_Length = SM_COMMON_3DES_BLOCKSIZE; CBC_KeyLength = 8; // for DES. } else // Default to 3DES length. { CBC_Length = SM_COMMON_3DES_BLOCKSIZE; CBC_KeyLength = SM_COMMON_3DES_KEYLEN; } John Stark E-mail: [email protected] Tel: +44 (0) 1223 566732 Fax: +44 (0) 1223 566727 Mobile: +44 (0) 7968 110628 ----------------------------------------------------------------------- Clearswift monitors, controls and protects all its messaging traffic in compliance with its corporate email policy using Clearswift products. Find out more about Clearswift, its solutions and services at http://www.clearswift.com ************************************************************************ ******************************** This communication is confidential and may contain privileged information intended solely for the named addressee(s). It may not be used or disclosed except for the purpose for which it has been sent. If you are not the intended recipient, you must not copy, distribute or take any action in reliance on it. Unless expressly stated, opinions in this message are those of the individual sender and not of Clearswift. If you have received this communication in error, please notify Clearswift by emailing [email protected] quoting the sender and delete the message and any attached documents. Clearswift accepts no liability or responsibility for any onward transmission or use of emails and attachments having left the Clearswift domain.