Bug 475578 - Implement Extended DSA as defined in FIPS 186-3 (DSS)
authorrrelyea%redhat.com
Mon, 25 Jun 2012 21:48:41 +0000
changeset 10393 0b2bfb8edac19a297baf86e946392179bb423d19
parent 10392 884b916c47fee8a8bf93920b6a6afb4e64aa4a54
child 10394 b71f71900121498e6f21d2ed3128c85456d4b960
push idunknown
push userunknown
push dateunknown
bugs475578
Bug 475578 - Implement Extended DSA as defined in FIPS 186-3 (DSS) r = wtc patch 5 of 7
security/nss/lib/cryptohi/cryptohi.h
security/nss/lib/cryptohi/dsautil.c
security/nss/lib/cryptohi/seckey.c
security/nss/lib/cryptohi/secsign.c
security/nss/lib/cryptohi/secvfy.c
security/nss/lib/pk11wrap/pk11pub.h
security/nss/lib/pk11wrap/pk11slot.c
security/nss/lib/util/secoid.c
security/nss/lib/util/secoidt.h
--- a/security/nss/lib/cryptohi/cryptohi.h
+++ b/security/nss/lib/cryptohi/cryptohi.h
@@ -22,27 +22,27 @@
 SEC_BEGIN_PROTOS
 
 
 /****************************************/
 /*
 ** DER encode/decode (EC)DSA signatures
 */
 
-/* ANSI X9.57 defines DSA signatures as DER encoded data.  Our DSA code (and
+/* ANSI X9.57 defines DSA signatures as DER encoded data.  Our DSA1 code (and
  * most of the rest of the world) just generates 40 bytes of raw data.  These
  * functions convert between formats.
  */
 extern SECStatus DSAU_EncodeDerSig(SECItem *dest, SECItem *src);
 extern SECItem *DSAU_DecodeDerSig(const SECItem *item);
 
 /*
- * Unlike DSA, raw ECDSA signatures do not have a fixed length.
+ * Unlike DSA1, raw DSA2 and ECDSA signatures do not have a fixed length.
  * Rather they contain two integers r and s whose length depends
- * on the size of the EC key used for signing.
+ * on the size of q or the EC key used for signing.
  *
  * We can reuse the DSAU_EncodeDerSig interface to DER encode
  * raw ECDSA signature keeping in mind that the length of r 
  * is the same as that of s and exactly half of src->len.
  *
  * For decoding, we need to pass the length of the desired
  * raw signature (twice the key size) explicitly.
  */
--- a/security/nss/lib/cryptohi/dsautil.c
+++ b/security/nss/lib/cryptohi/dsautil.c
@@ -1,18 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "cryptohi.h"
 #include "secasn1.h"
 #include "secitem.h"
 #include "prerr.h"
 
-#ifndef DSA_SUBPRIME_LEN
-#define DSA_SUBPRIME_LEN 20	/* bytes */
+#ifndef DSA1_SUBPRIME_LEN
+#define DSA1_SUBPRIME_LEN 20	/* bytes */
 #endif
 
 typedef struct {
     SECItem r;
     SECItem s;
 } DSA_ASN1Signature;
 
 const SEC_ASN1Template DSA_SignatureTemplate[] =
@@ -150,17 +150,17 @@ common_EncodeDerSig(SECItem *dest, SECIt
 
     /* XXX leak item? */
     return SECSuccess;
 }
 
 /* src is a DER-encoded ECDSA or DSA signature.
 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
 ** buffer containing the "raw" signature, which is len bytes of r,
-** followed by len bytes of s. For DSA, len is always DSA_SUBPRIME_LEN.
+** followed by len bytes of s. For DSA, len is the length of q.
 ** For ECDSA, len depends on the key size used to create the signature.
 */
 static SECItem *
 common_DecodeDerSig(const SECItem *item, unsigned int len)
 {
     SECItem *         result = NULL;
     SECStatus         status;
     DSA_ASN1Signature sig;
@@ -208,24 +208,24 @@ done:
 loser:
     if (result != NULL) {
 	SECITEM_FreeItem(result, PR_TRUE);
 	result = NULL;
     }
     goto done;
 }
 
