Blame SOURCES/cve-2014-1568-softokn.patch

e47d09
e47d09
# HG changeset patch
e47d09
# User Kai Engert <kaie@kuix.de>
e47d09
# Date 1411493325 -7200
e47d09
# Node ID 4e90910ad2f9741978820ec2314b12a504d78c4e
e47d09
# Parent  ad411fb64046d987272043f311ca477022c6fef4
e47d09
Fix bug	1064636, patch part 3, r=rrelyea
e47d09
e47d09
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
e47d09
--- a/lib/softoken/pkcs11c.c
e47d09
+++ b/lib/softoken/pkcs11c.c
e47d09
@@ -18,16 +18,17 @@
e47d09
  *   that created or generated them.
e47d09
  */
e47d09
 #include "seccomon.h"
e47d09
 #include "secitem.h"
e47d09
 #include "secport.h"
e47d09
 #include "blapi.h"
e47d09
 #include "pkcs11.h"
e47d09
 #include "pkcs11i.h"
e47d09
+#include "pkcs1sig.h"
e47d09
 #include "lowkeyi.h"
e47d09
 #include "secder.h"
e47d09
 #include "secdig.h"
e47d09
 #include "lowpbe.h"	/* We do PBE below */
e47d09
 #include "pkcs11t.h"
e47d09
 #include "secoid.h"
e47d09
 #include "alghmac.h"
e47d09
 #include "softoken.h"
e47d09
@@ -2851,75 +2852,52 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *i
e47d09
         return SECFailure;
e47d09
     }
e47d09
 
e47d09
     return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest,
e47d09
                              digestLen);
e47d09
 }
e47d09
 
e47d09
 SECStatus
e47d09
-RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
e47d09
+RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key,
e47d09
                   const unsigned char *sig, unsigned int sigLen,
e47d09
-                  const unsigned char *hash, unsigned int hashLen)
e47d09
+                  const unsigned char *digestData, unsigned int digestLen)
e47d09
 {
e47d09
-    SECItem it;
e47d09
-    SGNDigestInfo *di = NULL;
e47d09
-    SECStatus rv = SECSuccess;
e47d09
-
e47d09
-    it.data = NULL;
e47d09
-    it.len = nsslowkey_PublicModulusLen(key);
e47d09
-    if (!it.len) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-
e47d09
-    it.data = (unsigned char *)PORT_Alloc(it.len);
e47d09
-    if (it.data == NULL) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-
e47d09
+    unsigned char *pkcs1DigestInfoData;
e47d09
+    SECItem pkcs1DigestInfo;
e47d09
+    SECItem digest;
e47d09
+    unsigned int bufferSize;
e47d09
+    SECStatus rv;
e47d09
+
e47d09
+    /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */
e47d09
+    bufferSize = key->u.rsa.modulus.len;
e47d09
+    pkcs1DigestInfoData = PORT_ZAlloc(bufferSize);
e47d09
+    if (!pkcs1DigestInfoData) {
e47d09
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
e47d09
+        return SECFailure;
e47d09
+    }
e47d09
+
e47d09
+    pkcs1DigestInfo.data = pkcs1DigestInfoData;
e47d09
+    pkcs1DigestInfo.len = bufferSize;
e47d09
+    
e47d09
     /* decrypt the block */
e47d09
-    rv = RSA_CheckSignRecover(&key->u.rsa, it.data, &it.len, it.len, sig,
e47d09
-                              sigLen);
e47d09
+    rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data,
e47d09
+                             &pkcs1DigestInfo.len, pkcs1DigestInfo.len,
e47d09
+                             sig, sigLen);
e47d09
     if (rv != SECSuccess) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-
e47d09
-    di = SGN_DecodeDigestInfo(&it);
e47d09
-    if (di == NULL) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-    if (di->digest.len != hashLen) {
e47d09
-        goto loser; 
e47d09
-    }
e47d09
-
e47d09
-    /* make sure the tag is OK */
e47d09
-    if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-    /* make sure the "parameters" are not too bogus. */
e47d09
-    if (di->digestAlgorithm.parameters.len > 2) {
e47d09
-        goto loser;
e47d09
-    }
e47d09
-    /* Now check the signature */
e47d09
-    if (PORT_Memcmp(hash, di->digest.data, di->digest.len) == 0) {
e47d09
-        goto done;
e47d09
-    }
e47d09
-
e47d09
-  loser:
e47d09
-    PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
e47d09
-    rv = SECFailure;
e47d09
-
e47d09
-  done:
e47d09
-    if (it.data != NULL) {
e47d09
-        PORT_Free(it.data);
e47d09
-    }
e47d09
-    if (di != NULL) {
e47d09
-        SGN_DestroyDigestInfo(di);
e47d09
-    }
e47d09
-
e47d09
+        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
e47d09
+    } else {
e47d09
+        digest.data = (PRUint8*) digestData;
e47d09
+        digest.len = digestLen;
e47d09
+        rv = _SGN_VerifyPKCS1DigestInfo(
e47d09
+                digestOid, &digest, &pkcs1DigestInfo,
e47d09
+                PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
e47d09
+    }
e47d09
+
e47d09
+    PORT_Free(pkcs1DigestInfoData);
e47d09
     return rv;
e47d09
 }
e47d09
 
e47d09
 static SECStatus
e47d09
 sftk_RSACheckSign(NSSLOWKEYPublicKey *key, const unsigned char *sig,
e47d09
                   unsigned int sigLen, const unsigned char *digest,
e47d09
                   unsigned int digestLen)
e47d09
 {
e47d09