summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2003-11-07 03:38:59 +0000
committerrelyea%netscape.com <devnull@localhost>2003-11-07 03:38:59 +0000
commit0343d308c1449482733cb609a085671ca4fa4ffb (patch)
treeaa7dddf73b1bb4c0882dba21a9108b35edb2d20b
parent9a798bb113b53227353dbd47a2542c300cd6abbf (diff)
downloadnss-hg-0343d308c1449482733cb609a085671ca4fa4ffb.tar.gz
Verify Parameters from the user before passing it on to freebl. r=nelson
-rw-r--r--security/nss/lib/softoken/pkcs11.c103
-rw-r--r--security/nss/lib/softoken/pkcs11c.c77
-rw-r--r--security/nss/lib/softoken/pkcs11i.h4
-rw-r--r--security/nss/lib/softoken/pkcs11u.c65
-rw-r--r--security/nss/lib/softoken/rsawrapr.c8
5 files changed, 216 insertions, 41 deletions
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index dde438e47..1b524a62e 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -263,27 +263,42 @@ static const struct mechanismList mechanisms[] = {
*/
/* ------------------------- RSA Operations ---------------------------*/
- {CKM_RSA_PKCS_KEY_PAIR_GEN,{128,CK_MAX,CKF_GENERATE_KEY_PAIR},PR_TRUE},
- {CKM_RSA_PKCS, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
+ {CKM_RSA_PKCS_KEY_PAIR_GEN,{RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_GENERATE_KEY_PAIR},PR_TRUE},
+ {CKM_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_DUZ_IT_ALL}, PR_TRUE},
#ifdef PK11_RSA9796_SUPPORTED
- {CKM_RSA_9796, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
+ {CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_DUZ_IT_ALL}, PR_TRUE},
#endif
- {CKM_RSA_X_509, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
+ {CKM_RSA_X_509, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_DUZ_IT_ALL}, PR_TRUE},
/* -------------- RSA Multipart Signing Operations -------------------- */
- {CKM_MD2_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
- {CKM_SHA1_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
- {CKM_SHA256_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
- {CKM_SHA384_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
- {CKM_SHA512_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
+ {CKM_MD2_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_MD5_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA1_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA256_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA384_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA512_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
+ CKF_SN_VR}, PR_TRUE},
/* ------------------------- DSA Operations --------------------------- */
- {CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DSA, {512, 1024, CKF_SN_VR}, PR_TRUE},
- {CKM_DSA_SHA1, {512, 1024, CKF_SN_VR}, PR_TRUE},
+ {CKM_DSA_KEY_PAIR_GEN, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
+ CKF_GENERATE_KEY_PAIR}, PR_TRUE},
+ {CKM_DSA, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
+ CKF_SN_VR}, PR_TRUE},
+ {CKM_DSA_SHA1, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
+ CKF_SN_VR}, PR_TRUE},
/* -------------------- Diffie Hellman Operations --------------------- */
/* no diffie hellman yet */
- {CKM_DH_PKCS_KEY_PAIR_GEN, {128, 1024, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DH_PKCS_DERIVE, {128, 1024, CKF_DERIVE}, PR_TRUE},
+ {CKM_DH_PKCS_KEY_PAIR_GEN, {DH_MIN_P_BITS, DH_MAX_P_BITS,
+ CKF_GENERATE_KEY_PAIR}, PR_TRUE},
+ {CKM_DH_PKCS_DERIVE, {DH_MIN_P_BITS, DH_MAX_P_BITS,
+ CKF_DERIVE}, PR_TRUE},
#ifdef NSS_ENABLE_ECC
/* -------------------- Elliptic Curve Operations --------------------- */
{CKM_EC_KEY_PAIR_GEN, {112, 571, CKF_GENERATE_KEY_PAIR|CKF_EC_BPNU}, PR_TRUE},
@@ -1025,37 +1040,61 @@ pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
CK_BBOOL derive = CK_FALSE;
CK_BBOOL verify = CK_TRUE;
CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
+ PK11Attribute *attribute;
CK_RV crv;
switch (key_type) {
case CKK_RSA:
- if ( !pk11_hasAttribute(object, CKA_MODULUS)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_MODULUS,
+ RSA_MIN_MODULUS_BITS, 0, 2);
+ if (crv != CKR_OK) {
+ return crv;
}
- if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);
+ if (crv != CKR_OK) {
+ return crv;
}
pubKeyAttr = CKA_MODULUS;
break;
case CKK_DSA:
- if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_SUBPRIME,
+ DSA_Q_BITS, DSA_Q_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
}
- /* fall through */
+ crv = pk11_ConstrainAttribute(object, CKA_PRIME,
+ DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ crv = pk11_ConstrainAttribute(object, CKA_BASE, 1, DSA_MAX_P_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ crv = pk11_ConstrainAttribute(object, CKA_VALUE, 1, DSA_MAX_P_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ encrypt = CK_FALSE;
+ recover = CK_FALSE;
+ wrap = CK_FALSE;
+ break;
case CKK_DH:
- if ( !pk11_hasAttribute(object, CKA_PRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_PRIME,
+ DH_MIN_P_BITS, DH_MAX_P_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
}
- if ( !pk11_hasAttribute(object, CKA_BASE)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_BASE, 1, DH_MAX_P_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
}
- if ( !pk11_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = pk11_ConstrainAttribute(object, CKA_VALUE, 1, DH_MAX_P_BITS, 0);
+ if (crv != CKR_OK) {
+ return crv;
}
- if (key_type == CKK_DH) {
- verify = CK_FALSE;
- derive = CK_TRUE;
- }
+ verify = CK_FALSE;
+ derive = CK_TRUE;
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 5cf49f4bd..945b1e868 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -2946,7 +2946,6 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
-
/* NSC_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects. */
CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
@@ -2965,6 +2964,7 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
int i;
PK11Slot * slot = pk11_SlotFromSessionHandle(hSession);
+ unsigned int bitSize;
/* RSA */
int public_modulus_bits = 0;
@@ -3064,10 +3064,23 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
crv = CKR_TEMPLATE_INCOMPLETE;
break;
}
+ if (public_modulus_bits < RSA_MIN_MODULUS_BITS) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ break;
+ }
+ if (public_modulus_bits % 2 != 0) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ break;
+ }
/* extract the exponent */
crv=pk11_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT);
if (crv != CKR_OK) break;
+ bitSize = pk11_GetLengthInBits(pubExp.data, pubExp.len);
+ if (bitSize < 2) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ break;
+ }
crv = pk11_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
pk11_item_expand(&pubExp));
if (crv != CKR_OK) {
@@ -3161,6 +3174,32 @@ kpg_done:
break;
}
+ bitSize = pk11_GetLengthInBits(pqgParam.subPrime.data,
+ pqgParam.subPrime.len);
+ if (bitSize != DSA_Q_BITS) {
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ PORT_Free(pqgParam.prime.data);
+ PORT_Free(pqgParam.subPrime.data);
+ PORT_Free(pqgParam.base.data);
+ break;
+ }
+ bitSize = pk11_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len);
+ if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) {
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ PORT_Free(pqgParam.prime.data);
+ PORT_Free(pqgParam.subPrime.data);
+ PORT_Free(pqgParam.base.data);
+ break;
+ }
+ bitSize = pk11_GetLengthInBits(pqgParam.base.data,pqgParam.base.len);
+ if ((bitSize < 1) || (bitSize > DSA_MAX_P_BITS)) {
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ PORT_Free(pqgParam.prime.data);
+ PORT_Free(pqgParam.subPrime.data);
+ PORT_Free(pqgParam.base.data);
+ break;
+ }
+
/* Generate the key */
rv = DSA_NewKey(&pqgParam, &dsaPriv);
@@ -3200,26 +3239,46 @@ dsagn_done:
if (crv != CKR_OK) break;
crv = pk11_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- break;
+ PORT_Free(dhParam.prime.data);
+ break;
}
crv = pk11_AddAttributeType(privateKey, CKA_PRIME,
pk11_item_expand(&dhParam.prime));
if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
+ PORT_Free(dhParam.prime.data);
+ PORT_Free(dhParam.base.data);
+ break;
}
crv = pk11_AddAttributeType(privateKey, CKA_BASE,
pk11_item_expand(&dhParam.base));
- if (crv != CKR_OK) goto dhgn_done;
+ if (crv != CKR_OK) {
+ PORT_Free(dhParam.prime.data);
+ PORT_Free(dhParam.base.data);
+ break;
+ }
+ bitSize = pk11_GetLengthInBits(dhParam.prime.data,dhParam.prime.len);
+ if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) {
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ PORT_Free(pqgParam.prime.data);
+ PORT_Free(pqgParam.subPrime.data);
+ PORT_Free(pqgParam.base.data);
+ break;
+ }
+ bitSize = pk11_GetLengthInBits(dhParam.base.data,dhParam.base.len);
+ if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) {
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ PORT_Free(pqgParam.prime.data);
+ PORT_Free(pqgParam.subPrime.data);
+ PORT_Free(pqgParam.base.data);
+ break;
+ }
rv = DH_NewKey(&dhParam, &dhPriv);
PORT_Free(dhParam.prime.data);
PORT_Free(dhParam.base.data);
if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- break;
+ crv = CKR_DEVICE_ERROR;
+ break;
}
crv=pk11_AddAttributeType(publicKey, CKA_VALUE,
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index fa7b17bce..27375b679 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -582,6 +582,10 @@ extern CK_RV pk11_AddAttributeType(PK11Object *object, CK_ATTRIBUTE_TYPE type,
CK_ULONG length);
extern CK_RV pk11_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
PK11Object *object, CK_ATTRIBUTE_TYPE type);
+extern unsigned int pk11_GetLengthInBits(unsigned char *buf,
+ unsigned int bufLen);
+extern CK_RV pk11_ConstrainAttribute(PK11Object *object,
+ CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple);
extern PRBool pk11_hasAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type);
extern PRBool pk11_isTrue(PK11Object *object, CK_ATTRIBUTE_TYPE type);
extern void pk11_DeleteAttributeType(PK11Object *object,
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index f2447d6cf..16f5c282a 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -1256,7 +1256,72 @@ pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
return(attribute);
}
+/*
+ * Take a buffer and it's length and return it's true size in bits;
+ */
+unsigned int
+pk11_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
+{
+ unsigned int size = bufLen * 8;
+ int i;
+ /* Get the real length in bytes */
+ for (i=0; i < bufLen; i++) {
+ unsigned char c = *buf++;
+ if (c != 0) {
+ unsigned char m;
+ for (m=0x80; m > 0 ; m = m >> 1) {
+ if ((c & m) != 0) {
+ break;
+ }
+ size--;
+ }
+ break;
+ }
+ size-=8;
+ }
+ return size;
+}
+
+/*
+ * Constrain a big num attribute. to size and padding
+ * minLength means length of the object must be greater than equal to minLength
+ * maxLength means length of the object must be less than equal to maxLength
+ * minMultiple means that object length mod minMultiple must equal 0.
+ * all input sizes are in bits.
+ * if any constraint is '0' that constraint is not checked.
+ */
+CK_RV
+pk11_ConstrainAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
+ int minLength, int maxLength, int minMultiple)
+{
+ PK11Attribute *attribute;
+ unsigned int size;
+ unsigned char *ptr;
+ int i,j;
+ attribute = pk11_FindAttribute(object, type);
+ if (!attribute) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ ptr = (unsigned char *) attribute->attrib.pValue;
+ if (ptr == NULL) {
+ pk11_FreeAttribute(attribute);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ size = pk11_GetLengthInBits(ptr, attribute->attrib.ulValueLen);
+ pk11_FreeAttribute(attribute);
+
+ if ((minLength != 0) && (size < minLength)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ if ((maxLength != 0) && (size > maxLength)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ if ((minMultiple != 0) && ((size % minMultiple) != 0)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ return CKR_OK;
+}
PRBool
pk11_hasAttributeToken(PK11TokenObject *object)
diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c
index b17d4fc8e..53bbfc35d 100644
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -218,6 +218,10 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
*/
padLen = modulusLen - data->len - 3;
PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
+ if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
+ PORT_Free (block);
+ return NULL;
+ }
PORT_Memset (bp,
blockType == RSA_BlockPrivate0
? RSA_BLOCK_PRIVATE0_PAD_OCTET
@@ -240,6 +244,10 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
*/
padLen = modulusLen - data->len - 3;
PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
+ if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
+ PORT_Free (block);
+ return NULL;
+ }
for (i = 0; i < padLen; i++) {
/* Pad with non-zero random data. */
do {