-/* src is a "raw" DSA signature, 20 bytes of r followed by 20 bytes of s.
+/* src is a "raw" DSA1 signature, 20 bytes of r followed by 20 bytes of s.
 ** dest is the signature DER encoded. ?
 */
 SECStatus
 DSAU_EncodeDerSig(SECItem *dest, SECItem *src)
 {
-    PORT_Assert(src->len == 2 * DSA_SUBPRIME_LEN);
-    if (src->len != 2 * DSA_SUBPRIME_LEN) {
+    PORT_Assert(src->len == 2 * DSA1_SUBPRIME_LEN);
+    if (src->len != 2 * DSA1_SUBPRIME_LEN) {
     	PORT_SetError( PR_INVALID_ARGUMENT_ERROR );
 	return SECFailure;
     }
 
     return common_EncodeDerSig(dest, src);
 }
 
 /* src is a "raw" DSA signature of length len (len/2 bytes of r followed
@@ -241,23 +241,23 @@ DSAU_EncodeDerSigWithLen(SECItem *dest, 
 	return SECFailure;
     }
 
     return common_EncodeDerSig(dest, src);
 }
 
 /* src is a DER-encoded DSA signature.
 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
-** buffer containing the "raw" DSA signature, which is 20 bytes of r,
+** buffer containing the "raw" DSA1 signature, which is 20 bytes of r,
 ** followed by 20 bytes of s.
 */
 SECItem *
 DSAU_DecodeDerSig(const SECItem *item)
 {
-    return common_DecodeDerSig(item, DSA_SUBPRIME_LEN);
+    return common_DecodeDerSig(item, DSA1_SUBPRIME_LEN);
 }
 
 /* src is a DER-encoded ECDSA signature.
 ** Returns a newly-allocated SECItem structure, pointing at a newly allocated
 ** buffer containing the "raw" ECDSA signature of length len containing
 ** r followed by s (both padded to take up exactly len/2 bytes).
 */
 SECItem *
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -320,21 +320,29 @@ seckey_UpdateCertPQGChain(CERTCertificat
     if (count > CERT_MAX_CERT_CHAIN) {
 	return SECFailure;
     }
 
     oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm);            
     if (oid != NULL) {  
         tag = oid->offset;
              
-        /* Check if cert has a DSA public key. If not, return
-         * success since no PQG params need to be updated.  */
+        /* Check if cert has a DSA or EC public key. If not, return
+         * success since no PQG params need to be updated.
+	 *
+	 * Question: do we really need to do this for EC keys. They don't have
+	 * PQG parameters, but they do have parameters. The question is does
+	 * the child cert inherit thost parameters for EC from the parent, or
+	 * do we always include those parameters in each cert.
+	 */
 
 	if ( (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
              (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
+             (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
+             (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
              (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
              (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
              (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
             
             return SECSuccess;
         }
     } else {
         return SECFailure;  /* return failure if oid is NULL */  
@@ -367,16 +375,18 @@ seckey_UpdateCertPQGChain(CERTCertificat
     if (oid != NULL) {  
         tag = oid->offset;
              
         /* Check if issuer cert has a DSA public key. If not,
          * return failure.   */
 
 	if ( (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
              (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
+             (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
+             (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
              (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
              (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
              (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {            
             rv = SECFailure;
             goto loser;
         }
     } else {
         rv = SECFailure;  /* return failure if oid is NULL */  
@@ -995,17 +1005,17 @@ SECKEY_SignatureLen(const SECKEYPublicKe
     unsigned char b0;
     unsigned size;
 
     switch (pubk->keyType) {
     case rsaKey:
     	b0 = pubk->u.rsa.modulus.data[0];
     	return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
     case dsaKey:
-    	return DSA_SIGNATURE_LEN;
+	return pubk->u.dsa.params.subPrime.len * 2;
     case ecKey:
 	/* Get the base point order length in bits and adjust */
 	size =	SECKEY_ECParamsToBasePointOrderLen(
 		&pubk->u.ec.DEREncodedParams);
 	return ((size + 7)/8) * 2;
     default:
 	break;
     }
--- a/security/nss/lib/cryptohi/secsign.c
+++ b/security/nss/lib/cryptohi/secsign.c
@@ -321,17 +321,28 @@ SEC_DerSignData(PRArenaPool *arena, SECI
      */
 
     if (algID == SEC_OID_UNKNOWN) {
 	switch(pk->keyType) {
 	  case rsaKey:
 	    algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
 	    break;
 	  case dsaKey:
-	    algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
+	    /* get Signature length (= q_len*2) and work from there */
+	    switch (PK11_SignatureLen(pk)) {
+		case 448:
+		    algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST;
+		    break;
+		case 512:
+		    algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST;
+		    break;
+		default:
+		    algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
+		    break;
+	    }
 	    break;
 	  case ecKey:
 	    algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
 	    break;
 	  default:
 	    PORT_SetError(SEC_ERROR_INVALID_KEY);
 	    return SECFailure;
 	}
@@ -457,16 +468,20 @@ SEC_GetSignatureAlgorithmOidTag(KeyType 
 	    break;
 	}
 	break;
     case dsaKey:
 	switch (hashAlgTag) {
 	case SEC_OID_UNKNOWN:	/* default for DSA if not specified */
 	case SEC_OID_SHA1:
 	    sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break;
+	case SEC_OID_SHA224:
+	    sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break;
+	case SEC_OID_SHA256:
+	    sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break;
 	default:
 	    break;
 	}
 	break;
     case ecKey:
 	switch (hashAlgTag) {
 	case SEC_OID_UNKNOWN:	/* default for ECDSA if not specified */
 	case SEC_OID_SHA1:
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -98,17 +98,17 @@ struct VFYContextStr {
      * the size of the union or some other union member instead.
      */
     union {
 	unsigned char buffer[1];
 
 	/* the digest in the decrypted RSA signature */
 	unsigned char rsadigest[HASH_LENGTH_MAX];
 	/* the full DSA signature... 40 bytes */
-	unsigned char dsasig[DSA_SIGNATURE_LEN];
+	unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
 	/* the full ECDSA signature */
 	unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
     } u;
     unsigned int rsadigestlen;
     void * wincx;
     void *hashcx;
     const SECHashObject *hashobj;
     SECOidTag encAlg;  /* enc alg */
@@ -205,20 +205,22 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
 	break;
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
         *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
 	break;
 
       case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
       case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
+      case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
 	*hashalg = SEC_OID_SHA224;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
+      case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
 	*hashalg = SEC_OID_SHA256;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
 	*hashalg = SEC_OID_SHA384;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
@@ -302,16 +304,18 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
 	break;
       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
 	*encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
 	break;
 
       /* what about normal DSA? */
       case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
       case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
+      case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
+      case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
 	*encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
 	break;
       case SEC_OID_MISSI_DSS:
       case SEC_OID_MISSI_KEA_DSS:
       case SEC_OID_MISSI_KEA_DSS_OLD:
       case SEC_OID_MISSI_DSS_OLD:
 	*encalg = SEC_OID_MISSI_DSS;
 	break;
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -143,19 +143,19 @@ SECMODModule *PK11_GetModule(PK11SlotInf
 /*********************************************************************
  *            Slot mapping utility functions.
  *********************************************************************/
 PRBool PK11_IsPresent(PK11SlotInfo *slot);
 PRBool PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
 PK11SlotList * PK11_GetAllTokens(CK_MECHANISM_TYPE type,PRBool needRW,
 					PRBool loadCerts, void *wincx);
 PK11SlotInfo *PK11_GetBestSlotMultipleWithKeySize(CK_MECHANISM_TYPE *type, 
-			  unsigned long *keySize, int count, void *wincx);
-PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int count,
-							void *wincx);
+			 unsigned long *keySize, unsigned int count, void *wincx);
+PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, 
+					unsigned int count, void *wincx);
 PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
 PK11SlotInfo *PK11_GetBestSlotWithKeySize(CK_MECHANISM_TYPE type, 
 					unsigned long keySize, void *wincx);
 CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
 int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
 
 /*
  * Open a new database using the softoken. The caller is responsible for making
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -1957,21 +1957,22 @@ PK11_GetPrivateKeyTokens(CK_MECHANISM_TY
 
 
 /*
  * Find the best slot which supports the given set of mechanisms and key sizes.
  * In normal cases this should grab the first slot on the list with no fuss.
  * The size array is presumed to match one for one with the mechanism type 
  * array, which allows you to specify the required key size for each
  * mechanism in the list. Whether key size is in bits or bytes is mechanism
- * dependent. Typically
+ * dependent. Typically asymetric keys are in bits and symetric keys are in 
+ * bytes.
  */
 PK11SlotInfo *
 PK11_GetBestSlotMultipleWithKeySize(CK_MECHANISM_TYPE *type, 
-                              unsigned long *size, int mech_count, void *wincx)
+                    unsigned long *size, unsigned int mech_count, void *wincx)
 {
     PK11SlotList *list = NULL;
     PK11SlotListElement *le ;
     PK11SlotInfo *slot = NULL;
     PRBool freeit = PR_FALSE;
     PRBool listNeedLogin = PR_FALSE;
     int i;
     SECStatus rv;
@@ -2048,17 +2049,18 @@ PK11_GetBestSlotMultipleWithKeySize(CK_M
     if (freeit) { PK11_FreeSlotList(list); }
     if (PORT_GetError() == 0) {
 	PORT_SetError(SEC_ERROR_NO_TOKEN);
     }
     return NULL;
 }
 
 PK11SlotInfo *
-PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int mech_count, void *wincx)
+PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, 
+			 unsigned int mech_count, void *wincx)
 {
     return PK11_GetBestSlotMultipleWithKeySize(type, NULL, mech_count, wincx);
 }
 
 /* original get best slot now calls the multiple version with only one type */
 PK11SlotInfo *
 PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx)
 {
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -26,28 +26,30 @@
  * must not end in a '$' to prevent rcs keyword substitution.
  */
 const char __nss_util_rcsid[] = "$Header: NSS " NSSUTIL_VERSION _DEBUG_STRING
         "  " __DATE__ " " __TIME__ " $";
 const char __nss_util_sccsid[] = "@(#)NSS " NSSUTIL_VERSION _DEBUG_STRING
         "  " __DATE__ " " __TIME__;
 
 /* MISSI Mosaic Object ID space */
+/* USGov algorithm OID space: { 2 16 840 1 101 } */
 #define USGOV                   0x60, 0x86, 0x48, 0x01, 0x65
 #define MISSI	                USGOV, 0x02, 0x01, 0x01
 #define MISSI_OLD_KEA_DSS	MISSI, 0x0c
 #define MISSI_OLD_DSS		MISSI, 0x02
 #define MISSI_KEA_DSS		MISSI, 0x14
 #define MISSI_DSS		MISSI, 0x13
 #define MISSI_KEA               MISSI, 0x0a
 #define MISSI_ALT_KEA           MISSI, 0x16
 
 #define NISTALGS    USGOV, 3, 4
 #define AES         NISTALGS, 1
 #define SHAXXX      NISTALGS, 2
+#define DSA2        NISTALGS, 3
 
 /**
  ** The Netscape OID space is allocated by Terry Hayes.  If you need
  ** a piece of the space, contact him at thayes@netscape.com.
  **/
 
 /* Netscape Communications Corporation Object ID space */
 /* { 2 16 840 1 113730 } */
@@ -76,20 +78,16 @@ const char __nss_util_sccsid[] = "@(#)NS
 #define DIGEST			RSADSI, 0x02
 #define CIPHER			RSADSI, 0x03
 #define PKCS1			PKCS, 0x01
 #define PKCS5			PKCS, 0x05
 #define PKCS7			PKCS, 0x07
 #define PKCS9			PKCS, 0x09
 #define PKCS12			PKCS, 0x0c
 
-/* Fortezza algorithm OID space: { 2 16 840 1 101 2 1 1 } */
-/* ### mwelch -- Is this just for algorithms, or all of Fortezza? */
-#define FORTEZZA_ALG 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01
-
 /* Other OID name spaces */
 #define ALGORITHM		0x2b, 0x0e, 0x03, 0x02
 #define X500			0x55
 #define X520_ATTRIBUTE_TYPE	X500, 0x04
 #define X500_ALG		X500, 0x08
 #define X500_ALG_ENCRYPTION	X500_ALG, 0x01
 
 /** X.509 v3 Extension OID 
@@ -409,16 +407,18 @@ CONST_OID pkcs12V1SafeContentsBag[]     
 
 /* The following encoding is INCORRECT, but correcting it would create a
  * duplicate OID in the table.  So, we will leave it alone.
  */
 CONST_OID pkcs12KeyUsageAttr[]          	= { 2, 5, 29, 15 };
 
 CONST_OID ansix9DSASignature[]               	= { ANSI_X9_ALGORITHM, 0x01 };
 CONST_OID ansix9DSASignaturewithSHA1Digest[] 	= { ANSI_X9_ALGORITHM, 0x03 };
+CONST_OID nistDSASignaturewithSHA224Digest[]	= { DSA2, 0x01 };
+CONST_OID nistDSASignaturewithSHA256Digest[]	= { DSA2, 0x02 };
 
 /* verisign OIDs */
 CONST_OID verisignUserNotices[]     		= { VERISIGN, 1, 7, 1, 1 };
 
 /* pkix OIDs */
 CONST_OID pkixCPSPointerQualifier[] 		= { PKIX_POLICY_QUALIFIERS, 1 };
 CONST_OID pkixUserNoticeQualifier[] 		= { PKIX_POLICY_QUALIFIERS, 2 };
 
@@ -448,17 +448,17 @@ CONST_OID pkixExtendedKeyUsageCodeSign[]
 CONST_OID pkixExtendedKeyUsageEMailProtect[]  	= { PKIX_KEY_USAGE, 4 };
 CONST_OID pkixExtendedKeyUsageTimeStamp[]     	= { PKIX_KEY_USAGE, 8 };
 CONST_OID pkixOCSPResponderExtendedKeyUsage[] 	= { PKIX_KEY_USAGE, 9 };
 
 /* OIDs for Netscape defined algorithms */
 CONST_OID netscapeSMimeKEA[] 			= { NETSCAPE_ALGS, 0x01 };
 
 /* Fortezza algorithm OIDs */
-CONST_OID skipjackCBC[] 			= { FORTEZZA_ALG, 0x04 };
+CONST_OID skipjackCBC[] 			= { MISSI, 0x04 };
 CONST_OID dhPublicKey[] 			= { ANSI_X942_ALGORITHM, 0x1 };
 
 CONST_OID aes128_ECB[] 				= { AES, 1 };
 CONST_OID aes128_CBC[] 				= { AES, 2 };
 #ifdef DEFINE_ALL_AES_CIPHERS
 CONST_OID aes128_OFB[] 				= { AES, 3 };
 CONST_OID aes128_CFB[] 				= { AES, 4 };
 #endif
@@ -1621,16 +1621,24 @@ const static SECOidData oids[SEC_OID_TOT
 	CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
     OD( evIncorporationCountry,  SEC_OID_EV_INCORPORATION_COUNTRY,
         "Jurisdiction of Incorporation Country Name",
 	CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
     OD( x520BusinessCategory,    SEC_OID_BUSINESS_CATEGORY,
         "Business Category",
 	CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
 
+    OD( nistDSASignaturewithSHA224Digest,
+	SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST,
+	"DSA with SHA-224 Signature",
+	CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION),
+    OD( nistDSASignaturewithSHA256Digest,
+	SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST,
+	"DSA with SHA-256 Signature",
+	CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION)
 };
 
 /* PRIVATE EXTENDED SECOID Table
  * This table is private. Its structure is opaque to the outside.
  * It is indexed by the same SECOidTag as the oids table above.
  * Every member of this struct must have accessor functions (set, get)
  * and those functions must operate by value, not by reference.
  * The addresses of the contents of this table must not be exposed 
--- a/security/nss/lib/util/secoidt.h
+++ b/security/nss/lib/util/secoidt.h
@@ -428,16 +428,19 @@ typedef enum {
 
     SEC_OID_SHA224                          = 309,
 
     SEC_OID_EV_INCORPORATION_LOCALITY       = 310,
     SEC_OID_EV_INCORPORATION_STATE          = 311,
     SEC_OID_EV_INCORPORATION_COUNTRY        = 312,
     SEC_OID_BUSINESS_CATEGORY               = 313,
 
+    SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST     = 314,
+    SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST     = 315,
+
     SEC_OID_TOTAL
 } SECOidTag;
 
 #define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
 #define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
 #define SEC_OID_PKCS12_KEY_USAGE  SEC_OID_X509_KEY_USAGE
 
 /* fake OID for DSS sign/verify */