diff options
author | relyea%netscape.com <devnull@localhost> | 2003-11-07 03:38:59 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2003-11-07 03:38:59 +0000 |
commit | 0343d308c1449482733cb609a085671ca4fa4ffb (patch) | |
tree | aa7dddf73b1bb4c0882dba21a9108b35edb2d20b | |
parent | 9a798bb113b53227353dbd47a2542c300cd6abbf (diff) | |
download | nss-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.c | 103 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11c.c | 77 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11i.h | 4 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11u.c | 65 | ||||
-rw-r--r-- | security/nss/lib/softoken/rsawrapr.c | 8 |
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 { |