| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 #include "cryptohi.h" | 4 #include "cryptohi.h" |
| 5 #include "keyhi.h" | 5 #include "keyhi.h" |
| 6 #include "secoid.h" | 6 #include "secoid.h" |
| 7 #include "secitem.h" | 7 #include "secitem.h" |
| 8 #include "secder.h" | 8 #include "secder.h" |
| 9 #include "base64.h" | 9 #include "base64.h" |
| 10 #include "secasn1.h" | 10 #include "secasn1.h" |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 ** to create this key pair without the "sensitive" attribute, but revert to | 171 ** to create this key pair without the "sensitive" attribute, but revert to |
| 172 ** creating a "sensitive" key if necessary. | 172 ** creating a "sensitive" key if necessary. |
| 173 */ | 173 */ |
| 174 SECKEYPrivateKey * | 174 SECKEYPrivateKey * |
| 175 SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
x) | 175 SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
x) |
| 176 { | 176 { |
| 177 SECKEYPrivateKey *privk; | 177 SECKEYPrivateKey *privk; |
| 178 PK11SlotInfo *slot; | 178 PK11SlotInfo *slot; |
| 179 | 179 |
| 180 if (!param || !param->base.data || !param->prime.data || | 180 if (!param || !param->base.data || !param->prime.data || |
| 181 param->prime.len < 512/8 || param->base.len == 0 || | 181 SECKEY_BigIntegerBitLength(¶m->prime) < DH_MIN_P_BITS || |
| 182 param->base.len > param->prime.len + 1 || | 182 param->base.len == 0 || param->base.len > param->prime.len + 1 || |
| 183 (param->base.len == 1 && param->base.data[0] == 0)) { | 183 (param->base.len == 1 && param->base.data[0] == 0)) { |
| 184 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 184 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 185 return NULL; | 185 return NULL; |
| 186 } | 186 } |
| 187 | 187 |
| 188 slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx); | 188 slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx); |
| 189 if (!slot) { | 189 if (!slot) { |
| 190 return NULL; | 190 return NULL; |
| 191 } | 191 } |
| 192 | 192 |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 case SEC_OID_SECG_EC_SECT571K1: | 934 case SEC_OID_SECG_EC_SECT571K1: |
| 935 case SEC_OID_SECG_EC_SECT571R1: | 935 case SEC_OID_SECG_EC_SECT571R1: |
| 936 return 570; | 936 return 570; |
| 937 | 937 |
| 938 default: | 938 default: |
| 939 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); | 939 PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); |
| 940 return 0; | 940 return 0; |
| 941 } | 941 } |
| 942 } | 942 } |
| 943 | 943 |
| 944 /* The number of bits in the number from the first non-zero bit onward. */ |
| 945 unsigned |
| 946 SECKEY_BigIntegerBitLength(const SECItem *number) |
| 947 { |
| 948 const unsigned char *p; |
| 949 unsigned octets; |
| 950 unsigned bits; |
| 951 |
| 952 if (!number || !number->data) { |
| 953 PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 954 return 0; |
| 955 } |
| 956 |
| 957 p = number->data; |
| 958 octets = number->len; |
| 959 while (octets > 0 && !*p) { |
| 960 ++p; |
| 961 --octets; |
| 962 } |
| 963 if (octets == 0) { |
| 964 return 0; |
| 965 } |
| 966 /* bits = 7..1 because we know at least one bit is set already */ |
| 967 /* Note: This could do a binary search, but this is faster for keys if we |
| 968 * assume that good keys will have the MSB set. */ |
| 969 for (bits = 7; bits > 0; --bits) { |
| 970 if (*p & (1 << bits)) { |
| 971 break; |
| 972 } |
| 973 } |
| 974 return octets * 8 + bits - 7; |
| 975 } |
| 976 |
| 944 /* returns key strength in bytes (not bits) */ | 977 /* returns key strength in bytes (not bits) */ |
| 945 unsigned | 978 unsigned |
| 946 SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk) | 979 SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk) |
| 947 { | 980 { |
| 948 unsigned char b0; | 981 return (SECKEY_PublicKeyStrengthInBits(pubk) + 7) / 8; |
| 949 unsigned size; | |
| 950 | |
| 951 /* interpret modulus length as key strength */ | |
| 952 if (!pubk) | |
| 953 » goto loser; | |
| 954 switch (pubk->keyType) { | |
| 955 case rsaKey: | |
| 956 » if (!pubk->u.rsa.modulus.data) break; | |
| 957 » b0 = pubk->u.rsa.modulus.data[0]; | |
| 958 » return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; | |
| 959 case dsaKey: | |
| 960 » if (!pubk->u.dsa.publicValue.data) break; | |
| 961 » b0 = pubk->u.dsa.publicValue.data[0]; | |
| 962 » return b0 ? pubk->u.dsa.publicValue.len : | |
| 963 » pubk->u.dsa.publicValue.len - 1; | |
| 964 case dhKey: | |
| 965 » if (!pubk->u.dh.publicValue.data) break; | |
| 966 » b0 = pubk->u.dh.publicValue.data[0]; | |
| 967 » return b0 ? pubk->u.dh.publicValue.len : | |
| 968 » pubk->u.dh.publicValue.len - 1; | |
| 969 case ecKey: | |
| 970 » /* Get the key size in bits and adjust */ | |
| 971 » size =» SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams); | |
| 972 » return (size + 7)/8; | |
| 973 default: | |
| 974 » break; | |
| 975 } | |
| 976 loser: | |
| 977 PORT_SetError(SEC_ERROR_INVALID_KEY); | |
| 978 return 0; | |
| 979 } | 982 } |
| 980 | 983 |
| 981 /* returns key strength in bits */ | 984 /* returns key strength in bits */ |
| 982 unsigned | 985 unsigned |
| 983 SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk) | 986 SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk) |
| 984 { | 987 { |
| 985 unsigned size; | 988 unsigned bitSize = 0; |
| 989 |
| 990 if (!pubk) { |
| 991 PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 992 return 0; |
| 993 } |
| 994 |
| 995 /* interpret modulus length as key strength */ |
| 986 switch (pubk->keyType) { | 996 switch (pubk->keyType) { |
| 987 case rsaKey: | 997 case rsaKey: |
| 998 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus); |
| 999 break; |
| 988 case dsaKey: | 1000 case dsaKey: |
| 1001 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.publicValue); |
| 1002 break; |
| 989 case dhKey: | 1003 case dhKey: |
| 990 » return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */ | 1004 bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.publicValue); |
| 1005 break; |
| 991 case ecKey: | 1006 case ecKey: |
| 992 » size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams); | 1007 bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams); |
| 993 » return size; | 1008 break; |
| 994 default: | 1009 default: |
| 995 » break; | 1010 PORT_SetError(SEC_ERROR_INVALID_KEY); |
| 1011 break; |
| 996 } | 1012 } |
| 997 PORT_SetError(SEC_ERROR_INVALID_KEY); | 1013 return bitSize; |
| 998 return 0; | |
| 999 } | 1014 } |
| 1000 | 1015 |
| 1001 /* returns signature length in bytes (not bits) */ | 1016 /* returns signature length in bytes (not bits) */ |
| 1002 unsigned | 1017 unsigned |
| 1003 SECKEY_SignatureLen(const SECKEYPublicKey *pubk) | 1018 SECKEY_SignatureLen(const SECKEYPublicKey *pubk) |
| 1004 { | 1019 { |
| 1005 unsigned char b0; | 1020 unsigned char b0; |
| 1006 unsigned size; | 1021 unsigned size; |
| 1007 | 1022 |
| 1008 switch (pubk->keyType) { | 1023 switch (pubk->keyType) { |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1543 { | 1558 { |
| 1544 PLArenaPool *poolp; | 1559 PLArenaPool *poolp; |
| 1545 | 1560 |
| 1546 if(pvk != NULL) { | 1561 if(pvk != NULL) { |
| 1547 if(pvk->arena) { | 1562 if(pvk->arena) { |
| 1548 poolp = pvk->arena; | 1563 poolp = pvk->arena; |
| 1549 /* zero structure since PORT_FreeArena does not support | 1564 /* zero structure since PORT_FreeArena does not support |
| 1550 * this yet. | 1565 * this yet. |
| 1551 */ | 1566 */ |
| 1552 PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len); | 1567 PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len); |
| 1553 » PORT_Memset((char *)pvk, 0, sizeof(*pvk)); | 1568 » PORT_Memset(pvk, 0, sizeof(*pvk)); |
| 1554 if(freeit == PR_TRUE) { | 1569 if(freeit == PR_TRUE) { |
| 1555 PORT_FreeArena(poolp, PR_TRUE); | 1570 PORT_FreeArena(poolp, PR_TRUE); |
| 1556 } else { | 1571 } else { |
| 1557 pvk->arena = poolp; | 1572 pvk->arena = poolp; |
| 1558 } | 1573 } |
| 1559 } else { | 1574 } else { |
| 1560 SECITEM_ZfreeItem(&pvk->version, PR_FALSE); | 1575 SECITEM_ZfreeItem(&pvk->version, PR_FALSE); |
| 1561 SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE); | 1576 SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE); |
| 1562 SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE); | 1577 SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE); |
| 1563 » PORT_Memset((char *)pvk, 0, sizeof(*pvk)); | 1578 » PORT_Memset(pvk, 0, sizeof(*pvk)); |
| 1564 if(freeit == PR_TRUE) { | 1579 if(freeit == PR_TRUE) { |
| 1565 PORT_Free(pvk); | 1580 PORT_Free(pvk); |
| 1566 } | 1581 } |
| 1567 } | 1582 } |
| 1568 } | 1583 } |
| 1569 } | 1584 } |
| 1570 | 1585 |
| 1571 void | 1586 void |
| 1572 SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki, | 1587 SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki, |
| 1573 PRBool freeit) | 1588 PRBool freeit) |
| 1574 { | 1589 { |
| 1575 PLArenaPool *poolp; | 1590 PLArenaPool *poolp; |
| 1576 | 1591 |
| 1577 if(epki != NULL) { | 1592 if(epki != NULL) { |
| 1578 if(epki->arena) { | 1593 if(epki->arena) { |
| 1579 poolp = epki->arena; | 1594 poolp = epki->arena; |
| 1580 /* zero structure since PORT_FreeArena does not support | 1595 /* zero structure since PORT_FreeArena does not support |
| 1581 * this yet. | 1596 * this yet. |
| 1582 */ | 1597 */ |
| 1583 PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len); | 1598 PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len); |
| 1584 » PORT_Memset((char *)epki, 0, sizeof(*epki)); | 1599 » PORT_Memset(epki, 0, sizeof(*epki)); |
| 1585 if(freeit == PR_TRUE) { | 1600 if(freeit == PR_TRUE) { |
| 1586 PORT_FreeArena(poolp, PR_TRUE); | 1601 PORT_FreeArena(poolp, PR_TRUE); |
| 1587 } else { | 1602 } else { |
| 1588 epki->arena = poolp; | 1603 epki->arena = poolp; |
| 1589 } | 1604 } |
| 1590 } else { | 1605 } else { |
| 1591 SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE); | 1606 SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE); |
| 1592 SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE); | 1607 SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE); |
| 1593 » PORT_Memset((char *)epki, 0, sizeof(*epki)); | 1608 » PORT_Memset(epki, 0, sizeof(*epki)); |
| 1594 if(freeit == PR_TRUE) { | 1609 if(freeit == PR_TRUE) { |
| 1595 PORT_Free(epki); | 1610 PORT_Free(epki); |
| 1596 } | 1611 } |
| 1597 } | 1612 } |
| 1598 } | 1613 } |
| 1599 } | 1614 } |
| 1600 | 1615 |
| 1601 SECStatus | 1616 SECStatus |
| 1602 SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp, | 1617 SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp, |
| 1603 SECKEYPrivateKeyInfo *to, | 1618 SECKEYPrivateKeyInfo *to, |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 { | 1897 { |
| 1883 SECStatus rv = SECFailure; | 1898 SECStatus rv = SECFailure; |
| 1884 if (key && key->pkcs11Slot && key->pkcs11ID) { | 1899 if (key && key->pkcs11Slot && key->pkcs11ID) { |
| 1885 key->staticflags |= SECKEY_Attributes_Cached; | 1900 key->staticflags |= SECKEY_Attributes_Cached; |
| 1886 SECKEY_CacheAttribute(key, CKA_PRIVATE); | 1901 SECKEY_CacheAttribute(key, CKA_PRIVATE); |
| 1887 SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE); | 1902 SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE); |
| 1888 rv = SECSuccess; | 1903 rv = SECSuccess; |
| 1889 } | 1904 } |
| 1890 return rv; | 1905 return rv; |
| 1891 } | 1906 } |
| 1907 |
| 1908 SECOidTag |
| 1909 SECKEY_GetECCOid(const SECKEYECParams * params) |
| 1910 { |
| 1911 SECItem oid = { siBuffer, NULL, 0}; |
| 1912 SECOidData *oidData = NULL; |
| 1913 |
| 1914 /* |
| 1915 * params->data needs to contain the ASN encoding of an object ID (OID) |
| 1916 * representing a named curve. Here, we strip away everything |
| 1917 * before the actual OID and use the OID to look up a named curve. |
| 1918 */ |
| 1919 if (params->data[0] != SEC_ASN1_OBJECT_ID) return 0; |
| 1920 oid.len = params->len - 2; |
| 1921 oid.data = params->data + 2; |
| 1922 if ((oidData = SECOID_FindOID(&oid)) == NULL) return 0; |
| 1923 |
| 1924 return oidData->offset; |
| 1925 } |
| OLD | NEW |