Bug 679377 - RFE: be more forgiving of malformed(?) kerberos CMS SignedData messages

r=emaldona


git-svn-id: svn://10.0.0.236/trunk@262935 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rrelyea%redhat.com 2011-09-30 19:42:09 +00:00
parent e6f6c77e65
commit 77c175d416
4 changed files with 92 additions and 6 deletions

View File

@ -42,7 +42,7 @@
* you. If that has a problem, then just move out what you need, changing
* its name as appropriate!
*
* $Id: cmslocal.h,v 1.7 2011-08-21 01:14:18 wtc%google.com Exp $
* $Id: cmslocal.h,v 1.8 2011-09-30 19:42:09 rrelyea%redhat.com Exp $
*/
#ifndef _CMSLOCAL_H_
@ -348,6 +348,12 @@ NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECO
extern SECStatus
NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
/*
* local function to handle compatibility issues
* by mapping a signature algorithm back to a digest.
*/
SECOidTag NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg);
/************************************************************************/

View File

@ -37,7 +37,7 @@
/*
* CMS signedData methods.
*
* $Id: cmssigdata.c,v 1.31 2011-02-11 01:53:17 emaldona%redhat.com Exp $
* $Id: cmssigdata.c,v 1.32 2011-09-30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -406,6 +406,25 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
if (rv != SECSuccess) {
return SECFailure;
}
/* handle issue with Windows 2003 servers and kerberos */
if (sigd->digestAlgorithms != NULL) {
int i;
for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
SECAlgorithmID *algid = sigd->digestAlgorithms[i];
SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm);
SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag);
if (maptag != senttag) {
SECOidData *hashoid = SECOID_FindOIDByTag(maptag);
rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm
,&hashoid->oid);
if (rv != SECSuccess) {
return rv;
}
}
}
}
/* set up the digests */
if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
/* if digests are already there, do nothing */

View File

@ -38,7 +38,7 @@
/*
* CMS signerInfo methods.
*
* $Id: cmssiginfo.c,v 1.35 2011-08-21 01:14:18 wtc%google.com Exp $
* $Id: cmssiginfo.c,v 1.36 2011-09-30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -530,7 +530,28 @@ NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
SECOidData *
NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
{
return SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
SECOidData *algdata;
SECOidTag algtag;
algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
if (algdata == NULL) {
return algdata;
}
/* Windows may have given us a signer algorithm oid instead of a digest
* algorithm oid. This call will map to a signer oid to a digest one,
* otherwise it leaves the oid alone and let the chips fall as they may
* if it's not a digest oid.
*/
algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
if (algtag != algdata->offset) {
/* if the tags don't match, then we must have received a signer
* algorithID. Now we need to get the oid data for the digest
* oid, which the rest of the code is expecting */
algdata = SECOID_FindOIDByTag(algtag);
}
return algdata;
}
SECOidTag
@ -543,7 +564,7 @@ NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
return SEC_OID_UNKNOWN;
}
algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
if (algdata != NULL)
return algdata->offset;
else

View File

@ -38,7 +38,7 @@
/*
* CMS miscellaneous utility functions.
*
* $Id: cmsutil.c,v 1.16 2011-01-28 23:03:59 rrelyea%redhat.com Exp $
* $Id: cmsutil.c,v 1.17 2011-09-30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -211,6 +211,45 @@ NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
return i;
}
/*
* Map a sign algorithm to a digest algorithm.
* This is used to handle incorrectly formatted packages sent to us
* from Windows 2003.
*/
SECOidTag
NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg)
{
switch (signAlg) {
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
return SEC_OID_MD2;
break;
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
return SEC_OID_MD5;
break;
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
return SEC_OID_SHA1;
break;
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
return SEC_OID_SHA256;
break;
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
return SEC_OID_SHA384;
break;
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
return SEC_OID_SHA512;
break;
default:
break;
}
/* not one of the algtags incorrectly sent to us*/
return signAlg;
}
const SECHashObject *
NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
{
@ -350,3 +389,4 @@ NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
}
return rv;
}