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 |