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 | 4 |
5 #include "plarena.h" | 5 #include "plarena.h" |
6 | 6 |
7 #include "seccomon.h" | 7 #include "seccomon.h" |
8 #include "secitem.h" | 8 #include "secitem.h" |
9 #include "secport.h" | 9 #include "secport.h" |
10 #include "hasht.h" | 10 #include "hasht.h" |
11 #include "pkcs11t.h" | 11 #include "pkcs11t.h" |
12 #include "sechash.h" | 12 #include "sechash.h" |
13 #include "secasn1.h" | 13 #include "secasn1.h" |
14 #include "secder.h" | 14 #include "secder.h" |
15 #include "secoid.h" | 15 #include "secoid.h" |
16 #include "secerr.h" | 16 #include "secerr.h" |
17 #include "secmod.h" | 17 #include "secmod.h" |
18 #include "pk11func.h" | 18 #include "pk11func.h" |
19 #include "secpkcs5.h" | 19 #include "secpkcs5.h" |
20 #include "secmodi.h" | 20 #include "secmodi.h" |
21 #include "secmodti.h" | 21 #include "secmodti.h" |
22 #include "pkcs11.h" | 22 #include "pkcs11.h" |
23 #include "pk11func.h" | 23 #include "pk11func.h" |
24 #include "secitem.h" | 24 #include "secitem.h" |
25 #include "key.h" | 25 #include "key.h" |
26 | 26 |
27 typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter; | 27 typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter; |
28 struct SEC_PKCS5PBEParameterStr { | 28 struct SEC_PKCS5PBEParameterStr { |
29 PLArenaPool *poolp; | 29 PLArenaPool *poolp; |
30 SECItem salt; /* octet string */ | 30 SECItem salt; /* octet string */ |
31 SECItem iteration; /* integer */ | 31 SECItem iteration; /* integer */ |
32 SECItem keyLength;» /* PKCS5v2 only */ | 32 SECItem keyLength; /* PKCS5v2 only */ |
33 SECAlgorithmID *pPrfAlgId;»/* PKCS5v2 only */ | 33 SECAlgorithmID *pPrfAlgId; /* PKCS5v2 only */ |
34 SECAlgorithmID prfAlgId;» /* PKCS5v2 only */ | 34 SECAlgorithmID prfAlgId; /* PKCS5v2 only */ |
35 }; | 35 }; |
36 | 36 |
37 /* PKCS5 V2 has an algorithm ID for the encryption and for | 37 /* PKCS5 V2 has an algorithm ID for the encryption and for |
38 * the key generation. This is valid for SEC_OID_PKCS5_PBES2 | 38 * the key generation. This is valid for SEC_OID_PKCS5_PBES2 |
39 * and SEC_OID_PKCS5_PBMAC1 | 39 * and SEC_OID_PKCS5_PBMAC1 |
40 */ | 40 */ |
41 struct sec_pkcs5V2ParameterStr { | 41 struct sec_pkcs5V2ParameterStr { |
42 PLArenaPool *poolp; | 42 PLArenaPool *poolp; |
43 SECAlgorithmID pbeAlgId; /* real pbe algorithms */ | 43 SECAlgorithmID pbeAlgId; /* real pbe algorithms */ |
44 SECAlgorithmID cipherAlgId; /* encryption/mac */ | 44 SECAlgorithmID cipherAlgId; /* encryption/mac */ |
45 }; | 45 }; |
46 | 46 |
47 typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter; | 47 typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter; |
48 | 48 |
49 | |
50 /* template for PKCS 5 PBE Parameter. This template has been expanded | 49 /* template for PKCS 5 PBE Parameter. This template has been expanded |
51 * based upon the additions in PKCS 12. This should eventually be moved | 50 * based upon the additions in PKCS 12. This should eventually be moved |
52 * if RSA updates PKCS 5. | 51 * if RSA updates PKCS 5. |
53 */ | 52 */ |
54 const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] = | 53 const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] = { |
55 { | 54 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter)}, |
56 { SEC_ASN1_SEQUENCE, | 55 {SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt)}, |
57 » 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, | 56 {SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration)}, |
58 { SEC_ASN1_OCTET_STRING, | 57 {0}}; |
59 » offsetof(SEC_PKCS5PBEParameter, salt) }, | 58 |
60 { SEC_ASN1_INTEGER, | 59 const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] = { |
61 » offsetof(SEC_PKCS5PBEParameter, iteration) }, | 60 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter)}, |
62 { 0 } | 61 {SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt)}, |
63 }; | 62 {SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration)}, |
64 | 63 {0}}; |
65 const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] = | |
66 {··· | |
67 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, | |
68 { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) }, | |
69 { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) }, | |
70 { 0 } | |
71 }; | |
72 | 64 |
73 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | 65 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) |
74 | 66 |
75 /* SECOID_PKCS5_PBKDF2 */ | 67 /* SECOID_PKCS5_PBKDF2 */ |
76 const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] = | 68 const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] = { |
77 { | 69 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter)}, |
78 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, | |
79 /* This is really a choice, but since we only understand this | 70 /* This is really a choice, but since we only understand this |
80 * choice, just inline it */ | 71 * choice, just inline it */ |
81 { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) }, | 72 {SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt)}, |
82 { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) }, | 73 {SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration)}, |
83 { SEC_ASN1_INTEGER|SEC_ASN1_OPTIONAL, | 74 {SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, |
84 » » offsetof(SEC_PKCS5PBEParameter, keyLength) }, | 75 offsetof(SEC_PKCS5PBEParameter, keyLength)}, |
85 { SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL,· | 76 {SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL, |
86 » offsetof(SEC_PKCS5PBEParameter, pPrfAlgId), | 77 offsetof(SEC_PKCS5PBEParameter, pPrfAlgId), |
87 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | 78 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)}, |
88 { 0 } | 79 {0}}; |
89 }; | |
90 | 80 |
91 /* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */ | 81 /* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */ |
92 const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] = | 82 const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] = { |
93 { | 83 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter)}, |
94 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, | 84 {SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId), |
95 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId), | 85 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)}, |
96 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | 86 {SEC_ASN1_INLINE | SEC_ASN1_XTRN, |
97 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | 87 offsetof(sec_pkcs5V2Parameter, cipherAlgId), |
98 » offsetof(sec_pkcs5V2Parameter, cipherAlgId), | 88 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)}, |
99 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | 89 {0}}; |
100 { 0 } | |
101 }; | |
102 | |
103 | 90 |
104 /* | 91 /* |
105 * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1 | 92 * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1 |
106 * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2. | 93 * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2. |
107 */ | 94 */ |
108 SECOidTag | 95 SECOidTag sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm) { |
109 sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm) | 96 switch (algorithm) { |
110 { | 97 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: |
111 switch(algorithm) | 98 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: |
112 { | 99 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: |
113 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: | 100 return SEC_OID_DES_EDE3_CBC; |
114 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: | 101 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: |
115 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: | 102 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: |
116 » return SEC_OID_DES_EDE3_CBC; | 103 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: |
117 » case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: | 104 return SEC_OID_DES_CBC; |
118 » case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: | 105 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: |
119 » case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: | 106 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: |
120 » return SEC_OID_DES_CBC; | 107 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: |
121 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: | 108 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: |
122 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: | 109 return SEC_OID_RC2_CBC; |
123 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: | 110 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: |
124 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: | 111 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: |
125 » return SEC_OID_RC2_CBC; | 112 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: |
126 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: | 113 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: |
127 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: | 114 return SEC_OID_RC4; |
128 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: | 115 case SEC_OID_PKCS5_PBKDF2: |
129 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: | 116 case SEC_OID_PKCS5_PBES2: |
130 » return SEC_OID_RC4; | 117 case SEC_OID_PKCS5_PBMAC1: |
131 » case SEC_OID_PKCS5_PBKDF2: | 118 return SEC_OID_PKCS5_PBKDF2; |
132 » case SEC_OID_PKCS5_PBES2: | 119 default: |
133 » case SEC_OID_PKCS5_PBMAC1: | 120 break; |
134 » return SEC_OID_PKCS5_PBKDF2; | 121 } |
135 » default: | 122 |
136 » break; | 123 return SEC_OID_UNKNOWN; |
137 } | |
138 | |
139 return SEC_OID_UNKNOWN; | |
140 } | 124 } |
141 | 125 |
142 /* | 126 /* |
143 * get a new PKCS5 V2 Parameter from the algorithm id. | 127 * get a new PKCS5 V2 Parameter from the algorithm id. |
144 * if arena is passed in, use it, otherwise create a new arena. | 128 * if arena is passed in, use it, otherwise create a new arena. |
145 */ | 129 */ |
146 sec_pkcs5V2Parameter * | 130 sec_pkcs5V2Parameter *sec_pkcs5_v2_get_v2_param(PLArenaPool *arena, |
147 sec_pkcs5_v2_get_v2_param(PLArenaPool *arena, SECAlgorithmID *algid) | 131 SECAlgorithmID *algid) { |
148 { | 132 PLArenaPool *localArena = NULL; |
149 PLArenaPool *localArena = NULL; | 133 sec_pkcs5V2Parameter *pbeV2_param; |
| 134 SECStatus rv; |
| 135 |
| 136 if (arena == NULL) { |
| 137 localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); |
| 138 if (arena == NULL) { |
| 139 return NULL; |
| 140 } |
| 141 } |
| 142 pbeV2_param = PORT_ArenaZNew(arena, sec_pkcs5V2Parameter); |
| 143 if (pbeV2_param == NULL) { |
| 144 goto loser; |
| 145 } |
| 146 |
| 147 rv = SEC_ASN1DecodeItem(arena, pbeV2_param, SEC_PKCS5V2ParameterTemplate, |
| 148 &algid->parameters); |
| 149 if (rv == SECFailure) { |
| 150 goto loser; |
| 151 } |
| 152 |
| 153 pbeV2_param->poolp = arena; |
| 154 return pbeV2_param; |
| 155 loser: |
| 156 if (localArena) { |
| 157 PORT_FreeArena(arena, PR_FALSE); |
| 158 } |
| 159 return NULL; |
| 160 } |
| 161 |
| 162 void sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param) { |
| 163 if (param && param->poolp) { |
| 164 PORT_FreeArena(param->poolp, PR_TRUE); |
| 165 } |
| 166 } |
| 167 |
| 168 /* maps crypto algorithm from PBE algorithm. |
| 169 */ |
| 170 SECOidTag SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid) { |
| 171 |
| 172 SECOidTag pbeAlg; |
| 173 SECOidTag cipherAlg; |
| 174 |
| 175 if (algid == NULL) return SEC_OID_UNKNOWN; |
| 176 |
| 177 pbeAlg = SECOID_GetAlgorithmTag(algid); |
| 178 cipherAlg = sec_pkcs5GetCryptoFromAlgTag(pbeAlg); |
| 179 if ((cipherAlg == SEC_OID_PKCS5_PBKDF2) && (pbeAlg != SEC_OID_PKCS5_PBKDF2)) { |
150 sec_pkcs5V2Parameter *pbeV2_param; | 180 sec_pkcs5V2Parameter *pbeV2_param; |
151 SECStatus rv; | 181 cipherAlg = SEC_OID_UNKNOWN; |
152 | 182 |
153 if (arena == NULL) { | 183 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); |
154 » localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | 184 if (pbeV2_param != NULL) { |
155 » if (arena == NULL) { | 185 cipherAlg = SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId); |
156 » return NULL; | 186 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); |
157 » } | 187 } |
158 } | 188 } |
159 pbeV2_param = PORT_ArenaZNew(arena, sec_pkcs5V2Parameter); | 189 |
160 if (pbeV2_param == NULL) { | 190 return cipherAlg; |
161 » goto loser; | |
162 } | |
163 »······· | |
164 rv = SEC_ASN1DecodeItem(arena, pbeV2_param, | |
165 » » SEC_PKCS5V2ParameterTemplate, &algid->parameters); | |
166 if (rv == SECFailure) { | |
167 » goto loser; | |
168 } | |
169 | |
170 pbeV2_param->poolp = arena; | |
171 return pbeV2_param; | |
172 loser: | |
173 if (localArena) { | |
174 » PORT_FreeArena(arena, PR_FALSE); | |
175 } | |
176 return NULL; | |
177 } | |
178 | |
179 void | |
180 sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param) | |
181 { | |
182 if (param && param->poolp) { | |
183 » PORT_FreeArena(param->poolp, PR_TRUE); | |
184 } | |
185 } | |
186 »······· | |
187 | |
188 /* maps crypto algorithm from PBE algorithm. | |
189 */ | |
190 SECOidTag· | |
191 SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid) | |
192 { | |
193 | |
194 SECOidTag pbeAlg; | |
195 SECOidTag cipherAlg; | |
196 | |
197 if(algid == NULL) | |
198 » return SEC_OID_UNKNOWN; | |
199 | |
200 pbeAlg = SECOID_GetAlgorithmTag(algid); | |
201 cipherAlg = sec_pkcs5GetCryptoFromAlgTag(pbeAlg); | |
202 if ((cipherAlg == SEC_OID_PKCS5_PBKDF2) && | |
203 » (pbeAlg != SEC_OID_PKCS5_PBKDF2)) { | |
204 » sec_pkcs5V2Parameter *pbeV2_param; | |
205 » cipherAlg = SEC_OID_UNKNOWN; | |
206 | |
207 » pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); | |
208 » if (pbeV2_param != NULL) { | |
209 » cipherAlg = SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId); | |
210 » sec_pkcs5_v2_destroy_v2_param(pbeV2_param); | |
211 » } | |
212 } | |
213 | |
214 return cipherAlg; | |
215 } | 191 } |
216 | 192 |
217 /* check to see if an oid is a pbe algorithm | 193 /* check to see if an oid is a pbe algorithm |
218 */ | 194 */ |
219 PRBool | 195 PRBool SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid) { |
220 SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid) | 196 return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN); |
221 { | 197 } |
222 return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN); | 198 |
223 } | 199 PRBool SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag) { |
224 | 200 return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN); |
225 PRBool | |
226 SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag) | |
227 { | |
228 return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN); | |
229 } | 201 } |
230 | 202 |
231 /* | 203 /* |
232 * find the most appropriate PKCS5v2 overall oid tag from a regular | 204 * find the most appropriate PKCS5v2 overall oid tag from a regular |
233 * cipher/hash algorithm tag. | 205 * cipher/hash algorithm tag. |
234 */ | 206 */ |
235 static SECOidTag | 207 static SECOidTag sec_pkcs5v2_get_pbe(SECOidTag algTag) { |
236 sec_pkcs5v2_get_pbe(SECOidTag algTag) | 208 /* if it's a valid hash oid... */ |
237 { | 209 if (HASH_GetHashOidTagByHMACOidTag(algTag) != SEC_OID_UNKNOWN) { |
238 /* if it's a valid hash oid... */ | 210 /* use the MAC tag */ |
239 if (HASH_GetHashOidTagByHMACOidTag(algTag) != SEC_OID_UNKNOWN) { | 211 return SEC_OID_PKCS5_PBMAC1; |
240 » /* use the MAC tag */ | 212 } |
241 » return SEC_OID_PKCS5_PBMAC1; | 213 if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) { |
242 } | 214 /* eliminate Hash algorithms */ |
243 if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) { | |
244 » /* eliminate Hash algorithms */ | |
245 » return SEC_OID_UNKNOWN; | |
246 } | |
247 if (PK11_AlgtagToMechanism(algTag) != CKM_INVALID_MECHANISM) { | |
248 » /* it's not a hash, if it has a PKCS #11 mechanism associated | |
249 » * with it, assume it's a cipher. (NOTE this will generate | |
250 » * some false positives). */ | |
251 » return SEC_OID_PKCS5_PBES2; | |
252 } | |
253 return SEC_OID_UNKNOWN; | 215 return SEC_OID_UNKNOWN; |
254 } | 216 } |
255 | 217 if (PK11_AlgtagToMechanism(algTag) != CKM_INVALID_MECHANISM) { |
256 /* | 218 /* it's not a hash, if it has a PKCS #11 mechanism associated |
| 219 * with it, assume it's a cipher. (NOTE this will generate |
| 220 * some false positives). */ |
| 221 return SEC_OID_PKCS5_PBES2; |
| 222 } |
| 223 return SEC_OID_UNKNOWN; |
| 224 } |
| 225 |
| 226 /* |
257 * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing. | 227 * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing. |
258 * input keyLen in bits. | 228 * input keyLen in bits. |
259 */ | 229 */ |
260 SECOidTag | 230 SECOidTag SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen) { |
261 SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen) | 231 switch (algTag) { |
262 { | 232 case SEC_OID_DES_EDE3_CBC: |
263 switch(algTag) | 233 switch (keyLen) { |
264 { | 234 case 168: |
265 » case SEC_OID_DES_EDE3_CBC: | 235 case 192: |
266 » switch(keyLen) { | 236 case 0: |
267 » » case 168: | 237 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC; |
268 » » case 192: | 238 case 128: |
269 » » case 0: | 239 case 92: |
270 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_C
BC; | 240 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC; |
271 » » case 128: | 241 default: |
272 » » case 92: | 242 break; |
273 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_C
BC; | 243 } |
274 » » default: | 244 break; |
275 » » break; | 245 case SEC_OID_DES_CBC: |
276 » } | 246 return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC; |
277 » break; | 247 case SEC_OID_RC2_CBC: |
278 » case SEC_OID_DES_CBC: | 248 switch (keyLen) { |
279 » return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC; | 249 case 40: |
280 » case SEC_OID_RC2_CBC: | 250 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; |
281 » switch(keyLen) { | 251 case 128: |
282 » » case 40: | 252 case 0: |
283 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; | 253 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC; |
284 » » case 128: | 254 default: |
285 » » case 0: | 255 break; |
286 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC; | 256 } |
287 » » default: | 257 break; |
288 » » break; | 258 case SEC_OID_RC4: |
289 » } | 259 switch (keyLen) { |
290 » break; | 260 case 40: |
291 » case SEC_OID_RC4: | 261 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4; |
292 » switch(keyLen) { | 262 case 128: |
293 » » case 40: | 263 case 0: |
294 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4; | 264 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4; |
295 » » case 128: | 265 default: |
296 » » case 0: | 266 break; |
297 » » return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4; | 267 } |
298 » » default: | 268 break; |
299 » » break; | 269 default: |
300 » } | 270 return sec_pkcs5v2_get_pbe(algTag); |
301 » break; | 271 } |
302 » default: | 272 |
303 » return sec_pkcs5v2_get_pbe(algTag); | 273 return SEC_OID_UNKNOWN; |
304 } | |
305 | |
306 return SEC_OID_UNKNOWN; | |
307 } | 274 } |
308 | 275 |
309 /* | 276 /* |
310 * get the key length in bytes from a PKCS5 PBE | 277 * get the key length in bytes from a PKCS5 PBE |
311 */ | 278 */ |
312 int | 279 int sec_pkcs5v2_key_length(SECAlgorithmID *algid) { |
313 sec_pkcs5v2_key_length(SECAlgorithmID *algid) | 280 SECOidTag algorithm; |
314 { | 281 PLArenaPool *arena = NULL; |
315 SECOidTag algorithm; | 282 SEC_PKCS5PBEParameter p5_param; |
316 PLArenaPool *arena = NULL; | 283 SECStatus rv; |
317 SEC_PKCS5PBEParameter p5_param; | 284 int length = -1; |
318 SECStatus rv; | 285 |
319 int length = -1; | 286 algorithm = SECOID_GetAlgorithmTag(algid); |
320 | 287 /* sanity check, they should all be PBKDF2 here */ |
321 algorithm = SECOID_GetAlgorithmTag(algid); | 288 if (algorithm != SEC_OID_PKCS5_PBKDF2) { |
322 /* sanity check, they should all be PBKDF2 here */ | 289 return -1; |
323 if (algorithm != SEC_OID_PKCS5_PBKDF2) { | 290 } |
324 » return -1; | 291 |
325 } | 292 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); |
326 | 293 if (arena == NULL) { |
327 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | 294 goto loser; |
328 if (arena == NULL) { | 295 } |
329 » goto loser; | 296 PORT_Memset(&p5_param, 0, sizeof(p5_param)); |
330 } | 297 rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5V2PBEParameterTemplate, |
331 PORT_Memset(&p5_param, 0, sizeof(p5_param)); | 298 &algid->parameters); |
332 rv = SEC_ASN1DecodeItem(arena,&p5_param, | 299 if (rv != SECSuccess) { |
333 » » » SEC_PKCS5V2PBEParameterTemplate, &algid->parameters); | 300 goto loser; |
334 if (rv != SECSuccess) { | 301 } |
335 » goto loser; | 302 |
336 } | 303 if (p5_param.keyLength.data != NULL) { |
337 | 304 length = DER_GetInteger(&p5_param.keyLength); |
338 if (p5_param.keyLength.data != NULL) { | 305 } |
339 length = DER_GetInteger(&p5_param.keyLength); | |
340 } | |
341 | 306 |
342 loser: | 307 loser: |
343 if (arena) { | 308 if (arena) { |
344 » PORT_FreeArena(arena, PR_FALSE); | 309 PORT_FreeArena(arena, PR_FALSE); |
345 } | 310 } |
346 return length; | 311 return length; |
347 } | 312 } |
348 | 313 |
349 /* | 314 /* |
350 * get the key length in bytes needed for the PBE algorithm | 315 * get the key length in bytes needed for the PBE algorithm |
351 */ | 316 */ |
352 int | 317 int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid) { |
353 SEC_PKCS5GetKeyLength(SECAlgorithmID *algid) | 318 |
354 { | 319 SECOidTag algorithm; |
355 | 320 |
356 SECOidTag algorithm; | 321 if (algid == NULL) return SEC_OID_UNKNOWN; |
357 | 322 |
358 if(algid == NULL) | 323 algorithm = SECOID_GetAlgorithmTag(algid); |
359 » return SEC_OID_UNKNOWN; | 324 |
360 | 325 switch (algorithm) { |
361 algorithm = SECOID_GetAlgorithmTag(algid); | 326 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: |
362 | 327 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: |
363 switch(algorithm) | 328 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: |
364 { | 329 return 24; |
365 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: | 330 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: |
366 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: | 331 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: |
367 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: | 332 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: |
368 » return 24; | 333 return 8; |
369 » case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: | 334 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: |
370 » case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: | 335 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: |
371 » case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: | 336 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: |
372 » return 8; | 337 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: |
373 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: | 338 return 5; |
374 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: | 339 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: |
375 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: | 340 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: |
376 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: | 341 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: |
377 » return 5; | 342 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: |
378 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: | 343 return 16; |
379 » case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: | 344 case SEC_OID_PKCS5_PBKDF2: |
380 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: | 345 return sec_pkcs5v2_key_length(algid); |
381 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: | 346 case SEC_OID_PKCS5_PBES2: |
382 » return 16; | 347 case SEC_OID_PKCS5_PBMAC1: { |
383 » case SEC_OID_PKCS5_PBKDF2: | 348 sec_pkcs5V2Parameter *pbeV2_param; |
384 » return sec_pkcs5v2_key_length(algid); | 349 int length = -1; |
385 » case SEC_OID_PKCS5_PBES2: | 350 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); |
386 » case SEC_OID_PKCS5_PBMAC1: | 351 if (pbeV2_param != NULL) { |
387 » { | 352 length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId); |
388 » » sec_pkcs5V2Parameter *pbeV2_param; | 353 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); |
389 » » int length = -1; | 354 } |
390 » » pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); | 355 return length; |
391 » » if (pbeV2_param != NULL) { | 356 } |
392 » » length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId); | 357 |
393 » » sec_pkcs5_v2_destroy_v2_param(pbeV2_param); | 358 default: |
394 » » } | 359 break; |
395 » » return length; | 360 } |
396 » } | 361 return -1; |
397 »······· | 362 } |
398 » default: | |
399 » break; | |
400 } | |
401 return -1; | |
402 } | |
403 | |
404 | 363 |
405 /* the PKCS12 V2 algorithms only encode the salt, there is no iteration | 364 /* the PKCS12 V2 algorithms only encode the salt, there is no iteration |
406 * count so we need a check for V2 algorithm parameters. | 365 * count so we need a check for V2 algorithm parameters. |
407 */ | 366 */ |
408 static PRBool | 367 static PRBool sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm) { |
409 sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm) | 368 switch (algorithm) { |
410 { | 369 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: |
411 switch(algorithm) | 370 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: |
412 { | 371 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: |
413 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: | 372 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: |
414 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: | 373 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: |
415 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: | 374 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: |
416 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: | 375 return PR_TRUE; |
417 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: | 376 default: |
418 » case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: | 377 break; |
419 » return PR_TRUE; | 378 } |
420 » default: | 379 |
421 » break; | 380 return PR_FALSE; |
422 } | 381 } |
423 | 382 |
424 return PR_FALSE; | 383 static PRBool sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm) { |
425 } | 384 switch (algorithm) { |
426 | 385 case SEC_OID_PKCS5_PBES2: |
427 static PRBool | 386 case SEC_OID_PKCS5_PBMAC1: |
428 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm) | 387 case SEC_OID_PKCS5_PBKDF2: |
429 { | 388 return PR_TRUE; |
430 switch(algorithm) | 389 default: |
431 { | 390 break; |
432 » case SEC_OID_PKCS5_PBES2: | 391 } |
433 » case SEC_OID_PKCS5_PBMAC1: | 392 |
434 » case SEC_OID_PKCS5_PBKDF2: | 393 return PR_FALSE; |
435 » return PR_TRUE; | 394 } |
436 » default: | 395 |
437 » break; | 396 /* destroy a pbe parameter. it assumes that the parameter was |
438 } | |
439 | |
440 return PR_FALSE; | |
441 } | |
442 | |
443 /* destroy a pbe parameter. it assumes that the parameter was· | |
444 * generated using the appropriate create function and therefor | 397 * generated using the appropriate create function and therefor |
445 * contains an arena pool. | 398 * contains an arena pool. |
446 */ | 399 */ |
447 static void | 400 static void sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param) { |
448 sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param) | 401 if (pbe_param != NULL) PORT_FreeArena(pbe_param->poolp, PR_TRUE); |
449 { | |
450 if(pbe_param != NULL) | |
451 » PORT_FreeArena(pbe_param->poolp, PR_TRUE); | |
452 } | 402 } |
453 | 403 |
454 /* creates a PBE parameter based on the PBE algorithm. the only required | 404 /* creates a PBE parameter based on the PBE algorithm. the only required |
455 * parameters are algorithm and interation. the return is a PBE parameter | 405 * parameters are algorithm and interation. the return is a PBE parameter |
456 * which conforms to PKCS 5 parameter unless an extended parameter is needed. | 406 * which conforms to PKCS 5 parameter unless an extended parameter is needed. |
457 * this is primarily if keyLength and a variable key length algorithm are | 407 * this is primarily if keyLength and a variable key length algorithm are |
458 * specified. | 408 * specified. |
459 * salt - if null, a salt will be generated from random bytes. | 409 * salt - if null, a salt will be generated from random bytes. |
460 * iteration - number of iterations to perform hashing. | 410 * iteration - number of iterations to perform hashing. |
461 * keyLength - only used in variable key length algorithms. if specified, | 411 * keyLength - only used in variable key length algorithms. if specified, |
462 * should be in bytes. | 412 * should be in bytes. |
463 * once a parameter is allocated, it should be destroyed calling | 413 * once a parameter is allocated, it should be destroyed calling |
464 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter. | 414 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter. |
465 */ | 415 */ |
466 #define DEFAULT_SALT_LENGTH 16 | 416 #define DEFAULT_SALT_LENGTH 16 |
467 static SEC_PKCS5PBEParameter * | 417 static SEC_PKCS5PBEParameter *sec_pkcs5_create_pbe_parameter( |
468 sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,· | 418 SECOidTag algorithm, SECItem *salt, int iteration, int keyLength, |
469 » » » SECItem *salt,· | 419 SECOidTag prfAlg) { |
470 » » » int iteration, | 420 PLArenaPool *poolp = NULL; |
471 » » » int keyLength, | 421 SEC_PKCS5PBEParameter *pbe_param = NULL; |
472 » » » SECOidTag prfAlg) | 422 SECStatus rv = SECSuccess; |
473 { | 423 void *dummy = NULL; |
474 PLArenaPool *poolp = NULL; | 424 |
475 SEC_PKCS5PBEParameter *pbe_param = NULL; | 425 if (iteration < 0) { |
476 SECStatus rv= SECSuccess;· | 426 return NULL; |
477 void *dummy = NULL; | 427 } |
478 | 428 |
479 if(iteration < 0) { | 429 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); |
480 » return NULL; | 430 if (poolp == NULL) return NULL; |
481 } | 431 |
482 | 432 pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc( |
483 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | 433 poolp, sizeof(SEC_PKCS5PBEParameter)); |
484 if(poolp == NULL) | 434 if (!pbe_param) { |
485 » return NULL; | 435 PORT_FreeArena(poolp, PR_TRUE); |
486 | 436 return NULL; |
487 pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp, | 437 } |
488 » sizeof(SEC_PKCS5PBEParameter)); | 438 |
489 if(!pbe_param) { | 439 pbe_param->poolp = poolp; |
490 » PORT_FreeArena(poolp, PR_TRUE); | 440 |
491 » return NULL; | 441 rv = SECFailure; |
492 } | 442 if (salt && salt->data) { |
493 | 443 rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt); |
494 pbe_param->poolp = poolp; | 444 } else { |
495 | 445 /* sigh, the old interface generated salt on the fly, so we have to |
496 rv = SECFailure; | 446 * preserve the semantics */ |
497 if (salt && salt->data) { | 447 pbe_param->salt.len = DEFAULT_SALT_LENGTH; |
498 » rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt); | 448 pbe_param->salt.data = PORT_ArenaZAlloc(poolp, DEFAULT_SALT_LENGTH); |
| 449 if (pbe_param->salt.data) { |
| 450 rv = PK11_GenerateRandom(pbe_param->salt.data, DEFAULT_SALT_LENGTH); |
| 451 } |
| 452 } |
| 453 |
| 454 if (rv != SECSuccess) { |
| 455 PORT_FreeArena(poolp, PR_TRUE); |
| 456 return NULL; |
| 457 } |
| 458 |
| 459 /* encode the integer */ |
| 460 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration, iteration); |
| 461 rv = (dummy) ? SECSuccess : SECFailure; |
| 462 |
| 463 if (rv != SECSuccess) { |
| 464 PORT_FreeArena(poolp, PR_FALSE); |
| 465 return NULL; |
| 466 } |
| 467 |
| 468 /* |
| 469 * for PKCS5 v2 Add the keylength and the prf |
| 470 */ |
| 471 if (algorithm == SEC_OID_PKCS5_PBKDF2) { |
| 472 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->keyLength, keyLength); |
| 473 rv = (dummy) ? SECSuccess : SECFailure; |
| 474 if (rv != SECSuccess) { |
| 475 PORT_FreeArena(poolp, PR_FALSE); |
| 476 return NULL; |
| 477 } |
| 478 rv = SECOID_SetAlgorithmID(poolp, &pbe_param->prfAlgId, prfAlg, NULL); |
| 479 if (rv != SECSuccess) { |
| 480 PORT_FreeArena(poolp, PR_FALSE); |
| 481 return NULL; |
| 482 } |
| 483 pbe_param->pPrfAlgId = &pbe_param->prfAlgId; |
| 484 } |
| 485 |
| 486 return pbe_param; |
| 487 } |
| 488 |
| 489 /* creates a algorithm ID containing the PBE algorithm and appropriate |
| 490 * parameters. the required parameter is the algorithm. if salt is |
| 491 * not specified, it is generated randomly. |
| 492 * |
| 493 * the returned SECAlgorithmID should be destroyed using |
| 494 * SECOID_DestroyAlgorithmID |
| 495 */ |
| 496 SECAlgorithmID *sec_pkcs5CreateAlgorithmID( |
| 497 SECOidTag algorithm, SECOidTag cipherAlgorithm, SECOidTag prfAlg, |
| 498 SECOidTag *pPbeAlgorithm, int keyLength, SECItem *salt, int iteration) { |
| 499 PLArenaPool *poolp = NULL; |
| 500 SECAlgorithmID *algid, *ret_algid = NULL; |
| 501 SECOidTag pbeAlgorithm = algorithm; |
| 502 SECItem der_param; |
| 503 void *dummy; |
| 504 SECStatus rv = SECFailure; |
| 505 SEC_PKCS5PBEParameter *pbe_param = NULL; |
| 506 sec_pkcs5V2Parameter pbeV2_param; |
| 507 |
| 508 if (iteration <= 0) { |
| 509 return NULL; |
| 510 } |
| 511 |
| 512 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); |
| 513 if (!poolp) { |
| 514 goto loser; |
| 515 } |
| 516 |
| 517 if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm) || |
| 518 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { |
| 519 /* use PKCS 5 v2 */ |
| 520 SECItem *cipherParams; |
| 521 |
| 522 /* |
| 523 * if we ask for pkcs5 Algorithms directly, then the |
| 524 * application needs to supply the cipher algorithm, |
| 525 * otherwise we are implicitly using pkcs5 v2 and the |
| 526 * passed in algorithm is the encryption algorithm. |
| 527 */ |
| 528 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { |
| 529 if (cipherAlgorithm == SEC_OID_UNKNOWN) { |
| 530 goto loser; |
| 531 } |
499 } else { | 532 } else { |
500 » /* sigh, the old interface generated salt on the fly, so we have to | 533 cipherAlgorithm = algorithm; |
501 » * preserve the semantics */ | 534 /* force algorithm to be chosen below */ |
502 » pbe_param->salt.len = DEFAULT_SALT_LENGTH; | 535 algorithm = SEC_OID_PKCS5_PBKDF2; |
503 » pbe_param->salt.data = PORT_ArenaZAlloc(poolp,DEFAULT_SALT_LENGTH); | 536 } |
504 » if (pbe_param->salt.data) { | 537 |
505 » rv = PK11_GenerateRandom(pbe_param->salt.data,DEFAULT_SALT_LENGTH); | 538 pbeAlgorithm = SEC_OID_PKCS5_PBKDF2; |
506 » } | |
507 } | |
508 | |
509 if(rv != SECSuccess) { | |
510 » PORT_FreeArena(poolp, PR_TRUE); | |
511 » return NULL; | |
512 } | |
513 | |
514 /* encode the integer */ | |
515 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,· | |
516 » » iteration); | |
517 rv = (dummy) ? SECSuccess : SECFailure; | |
518 | |
519 if(rv != SECSuccess) { | |
520 » PORT_FreeArena(poolp, PR_FALSE); | |
521 » return NULL; | |
522 } | |
523 | |
524 /* | 539 /* |
525 * for PKCS5 v2 Add the keylength and the prf | 540 * 'algorithm' is the overall algorithm oid tag used to wrap the |
| 541 * entire algoithm ID block. For PKCS5v1 and PKCS12, this |
| 542 * algorithm OID has encoded in it both the PBE KDF function |
| 543 * and the encryption algorithm. For PKCS 5v2, PBE KDF and |
| 544 * encryption/macing oids are encoded as parameters in |
| 545 * the algorithm ID block. |
| 546 * |
| 547 * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11 |
| 548 * mechanism, where as in PKCS 5v2, this alogithm tag does not map |
| 549 * directly to a PKCS #11 mechanim, instead the 2 oids in the |
| 550 * algorithm ID block map the the actual PKCS #11 mechanism. |
| 551 * gorithm is). We use choose this algorithm oid based on the |
| 552 * cipherAlgorithm to determine what this should be (MAC1 or PBES2). |
526 */ | 553 */ |
527 if (algorithm == SEC_OID_PKCS5_PBKDF2) { | 554 if (algorithm == SEC_OID_PKCS5_PBKDF2) { |
528 » dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->keyLength,· | 555 /* choose mac or pbes */ |
529 » » keyLength); | 556 algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm); |
530 » rv = (dummy) ? SECSuccess : SECFailure; | 557 } |
531 » if (rv != SECSuccess) { | 558 |
532 » PORT_FreeArena(poolp, PR_FALSE); | 559 /* set the PKCS5v2 specific parameters */ |
533 » return NULL; | 560 if (keyLength == 0) { |
534 » } | 561 SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm); |
535 » rv = SECOID_SetAlgorithmID(poolp, &pbe_param->prfAlgId, prfAlg, NULL); | 562 if (hashAlg != SEC_OID_UNKNOWN) { |
536 » if (rv != SECSuccess) { | 563 keyLength = HASH_ResultLenByOidTag(hashAlg); |
537 » PORT_FreeArena(poolp, PR_FALSE); | 564 } else { |
538 » return NULL; | 565 CK_MECHANISM_TYPE cryptoMech; |
539 » } | 566 cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm); |
540 » pbe_param->pPrfAlgId = &pbe_param->prfAlgId; | 567 if (cryptoMech == CKM_INVALID_MECHANISM) { |
541 } | 568 goto loser; |
542 | 569 } |
543 return pbe_param; | 570 keyLength = PK11_GetMaxKeyLength(cryptoMech); |
544 } | 571 } |
545 | 572 if (keyLength == 0) { |
546 /* creates a algorithm ID containing the PBE algorithm and appropriate | 573 goto loser; |
547 * parameters. the required parameter is the algorithm. if salt is | 574 } |
548 * not specified, it is generated randomly.·· | 575 } |
549 * | 576 /* currently only SEC_OID_HMAC_SHA1 is defined */ |
550 * the returned SECAlgorithmID should be destroyed using· | 577 if (prfAlg == SEC_OID_UNKNOWN) { |
551 * SECOID_DestroyAlgorithmID | 578 prfAlg = SEC_OID_HMAC_SHA1; |
552 */ | 579 } |
553 SECAlgorithmID * | 580 |
554 sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,· | 581 /* build the PKCS5v2 cipher algorithm id */ |
555 » » » SECOidTag cipherAlgorithm, | 582 cipherParams = pk11_GenerateNewParamWithKeyLen( |
556 » » » SECOidTag prfAlg, | 583 PK11_AlgtagToMechanism(cipherAlgorithm), keyLength); |
557 » » » SECOidTag *pPbeAlgorithm, | 584 if (!cipherParams) { |
558 » » » int keyLength, | 585 goto loser; |
559 » » » SECItem *salt,· | 586 } |
560 » » » int iteration) | 587 |
561 { | 588 PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param)); |
562 PLArenaPool *poolp = NULL; | 589 |
563 SECAlgorithmID *algid, *ret_algid = NULL; | 590 rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams, poolp, |
564 SECOidTag pbeAlgorithm = algorithm; | 591 &pbeV2_param.cipherAlgId); |
565 SECItem der_param; | 592 SECITEM_FreeItem(cipherParams, PR_TRUE); |
566 void *dummy; | 593 if (rv != SECSuccess) { |
567 SECStatus rv = SECFailure; | 594 goto loser; |
568 SEC_PKCS5PBEParameter *pbe_param = NULL; | 595 } |
569 sec_pkcs5V2Parameter pbeV2_param; | 596 } |
570 | 597 |
571 if(iteration <= 0) { | 598 /* generate the parameter */ |
572 » return NULL; | 599 pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration, |
573 } | 600 keyLength, prfAlg); |
574 | 601 if (!pbe_param) { |
575 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | 602 goto loser; |
576 if(!poolp) { | 603 } |
577 » goto loser; | 604 |
578 } | 605 /* generate the algorithm id */ |
579 | 606 algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); |
580 if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm) || | 607 if (algid == NULL) { |
581 » » sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { | 608 goto loser; |
582 » /* use PKCS 5 v2 */ | 609 } |
583 » SECItem *cipherParams; | 610 |
584 | 611 der_param.data = NULL; |
585 » /* | 612 der_param.len = 0; |
586 » * if we ask for pkcs5 Algorithms directly, then the | 613 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { |
587 » * application needs to supply the cipher algorithm, | 614 /* first encode the PBE algorithm ID */ |
588 » * otherwise we are implicitly using pkcs5 v2 and the | 615 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, |
589 » * passed in algorithm is the encryption algorithm. | 616 SEC_PKCS5V2PBEParameterTemplate); |
590 » */ | 617 if (dummy == NULL) { |
591 » if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { | 618 goto loser; |
592 » if (cipherAlgorithm == SEC_OID_UNKNOWN) { | 619 } |
593 » » goto loser; | 620 rv = SECOID_SetAlgorithmID(poolp, &pbeV2_param.pbeAlgId, pbeAlgorithm, |
594 » } | 621 &der_param); |
595 » } else { | 622 if (rv != SECSuccess) { |
596 » cipherAlgorithm = algorithm; | 623 goto loser; |
597 » /* force algorithm to be chosen below */ | 624 } |
598 » algorithm = SEC_OID_PKCS5_PBKDF2; | 625 |
599 » } | 626 /* now encode the Full PKCS 5 parameter */ |
600 »······· | |
601 » pbeAlgorithm = SEC_OID_PKCS5_PBKDF2; | |
602 » /* | |
603 » * 'algorithm' is the overall algorithm oid tag used to wrap the· | |
604 » * entire algoithm ID block. For PKCS5v1 and PKCS12, this· | |
605 » * algorithm OID has encoded in it both the PBE KDF function· | |
606 » * and the encryption algorithm. For PKCS 5v2, PBE KDF and | |
607 » * encryption/macing oids are encoded as parameters in | |
608 » * the algorithm ID block.· | |
609 » * | |
610 » * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11 | |
611 » * mechanism, where as in PKCS 5v2, this alogithm tag does not map | |
612 » * directly to a PKCS #11 mechanim, instead the 2 oids in the· | |
613 » * algorithm ID block map the the actual PKCS #11 mechanism. | |
614 » * gorithm is). We use choose this algorithm oid based on the· | |
615 » * cipherAlgorithm to determine what this should be (MAC1 or PBES2). | |
616 » */ | |
617 » if (algorithm == SEC_OID_PKCS5_PBKDF2) { | |
618 » /* choose mac or pbes */ | |
619 » algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm); | |
620 » } | |
621 | |
622 » /* set the PKCS5v2 specific parameters */ | |
623 » if (keyLength == 0) { | |
624 » SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm); | |
625 » if (hashAlg != SEC_OID_UNKNOWN) { | |
626 » keyLength = HASH_ResultLenByOidTag(hashAlg); | |
627 » } else { | |
628 » » CK_MECHANISM_TYPE cryptoMech; | |
629 » » cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm); | |
630 » » if (cryptoMech == CKM_INVALID_MECHANISM) { | |
631 » » goto loser; | |
632 » » } | |
633 » keyLength = PK11_GetMaxKeyLength(cryptoMech); | |
634 » } | |
635 » if (keyLength == 0) { | |
636 » » goto loser; | |
637 » } | |
638 » } | |
639 » /* currently only SEC_OID_HMAC_SHA1 is defined */ | |
640 » if (prfAlg == SEC_OID_UNKNOWN) { | |
641 » prfAlg = SEC_OID_HMAC_SHA1; | |
642 » } | |
643 | |
644 » /* build the PKCS5v2 cipher algorithm id */ | |
645 » cipherParams = pk11_GenerateNewParamWithKeyLen(» | |
646 » » » PK11_AlgtagToMechanism(cipherAlgorithm), keyLength); | |
647 » if (!cipherParams) { | |
648 » goto loser; | |
649 » } | |
650 | |
651 » PORT_Memset(&pbeV2_param, 0, sizeof (pbeV2_param)); | |
652 | |
653 » rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,· | |
654 » » » » poolp, &pbeV2_param.cipherAlgId); | |
655 » SECITEM_FreeItem(cipherParams, PR_TRUE); | |
656 » if (rv != SECSuccess) { | |
657 » goto loser; | |
658 » } | |
659 } | |
660 »······· | |
661 | |
662 /* generate the parameter */ | |
663 pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration, | |
664 » » » keyLength, prfAlg); | |
665 if(!pbe_param) { | |
666 » goto loser; | |
667 } | |
668 | |
669 /* generate the algorithm id */ | |
670 algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); | |
671 if(algid == NULL) { | |
672 » goto loser; | |
673 } | |
674 | |
675 der_param.data = NULL; | 627 der_param.data = NULL; |
676 der_param.len = 0; | 628 der_param.len = 0; |
677 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { | 629 dummy = SEC_ASN1EncodeItem(poolp, &der_param, &pbeV2_param, |
678 » /* first encode the PBE algorithm ID */ | 630 SEC_PKCS5V2ParameterTemplate); |
679 » dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, | 631 } else if (!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { |
680 » » » » » SEC_PKCS5V2PBEParameterTemplate); | 632 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, |
681 » if (dummy == NULL) { | 633 SEC_PKCS5PBEParameterTemplate); |
682 » goto loser; | 634 } else { |
683 » } | 635 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, |
684 » rv = SECOID_SetAlgorithmID(poolp, &pbeV2_param.pbeAlgId,· | 636 SEC_V2PKCS12PBEParameterTemplate); |
685 » » » » pbeAlgorithm, &der_param); | 637 } |
686 » if (rv != SECSuccess) { | 638 if (dummy == NULL) { |
687 » goto loser; | 639 goto loser; |
688 » } | 640 } |
689 | 641 |
690 » /* now encode the Full PKCS 5 parameter */ | 642 rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param); |
691 » der_param.data = NULL; | 643 if (rv != SECSuccess) { |
692 » der_param.len = 0; | 644 goto loser; |
693 » dummy = SEC_ASN1EncodeItem(poolp, &der_param, &pbeV2_param, | 645 } |
694 » » » » » SEC_PKCS5V2ParameterTemplate); | 646 |
695 } else if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { | 647 ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); |
696 » dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, | 648 if (ret_algid == NULL) { |
697 » » » » » SEC_PKCS5PBEParameterTemplate); | 649 goto loser; |
| 650 } |
| 651 |
| 652 rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); |
| 653 if (rv != SECSuccess) { |
| 654 SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); |
| 655 ret_algid = NULL; |
| 656 } else if (pPbeAlgorithm) { |
| 657 *pPbeAlgorithm = pbeAlgorithm; |
| 658 } |
| 659 |
| 660 loser: |
| 661 if (poolp != NULL) { |
| 662 PORT_FreeArena(poolp, PR_TRUE); |
| 663 algid = NULL; |
| 664 } |
| 665 |
| 666 if (pbe_param) { |
| 667 sec_pkcs5_destroy_pbe_param(pbe_param); |
| 668 } |
| 669 |
| 670 return ret_algid; |
| 671 } |
| 672 |
| 673 SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech) { |
| 674 SEC_PKCS5PBEParameter p5_param; |
| 675 SECItem *salt = NULL; |
| 676 SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); |
| 677 PLArenaPool *arena = NULL; |
| 678 SECStatus rv = SECFailure; |
| 679 unsigned char *paramData = NULL; |
| 680 unsigned char *pSalt = NULL; |
| 681 CK_ULONG iterations; |
| 682 int paramLen = 0; |
| 683 int iv_len; |
| 684 |
| 685 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); |
| 686 if (arena == NULL) { |
| 687 goto loser; |
| 688 } |
| 689 |
| 690 /* |
| 691 * decode the algid based on the pbe type |
| 692 */ |
| 693 PORT_Memset(&p5_param, 0, sizeof(p5_param)); |
| 694 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { |
| 695 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); |
| 696 rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_V2PKCS12PBEParameterTemplate, |
| 697 &algid->parameters); |
| 698 } else if (algorithm == SEC_OID_PKCS5_PBKDF2) { |
| 699 iv_len = 0; |
| 700 rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5V2PBEParameterTemplate, |
| 701 &algid->parameters); |
| 702 } else { |
| 703 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); |
| 704 rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5PBEParameterTemplate, |
| 705 &algid->parameters); |
| 706 } |
| 707 |
| 708 if (iv_len < 0) { |
| 709 goto loser; |
| 710 } |
| 711 |
| 712 if (rv != SECSuccess) { |
| 713 goto loser; |
| 714 } |
| 715 |
| 716 /* get salt */ |
| 717 salt = &p5_param.salt; |
| 718 iterations = (CK_ULONG)DER_GetInteger(&p5_param.iteration); |
| 719 |
| 720 /* allocate and fill in the PKCS #11 parameters |
| 721 * based on the algorithm. */ |
| 722 if (algorithm == SEC_OID_PKCS5_PBKDF2) { |
| 723 SECOidTag prfAlgTag; |
| 724 CK_PKCS5_PBKD2_PARAMS *pbeV2_params = (CK_PKCS5_PBKD2_PARAMS *)PORT_ZAlloc( |
| 725 sizeof(CK_PKCS5_PBKD2_PARAMS) + salt->len); |
| 726 |
| 727 if (pbeV2_params == NULL) { |
| 728 goto loser; |
| 729 } |
| 730 paramData = (unsigned char *)pbeV2_params; |
| 731 paramLen = sizeof(CK_PKCS5_PBKD2_PARAMS); |
| 732 |
| 733 /* set the prf */ |
| 734 prfAlgTag = SEC_OID_HMAC_SHA1; |
| 735 if (p5_param.pPrfAlgId && p5_param.pPrfAlgId->algorithm.data != 0) { |
| 736 prfAlgTag = SECOID_GetAlgorithmTag(p5_param.pPrfAlgId); |
| 737 } |
| 738 if (prfAlgTag == SEC_OID_HMAC_SHA1) { |
| 739 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1; |
698 } else { | 740 } else { |
699 » dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, | 741 /* only SHA1_HMAC is currently supported by PKCS #11 */ |
700 » » » » » SEC_V2PKCS12PBEParameterTemplate); | 742 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
701 } | 743 goto loser; |
702 if (dummy == NULL) { | 744 } |
703 » goto loser; | 745 |
704 } | 746 /* probably should fetch these from the prfAlgid */ |
705 | 747 pbeV2_params->pPrfData = NULL; |
706 rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param); | 748 pbeV2_params->ulPrfDataLen = 0; |
707 if (rv != SECSuccess) { | 749 pbeV2_params->saltSource = CKZ_SALT_SPECIFIED; |
708 » goto loser; | 750 pSalt = ((CK_CHAR_PTR)pbeV2_params) + sizeof(CK_PKCS5_PBKD2_PARAMS); |
709 } | 751 PORT_Memcpy(pSalt, salt->data, salt->len); |
710 | 752 pbeV2_params->pSaltSourceData = pSalt; |
711 ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); | 753 pbeV2_params->ulSaltSourceDataLen = salt->len; |
712 if (ret_algid == NULL) { | 754 pbeV2_params->iterations = iterations; |
713 » goto loser; | 755 } else { |
714 } | 756 CK_PBE_PARAMS *pbe_params = NULL; |
715 | 757 pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS) + |
716 rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); | 758 salt->len + iv_len); |
717 if (rv != SECSuccess) { | 759 if (pbe_params == NULL) { |
718 » SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); | 760 goto loser; |
719 » ret_algid = NULL; | 761 } |
720 } else if (pPbeAlgorithm) { | 762 paramData = (unsigned char *)pbe_params; |
721 » *pPbeAlgorithm = pbeAlgorithm; | 763 paramLen = sizeof(CK_PBE_PARAMS); |
722 } | 764 |
| 765 pSalt = ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS); |
| 766 pbe_params->pSalt = pSalt; |
| 767 PORT_Memcpy(pSalt, salt->data, salt->len); |
| 768 pbe_params->ulSaltLen = salt->len; |
| 769 if (iv_len) { |
| 770 pbe_params->pInitVector = |
| 771 ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS) + salt->len; |
| 772 } |
| 773 pbe_params->ulIteration = iterations; |
| 774 } |
| 775 |
| 776 /* copy into the mechanism sec item */ |
| 777 mech->data = paramData; |
| 778 mech->len = paramLen; |
| 779 if (arena) { |
| 780 PORT_FreeArena(arena, PR_TRUE); |
| 781 } |
| 782 return SECSuccess; |
723 | 783 |
724 loser: | 784 loser: |
725 if (poolp != NULL) { | 785 if (paramData) { |
726 » PORT_FreeArena(poolp, PR_TRUE); | 786 PORT_Free(paramData); |
727 » algid = NULL; | 787 } |
728 } | 788 if (arena) { |
729 | 789 PORT_FreeArena(arena, PR_TRUE); |
730 if (pbe_param) { | 790 } |
731 » sec_pkcs5_destroy_pbe_param(pbe_param); | 791 return SECFailure; |
732 } | 792 } |
733 | 793 |
734 return ret_algid; | 794 /* |
735 } | 795 * public, deprecated, not valid for pkcs5 v2 |
736 | 796 * |
737 SECStatus | |
738 pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech) | |
739 { | |
740 SEC_PKCS5PBEParameter p5_param; | |
741 SECItem *salt = NULL; | |
742 SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); | |
743 PLArenaPool *arena = NULL; | |
744 SECStatus rv = SECFailure; | |
745 unsigned char *paramData = NULL; | |
746 unsigned char *pSalt = NULL; | |
747 CK_ULONG iterations; | |
748 int paramLen = 0; | |
749 int iv_len; | |
750 ···· | |
751 | |
752 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); | |
753 if (arena == NULL) { | |
754 » goto loser; | |
755 } | |
756 | |
757 | |
758 /* | |
759 * decode the algid based on the pbe type | |
760 */ | |
761 PORT_Memset(&p5_param, 0, sizeof(p5_param)); | |
762 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { | |
763 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); | |
764 rv = SEC_ASN1DecodeItem(arena, &p5_param, | |
765 » » » SEC_V2PKCS12PBEParameterTemplate, &algid->parameters); | |
766 } else if (algorithm == SEC_OID_PKCS5_PBKDF2) { | |
767 » iv_len = 0; | |
768 rv = SEC_ASN1DecodeItem(arena,&p5_param, | |
769 » » » SEC_PKCS5V2PBEParameterTemplate, &algid->parameters); | |
770 } else { | |
771 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); | |
772 rv = SEC_ASN1DecodeItem(arena,&p5_param,SEC_PKCS5PBEParameterTemplate,· | |
773 » » » » » » &algid->parameters); | |
774 } | |
775 | |
776 if (iv_len < 0) { | |
777 » goto loser; | |
778 } | |
779 | |
780 if (rv != SECSuccess) { | |
781 » goto loser; | |
782 } | |
783 ········ | |
784 /* get salt */ | |
785 salt = &p5_param.salt; | |
786 iterations = (CK_ULONG) DER_GetInteger(&p5_param.iteration); | |
787 | |
788 /* allocate and fill in the PKCS #11 parameters | |
789 * based on the algorithm. */ | |
790 if (algorithm == SEC_OID_PKCS5_PBKDF2) { | |
791 » SECOidTag prfAlgTag; | |
792 » CK_PKCS5_PBKD2_PARAMS *pbeV2_params =· | |
793 » » (CK_PKCS5_PBKD2_PARAMS *)PORT_ZAlloc( | |
794 » » » sizeof(CK_PKCS5_PBKD2_PARAMS)+ salt->len); | |
795 | |
796 » if (pbeV2_params == NULL) { | |
797 » goto loser; | |
798 » } | |
799 » paramData = (unsigned char *)pbeV2_params; | |
800 » paramLen = sizeof(CK_PKCS5_PBKD2_PARAMS); | |
801 | |
802 » /* set the prf */ | |
803 » prfAlgTag = SEC_OID_HMAC_SHA1; | |
804 » if (p5_param.pPrfAlgId && | |
805 » p5_param.pPrfAlgId->algorithm.data != 0) { | |
806 » prfAlgTag = SECOID_GetAlgorithmTag(p5_param.pPrfAlgId); | |
807 » } | |
808 » if (prfAlgTag == SEC_OID_HMAC_SHA1) { | |
809 » pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1; | |
810 » } else { | |
811 » /* only SHA1_HMAC is currently supported by PKCS #11 */ | |
812 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | |
813 » goto loser; | |
814 » } | |
815 »······· | |
816 » /* probably should fetch these from the prfAlgid */ | |
817 » pbeV2_params->pPrfData = NULL; | |
818 » pbeV2_params->ulPrfDataLen = 0; | |
819 » pbeV2_params->saltSource = CKZ_SALT_SPECIFIED; | |
820 » pSalt = ((CK_CHAR_PTR) pbeV2_params)+sizeof(CK_PKCS5_PBKD2_PARAMS); | |
821 PORT_Memcpy(pSalt, salt->data, salt->len); | |
822 » pbeV2_params->pSaltSourceData = pSalt; | |
823 » pbeV2_params->ulSaltSourceDataLen = salt->len; | |
824 » pbeV2_params->iterations = iterations; | |
825 } else { | |
826 » CK_PBE_PARAMS *pbe_params = NULL; | |
827 » pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)+ | |
828 » » » » » » salt->len+iv_len); | |
829 » if (pbe_params == NULL) { | |
830 » goto loser; | |
831 » } | |
832 » paramData = (unsigned char *)pbe_params; | |
833 » paramLen = sizeof(CK_PBE_PARAMS); | |
834 | |
835 » pSalt = ((CK_CHAR_PTR) pbe_params)+sizeof(CK_PBE_PARAMS); | |
836 » pbe_params->pSalt = pSalt; | |
837 PORT_Memcpy(pSalt, salt->data, salt->len); | |
838 » pbe_params->ulSaltLen = salt->len; | |
839 » if (iv_len) { | |
840 » pbe_params->pInitVector =· | |
841 » » ((CK_CHAR_PTR) pbe_params)+ sizeof(CK_PBE_PARAMS)+salt->len; | |
842 » } | |
843 » pbe_params->ulIteration = iterations; | |
844 } | |
845 | |
846 /* copy into the mechanism sec item */ | |
847 mech->data = paramData; | |
848 mech->len = paramLen; | |
849 if (arena) { | |
850 » PORT_FreeArena(arena,PR_TRUE); | |
851 } | |
852 return SECSuccess; | |
853 | |
854 loser: | |
855 if (paramData) { | |
856 » PORT_Free(paramData); | |
857 } | |
858 if (arena) { | |
859 » PORT_FreeArena(arena,PR_TRUE); | |
860 } | |
861 return SECFailure; | |
862 } | |
863 | |
864 /* | |
865 * public, deprecated, not valid for pkcs5 v2· | |
866 *· | |
867 * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create | 797 * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create |
868 * PBE algorithmID's directly. | 798 * PBE algorithmID's directly. |
869 */ | 799 */ |
870 SECStatus | 800 SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, |
871 PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PLArenaPool *arena, | 801 PLArenaPool *arena, SECAlgorithmID *algId) { |
872 » » SECAlgorithmID *algId) | 802 CK_PBE_PARAMS *pbe_param; |
873 { | 803 SECItem pbeSalt; |
874 CK_PBE_PARAMS *pbe_param; | 804 SECAlgorithmID *pbeAlgID = NULL; |
875 SECItem pbeSalt; | 805 SECStatus rv; |
876 SECAlgorithmID *pbeAlgID = NULL; | 806 |
877 SECStatus rv; | 807 if (!param || !algId) { |
878 | 808 return SECFailure; |
879 if(!param || !algId) { | 809 } |
880 » return SECFailure; | 810 |
881 } | 811 pbe_param = (CK_PBE_PARAMS *)param->data; |
882 | 812 pbeSalt.data = (unsigned char *)pbe_param->pSalt; |
883 pbe_param = (CK_PBE_PARAMS *)param->data; | 813 pbeSalt.len = pbe_param->ulSaltLen; |
884 pbeSalt.data = (unsigned char *)pbe_param->pSalt; | 814 pbeAlgID = |
885 pbeSalt.len = pbe_param->ulSaltLen; | 815 sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL, |
886 pbeAlgID = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, | 816 0, &pbeSalt, (int)pbe_param->ulIteration); |
887 » SEC_OID_UNKNOWN, NULL, 0, &pbeSalt, (int)pbe_param->ulIteration); | 817 if (!pbeAlgID) { |
888 if(!pbeAlgID) { | 818 return SECFailure; |
889 » return SECFailure; | 819 } |
890 } | 820 |
891 | 821 rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID); |
892 rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID); | 822 SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE); |
893 SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE); | 823 return rv; |
894 return rv; | 824 } |
895 } | 825 |
896 | 826 /* |
897 /* | 827 * public, Deprecated, This function is only for binary compatibility with |
898 * public, Deprecated, This function is only for binary compatibility with· | |
899 * older applications. Does not support PKCS5v2. | 828 * older applications. Does not support PKCS5v2. |
900 * | 829 * |
901 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for | 830 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for |
902 * iv values rather than generating PBE bits directly. | 831 * iv values rather than generating PBE bits directly. |
903 */ | 832 */ |
904 PBEBitGenContext * | 833 PBEBitGenContext *PBE_CreateContext(SECOidTag hashAlgorithm, |
905 PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, | 834 PBEBitGenID bitGenPurpose, SECItem *pwitem, |
906 » SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, | 835 SECItem *salt, unsigned int bitsNeeded, |
907 » unsigned int iterations) | 836 unsigned int iterations) { |
908 { | 837 SECItem *context = NULL; |
909 SECItem *context = NULL; | 838 SECItem mechItem; |
910 SECItem mechItem; | 839 CK_PBE_PARAMS pbe_params; |
911 CK_PBE_PARAMS pbe_params; | 840 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
912 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 841 PK11SlotInfo *slot; |
913 PK11SlotInfo *slot; | 842 PK11SymKey *symKey = NULL; |
914 PK11SymKey *symKey = NULL; | 843 unsigned char ivData[8]; |
915 unsigned char ivData[8]; | 844 |
916 ···· | 845 /* use the purpose to select the low level keygen algorithm */ |
917 | 846 switch (bitGenPurpose) { |
918 /* use the purpose to select the low level keygen algorithm */ | |
919 switch (bitGenPurpose) { | |
920 case pbeBitGenIntegrityKey: | 847 case pbeBitGenIntegrityKey: |
921 » switch (hashAlgorithm) { | 848 switch (hashAlgorithm) { |
922 » case SEC_OID_SHA1: | 849 case SEC_OID_SHA1: |
923 » mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC; | 850 mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC; |
924 » break; | 851 break; |
925 » case SEC_OID_MD2: | 852 case SEC_OID_MD2: |
926 » mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; | 853 mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; |
927 » break; | 854 break; |
928 » case SEC_OID_MD5: | 855 case SEC_OID_MD5: |
929 » mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; | 856 mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; |
930 » break; | 857 break; |
931 » default: | 858 default: |
932 » break; | 859 break; |
933 » } | 860 } |
934 » break; | 861 break; |
935 case pbeBitGenCipherIV: | 862 case pbeBitGenCipherIV: |
936 » if (bitsNeeded > 64) { | 863 if (bitsNeeded > 64) { |
937 » break; | 864 break; |
938 » } | 865 } |
939 » if (hashAlgorithm != SEC_OID_SHA1) { | 866 if (hashAlgorithm != SEC_OID_SHA1) { |
940 » break; | 867 break; |
941 » } | 868 } |
942 » mechanism = CKM_PBE_SHA1_DES3_EDE_CBC; | 869 mechanism = CKM_PBE_SHA1_DES3_EDE_CBC; |
943 » break; | 870 break; |
944 case pbeBitGenCipherKey: | 871 case pbeBitGenCipherKey: |
945 » if (hashAlgorithm != SEC_OID_SHA1) { | 872 if (hashAlgorithm != SEC_OID_SHA1) { |
946 » break; | 873 break; |
947 » } | 874 } |
948 » switch (bitsNeeded) { | 875 switch (bitsNeeded) { |
949 » case 40: | 876 case 40: |
950 » mechanism = CKM_PBE_SHA1_RC4_40; | 877 mechanism = CKM_PBE_SHA1_RC4_40; |
951 » break; | 878 break; |
952 » case 128: | 879 case 128: |
953 » mechanism = CKM_PBE_SHA1_RC4_128; | 880 mechanism = CKM_PBE_SHA1_RC4_128; |
954 » break; | 881 break; |
955 » default: | 882 default: |
956 » break; | 883 break; |
957 » } | 884 } |
958 case pbeBitGenIDNull: | 885 case pbeBitGenIDNull: |
959 » break; | 886 break; |
960 } | 887 } |
961 | 888 |
962 if (mechanism == CKM_INVALID_MECHANISM) { | 889 if (mechanism == CKM_INVALID_MECHANISM) { |
963 » /* we should set an error, but this is a deprecated function, and | 890 /* we should set an error, but this is a deprecated function, and |
964 » * we are keeping bug for bug compatibility;)... */ | 891 * we are keeping bug for bug compatibility;)... */ |
965 » return NULL; | 892 return NULL; |
966 }· | 893 } |
967 | 894 |
968 pbe_params.pInitVector = ivData; | 895 pbe_params.pInitVector = ivData; |
969 pbe_params.pPassword = pwitem->data; | 896 pbe_params.pPassword = pwitem->data; |
970 pbe_params.ulPasswordLen = pwitem->len; | 897 pbe_params.ulPasswordLen = pwitem->len; |
971 pbe_params.pSalt = salt->data; | 898 pbe_params.pSalt = salt->data; |
972 pbe_params.ulSaltLen = salt->len; | 899 pbe_params.ulSaltLen = salt->len; |
973 pbe_params.ulIteration = iterations; | 900 pbe_params.ulIteration = iterations; |
974 mechItem.data = (unsigned char *) &pbe_params; | 901 mechItem.data = (unsigned char *)&pbe_params; |
975 mechItem.len = sizeof(pbe_params); | 902 mechItem.len = sizeof(pbe_params); |
976 | 903 |
977 | 904 slot = PK11_GetInternalSlot(); |
978 slot = PK11_GetInternalSlot(); | 905 symKey = |
979 symKey = PK11_RawPBEKeyGen(slot,mechanism, | 906 PK11_RawPBEKeyGen(slot, mechanism, &mechItem, pwitem, PR_FALSE, NULL); |
980 » » » » » &mechItem, pwitem, PR_FALSE, NULL); | 907 PK11_FreeSlot(slot); |
981 PK11_FreeSlot(slot); | 908 if (symKey != NULL) { |
982 if (symKey != NULL) { | 909 if (bitGenPurpose == pbeBitGenCipherIV) { |
983 » if (bitGenPurpose == pbeBitGenCipherIV) { | 910 /* NOTE: this assumes that bitsNeeded is a multiple of 8! */ |
984 » /* NOTE: this assumes that bitsNeeded is a multiple of 8! */ | 911 SECItem ivItem; |
985 » SECItem ivItem; | 912 |
986 | 913 ivItem.data = ivData; |
987 » ivItem.data = ivData; | 914 ivItem.len = bitsNeeded / 8; |
988 » ivItem.len = bitsNeeded/8; | 915 context = SECITEM_DupItem(&ivItem); |
989 » context = SECITEM_DupItem(&ivItem); | 916 } else { |
990 » } else { | 917 SECItem *keyData; |
991 » SECItem *keyData; | 918 PK11_ExtractKeyValue(symKey); |
992 » PK11_ExtractKeyValue(symKey); | 919 keyData = PK11_GetKeyData(symKey); |
993 » keyData = PK11_GetKeyData(symKey); | 920 |
994 | 921 /* assert bitsNeeded with length? */ |
995 » /* assert bitsNeeded with length? */ | 922 if (keyData) { |
996 » if (keyData) { | 923 context = SECITEM_DupItem(keyData); |
997 » » context = SECITEM_DupItem(keyData); | 924 } |
998 » } | 925 } |
999 » } | 926 PK11_FreeSymKey(symKey); |
1000 » PK11_FreeSymKey(symKey); | 927 } |
1001 } | 928 |
1002 | 929 return (PBEBitGenContext *)context; |
1003 return (PBEBitGenContext *)context; | 930 } |
1004 } | 931 |
1005 | 932 /* |
1006 /* | 933 * public, Deprecated, This function is only for binary compatibility with |
1007 * public, Deprecated, This function is only for binary compatibility with· | |
1008 * older applications. Does not support PKCS5v2. | 934 * older applications. Does not support PKCS5v2. |
1009 * | 935 * |
1010 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for | 936 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for |
1011 * iv values rather than generating PBE bits directly. | 937 * iv values rather than generating PBE bits directly. |
1012 */ | 938 */ |
1013 SECItem * | 939 SECItem *PBE_GenerateBits(PBEBitGenContext *context) { |
1014 PBE_GenerateBits(PBEBitGenContext *context) | 940 return (SECItem *)context; |
1015 { | 941 } |
1016 return (SECItem *)context; | 942 |
1017 } | 943 /* |
1018 | 944 * public, Deprecated, This function is only for binary compatibility with |
1019 /* | |
1020 * public, Deprecated, This function is only for binary compatibility with | |
1021 * older applications. Does not support PKCS5v2. | 945 * older applications. Does not support PKCS5v2. |
1022 * | 946 * |
1023 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for | 947 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for |
1024 * iv values rather than generating PBE bits directly. | 948 * iv values rather than generating PBE bits directly. |
1025 */ | 949 */ |
1026 void | 950 void PBE_DestroyContext(PBEBitGenContext *context) { |
1027 PBE_DestroyContext(PBEBitGenContext *context) | 951 SECITEM_FreeItem((SECItem *)context, PR_TRUE); |
1028 { | |
1029 SECITEM_FreeItem((SECItem *)context,PR_TRUE); | |
1030 } | 952 } |
1031 | 953 |
1032 /* | 954 /* |
1033 * public, deprecated. Replaced with PK11_GetPBEIV(). | 955 * public, deprecated. Replaced with PK11_GetPBEIV(). |
1034 */ | 956 */ |
1035 SECItem * | 957 SECItem *SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, |
1036 SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES) | 958 PRBool faulty3DES) { |
1037 { | 959 /* pbe stuff */ |
1038 /* pbe stuff */ | 960 CK_MECHANISM_TYPE type; |
1039 CK_MECHANISM_TYPE type; | 961 SECItem *param = NULL; |
1040 SECItem *param = NULL; | 962 SECItem *iv = NULL; |
1041 SECItem *iv = NULL; | 963 SECItem src; |
1042 SECItem src; | 964 int iv_len = 0; |
1043 int iv_len = 0; | 965 PK11SymKey *symKey; |
1044 PK11SymKey *symKey; | 966 PK11SlotInfo *slot; |
1045 PK11SlotInfo *slot; | 967 CK_PBE_PARAMS_PTR pPBEparams; |
1046 CK_PBE_PARAMS_PTR pPBEparams; | 968 SECOidTag pbeAlg; |
1047 SECOidTag» pbeAlg; | 969 |
1048 | 970 pbeAlg = SECOID_GetAlgorithmTag(algid); |
1049 pbeAlg = SECOID_GetAlgorithmTag(algid); | 971 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { |
1050 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { | 972 unsigned char *ivData; |
1051 » unsigned char *ivData; | 973 sec_pkcs5V2Parameter *pbeV2_param = NULL; |
1052 » sec_pkcs5V2Parameter *pbeV2_param = NULL; | 974 |
1053 | 975 /* can only return the IV if the crypto Algorithm exists */ |
1054 » /* can only return the IV if the crypto Algorithm exists */ | 976 if (pbeAlg == SEC_OID_PKCS5_PBKDF2) { |
1055 » if (pbeAlg == SEC_OID_PKCS5_PBKDF2) { | 977 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
1056 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 978 goto loser; |
1057 » goto loser; | 979 } |
1058 » } | 980 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); |
1059 » pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); | 981 if (pbeV2_param == NULL) { |
1060 » if (pbeV2_param == NULL) { | 982 goto loser; |
1061 » goto loser; | 983 } |
1062 » } | 984 /* extract the IV from the cipher algid portion of our pkcs 5 v2 |
1063 » /* extract the IV from the cipher algid portion of our pkcs 5 v2 | 985 * algorithm id */ |
1064 » * algorithm id */ | 986 type = PK11_AlgtagToMechanism( |
1065 » type = PK11_AlgtagToMechanism( | 987 SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); |
1066 » » SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); | 988 param = PK11_ParamFromAlgid(&pbeV2_param->cipherAlgId); |
1067 » param = PK11_ParamFromAlgid(&pbeV2_param->cipherAlgId); | 989 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); |
1068 » sec_pkcs5_v2_destroy_v2_param(pbeV2_param); | 990 if (!param) { |
1069 » if (!param) { | 991 goto loser; |
1070 » goto loser; | 992 } |
1071 » } | 993 /* NOTE: NULL is a permissible return here */ |
1072 » /* NOTE: NULL is a permissible return here */ | 994 ivData = PK11_IVFromParam(type, param, &iv_len); |
1073 » ivData = PK11_IVFromParam(type, param, &iv_len); | 995 src.data = ivData; |
1074 » src.data = ivData; | |
1075 » src.len = iv_len; | |
1076 » goto done; | |
1077 } | |
1078 | |
1079 type = PK11_AlgtagToMechanism(pbeAlg); | |
1080 param = PK11_ParamFromAlgid(algid); | |
1081 if (param == NULL) { | |
1082 » goto done; | |
1083 } | |
1084 slot = PK11_GetInternalSlot(); | |
1085 symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL); | |
1086 PK11_FreeSlot(slot); | |
1087 if (symKey == NULL) { | |
1088 » goto loser; | |
1089 } | |
1090 PK11_FreeSymKey(symKey); | |
1091 pPBEparams = (CK_PBE_PARAMS_PTR)param->data; | |
1092 iv_len = PK11_GetIVLength(type); | |
1093 | |
1094 src.data = (unsigned char *)pPBEparams->pInitVector; | |
1095 src.len = iv_len; | 996 src.len = iv_len; |
| 997 goto done; |
| 998 } |
| 999 |
| 1000 type = PK11_AlgtagToMechanism(pbeAlg); |
| 1001 param = PK11_ParamFromAlgid(algid); |
| 1002 if (param == NULL) { |
| 1003 goto done; |
| 1004 } |
| 1005 slot = PK11_GetInternalSlot(); |
| 1006 symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL); |
| 1007 PK11_FreeSlot(slot); |
| 1008 if (symKey == NULL) { |
| 1009 goto loser; |
| 1010 } |
| 1011 PK11_FreeSymKey(symKey); |
| 1012 pPBEparams = (CK_PBE_PARAMS_PTR)param->data; |
| 1013 iv_len = PK11_GetIVLength(type); |
| 1014 |
| 1015 src.data = (unsigned char *)pPBEparams->pInitVector; |
| 1016 src.len = iv_len; |
1096 | 1017 |
1097 done: | 1018 done: |
1098 iv = SECITEM_DupItem(&src); | 1019 iv = SECITEM_DupItem(&src); |
1099 | 1020 |
1100 loser: | 1021 loser: |
1101 if (param) { | 1022 if (param) { |
1102 » SECITEM_ZfreeItem(param, PR_TRUE); | 1023 SECITEM_ZfreeItem(param, PR_TRUE); |
1103 } | 1024 } |
1104 return iv; | 1025 return iv; |
1105 } | 1026 } |
1106 | 1027 |
1107 /* | 1028 /* |
1108 * Subs from nss 3.x that are deprecated | 1029 * Subs from nss 3.x that are deprecated |
1109 */ | 1030 */ |
1110 PBEBitGenContext * | 1031 PBEBitGenContext *__PBE_CreateContext(SECOidTag hashAlgorithm, |
1111 __PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, | 1032 PBEBitGenID bitGenPurpose, |
1112 » SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, | 1033 SECItem *pwitem, SECItem *salt, |
1113 » unsigned int iterations) | 1034 unsigned int bitsNeeded, |
1114 { | 1035 unsigned int iterations) { |
1115 PORT_Assert("__PBE_CreateContext is Deprecated" == NULL); | 1036 PORT_Assert("__PBE_CreateContext is Deprecated" == NULL); |
1116 return NULL; | 1037 return NULL; |
1117 } | 1038 } |
1118 | 1039 |
1119 SECItem * | 1040 SECItem *__PBE_GenerateBits(PBEBitGenContext *context) { |
1120 __PBE_GenerateBits(PBEBitGenContext *context) | 1041 PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL); |
1121 { | 1042 return NULL; |
1122 PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL); | 1043 } |
1123 return NULL; | 1044 |
1124 } | 1045 void __PBE_DestroyContext(PBEBitGenContext *context) { |
1125 | 1046 PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL); |
1126 void | 1047 } |
1127 __PBE_DestroyContext(PBEBitGenContext *context) | 1048 |
1128 { | 1049 SECStatus RSA_FormatBlock(SECItem *result, unsigned modulusLen, int blockType, |
1129 PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL); | 1050 SECItem *data) { |
1130 } | 1051 PORT_Assert("RSA_FormatBlock is Deprecated" == NULL); |
1131 | 1052 return SECFailure; |
1132 SECStatus | |
1133 RSA_FormatBlock(SECItem *result, unsigned modulusLen, | |
1134 int blockType, SECItem *data) | |
1135 { | |
1136 PORT_Assert("RSA_FormatBlock is Deprecated" == NULL); | |
1137 return SECFailure; | |
1138 } | 1053 } |
1139 | 1054 |
1140 /**************************************************************************** | 1055 /**************************************************************************** |
1141 * | 1056 * |
1142 * Now Do The PBE Functions Here... | 1057 * Now Do The PBE Functions Here... |
1143 * | 1058 * |
1144 ****************************************************************************/ | 1059 ****************************************************************************/ |
1145 | 1060 |
1146 static void | 1061 static void pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) { |
1147 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) | 1062 if (pbe_params) { |
1148 { | 1063 if (pbe_params->pPassword) |
1149 if (pbe_params) { | 1064 PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); |
1150 » if (pbe_params->pPassword) | 1065 if (pbe_params->pSalt) PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); |
1151 » PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); | 1066 PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); |
1152 » if (pbe_params->pSalt) | 1067 } |
1153 » PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); | 1068 } |
1154 » PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); | 1069 |
1155 } | 1070 /* |
1156 } | 1071 * public, deprecated. use PK11_CreatePBEAlgorithmID or |
1157 | 1072 * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters, |
1158 /* | 1073 * use PK11_ParamFromAlgid from the algorithm id you created using |
1159 * public, deprecated. use PK11_CreatePBEAlgorithmID or | |
1160 * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters, | |
1161 * use PK11_ParamFromAlgid from the algorithm id you created using· | |
1162 * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID. | 1074 * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID. |
1163 */ | 1075 */ |
1164 SECItem *· | 1076 SECItem *PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, |
1165 PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) | 1077 unsigned int iterations) { |
1166 { | 1078 CK_PBE_PARAMS *pbe_params = NULL; |
1167 CK_PBE_PARAMS *pbe_params = NULL; | 1079 SECItem *paramRV = NULL; |
1168 SECItem *paramRV = NULL; | 1080 |
1169 | 1081 paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); |
1170 paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); | 1082 if (!paramRV) { |
1171 if (!paramRV ) { | 1083 goto loser; |
1172 » goto loser; | 1084 } |
1173 } | 1085 /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ |
1174 /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ | 1086 PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); |
1175 PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); | 1087 |
1176 | 1088 pbe_params = (CK_PBE_PARAMS *)paramRV->data; |
1177 pbe_params = (CK_PBE_PARAMS *)paramRV->data; | 1089 pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); |
1178 pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); | 1090 if (!pbe_params->pPassword) { |
1179 if (!pbe_params->pPassword) { | 1091 goto loser; |
1180 goto loser; | 1092 } |
1181 } | 1093 PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); |
1182 PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); | 1094 pbe_params->ulPasswordLen = pwd->len; |
1183 pbe_params->ulPasswordLen = pwd->len; | 1095 |
1184 | 1096 pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); |
1185 pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); | 1097 if (!pbe_params->pSalt) { |
1186 if (!pbe_params->pSalt) { | 1098 goto loser; |
1187 » goto loser; | 1099 } |
1188 } | 1100 PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); |
1189 PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); | 1101 pbe_params->ulSaltLen = salt->len; |
1190 pbe_params->ulSaltLen = salt->len; | 1102 |
1191 | 1103 pbe_params->ulIteration = (CK_ULONG)iterations; |
1192 pbe_params->ulIteration = (CK_ULONG)iterations; | 1104 return paramRV; |
1193 return paramRV; | |
1194 | 1105 |
1195 loser: | 1106 loser: |
1196 if (pbe_params) | 1107 if (pbe_params) pk11_destroy_ck_pbe_params(pbe_params); |
1197 pk11_destroy_ck_pbe_params(pbe_params); | 1108 if (paramRV) PORT_ZFree(paramRV, sizeof(SECItem)); |
1198 if (paramRV) | 1109 return NULL; |
1199 » PORT_ZFree(paramRV, sizeof(SECItem)); | |
1200 return NULL; | |
1201 } | 1110 } |
1202 | 1111 |
1203 /* | 1112 /* |
1204 * public, deprecated. | 1113 * public, deprecated. |
1205 */ | 1114 */ |
1206 void | 1115 void PK11_DestroyPBEParams(SECItem *pItem) { |
1207 PK11_DestroyPBEParams(SECItem *pItem) | 1116 if (pItem) { |
1208 { | 1117 CK_PBE_PARAMS *params = (CK_PBE_PARAMS *)(pItem->data); |
1209 if (pItem) { | 1118 if (params) pk11_destroy_ck_pbe_params(params); |
1210 » CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data); | 1119 PORT_ZFree(pItem, sizeof(SECItem)); |
1211 » if (params) | 1120 } |
1212 » pk11_destroy_ck_pbe_params(params); | |
1213 » PORT_ZFree(pItem, sizeof(SECItem)); | |
1214 } | |
1215 } | 1121 } |
1216 | 1122 |
1217 /* | 1123 /* |
1218 * public, Partially supports PKCS5 V2 (some parameters are not controllable | 1124 * public, Partially supports PKCS5 V2 (some parameters are not controllable |
1219 * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need | 1125 * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need |
1220 * finer control these. | 1126 * finer control these. |
1221 */ | 1127 */ |
1222 SECAlgorithmID * | 1128 SECAlgorithmID *PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, |
1223 PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt) | 1129 SECItem *salt) { |
1224 { | 1130 SECAlgorithmID *algid = NULL; |
1225 SECAlgorithmID *algid = NULL; | 1131 algid = sec_pkcs5CreateAlgorithmID(algorithm, SEC_OID_UNKNOWN, |
1226 algid = sec_pkcs5CreateAlgorithmID(algorithm, | 1132 SEC_OID_UNKNOWN, NULL, 0, salt, iteration); |
1227 » » SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL, 0, salt, iteration); | 1133 return algid; |
1228 return algid; | |
1229 } | 1134 } |
1230 | 1135 |
1231 /* | 1136 /* |
1232 * public, fully support pkcs5v2. | 1137 * public, fully support pkcs5v2. |
1233 */ | 1138 */ |
1234 SECAlgorithmID * | 1139 SECAlgorithmID *PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, |
1235 PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag, | 1140 SECOidTag cipherAlgTag, |
1236 » » » SECOidTag prfAlgTag, int keyLength, int iteration,· | 1141 SECOidTag prfAlgTag, int keyLength, |
1237 » » » SECItem *salt) | 1142 int iteration, SECItem *salt) { |
1238 { | 1143 SECAlgorithmID *algid = NULL; |
1239 SECAlgorithmID *algid = NULL; | 1144 algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag, NULL, |
1240 algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag, | 1145 keyLength, salt, iteration); |
1241 » » » » » NULL, keyLength, salt, iteration); | 1146 return algid; |
1242 return algid; | |
1243 } | 1147 } |
1244 | 1148 |
1245 /* | 1149 /* |
1246 * private. | 1150 * private. |
1247 */ | 1151 */ |
1248 PK11SymKey * | 1152 PK11SymKey *pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, |
1249 pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,· | 1153 CK_MECHANISM_TYPE type, |
1250 » » » SECItem *params, CK_KEY_TYPE keyType, int keyLen, | 1154 SECItem *params, CK_KEY_TYPE keyType, |
1251 » » » SECItem *pwitem, void *wincx) | 1155 int keyLen, SECItem *pwitem, |
1252 { | 1156 void *wincx) { |
1253 CK_ULONG pwLen; | 1157 CK_ULONG pwLen; |
1254 /* do some sanity checks */ | 1158 /* do some sanity checks */ |
1255 if ((params == NULL) || (params->data == NULL)) { | 1159 if ((params == NULL) || (params->data == NULL)) { |
1256 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1160 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1257 » return NULL; | 1161 return NULL; |
1258 } | 1162 } |
1259 | 1163 |
1260 if (type == CKM_INVALID_MECHANISM) { | 1164 if (type == CKM_INVALID_MECHANISM) { |
1261 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 1165 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
1262 » return NULL; | 1166 return NULL; |
1263 } | 1167 } |
1264 | 1168 |
1265 /* set the password pointer in the parameters... */ | 1169 /* set the password pointer in the parameters... */ |
1266 if (type == CKM_PKCS5_PBKD2) { | 1170 if (type == CKM_PKCS5_PBKD2) { |
1267 » CK_PKCS5_PBKD2_PARAMS *pbev2_params; | 1171 CK_PKCS5_PBKD2_PARAMS *pbev2_params; |
1268 » if (params->len < sizeof(CK_PKCS5_PBKD2_PARAMS)) { | 1172 if (params->len < sizeof(CK_PKCS5_PBKD2_PARAMS)) { |
1269 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1173 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1270 » return NULL; | 1174 return NULL; |
1271 » } | 1175 } |
1272 » pbev2_params = (CK_PKCS5_PBKD2_PARAMS *)params->data; | 1176 pbev2_params = (CK_PKCS5_PBKD2_PARAMS *)params->data; |
1273 » pbev2_params->pPassword = pwitem->data; | 1177 pbev2_params->pPassword = pwitem->data; |
1274 » pwLen = pwitem->len; | 1178 pwLen = pwitem->len; |
1275 » pbev2_params->ulPasswordLen = &pwLen; | 1179 pbev2_params->ulPasswordLen = &pwLen; |
1276 } else { | 1180 } else { |
1277 » CK_PBE_PARAMS *pbe_params; | 1181 CK_PBE_PARAMS *pbe_params; |
1278 » if (params->len < sizeof(CK_PBE_PARAMS)) { | 1182 if (params->len < sizeof(CK_PBE_PARAMS)) { |
1279 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 1183 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1280 » return NULL; | 1184 return NULL; |
1281 » } | 1185 } |
1282 » pbe_params = (CK_PBE_PARAMS *)params->data; | 1186 pbe_params = (CK_PBE_PARAMS *)params->data; |
1283 » pbe_params->pPassword = pwitem->data; | 1187 pbe_params->pPassword = pwitem->data; |
1284 » pbe_params->ulPasswordLen = pwitem->len; | 1188 pbe_params->ulPasswordLen = pwitem->len; |
1285 } | 1189 } |
1286 | 1190 |
1287 /* generate the key (and sometimes the IV as a side effect...) */ | 1191 /* generate the key (and sometimes the IV as a side effect...) */ |
1288 return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType, | 1192 return pk11_TokenKeyGenWithFlagsAndKeyType( |
1289 » keyLen, NULL, CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP, | 1193 slot, type, params, keyType, keyLen, NULL, |
1290 » 0, wincx); | 1194 CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | CKF_UNWRAP | CKF_WRAP, 0, wincx); |
1291 } | 1195 } |
1292 | 1196 |
1293 /* | 1197 /* |
1294 * public, deprecated. use PK11_PBEKeyGen instead. | 1198 * public, deprecated. use PK11_PBEKeyGen instead. |
1295 */ | 1199 */ |
1296 PK11SymKey * | 1200 PK11SymKey *PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, |
1297 PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, | 1201 SECItem *mech, SECItem *pwitem, PRBool faulty3DES, |
1298 » » » SECItem *pwitem, PRBool faulty3DES, void *wincx) | 1202 void *wincx) { |
1299 { | 1203 if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { |
1300 if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { | 1204 type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; |
1301 » type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; | 1205 } |
1302 } | 1206 return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx); |
1303 return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx); | |
1304 } | 1207 } |
1305 | 1208 |
1306 /* | 1209 /* |
1307 * pubic, supports pkcs5 v2. | 1210 * pubic, supports pkcs5 v2. |
1308 * | 1211 * |
1309 * Create symkey from a PBE key. The algid can be created with | 1212 * Create symkey from a PBE key. The algid can be created with |
1310 * PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by | 1213 * PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by |
1311 * extraction of der data. | 1214 * extraction of der data. |
1312 */ | 1215 */ |
1313 PK11SymKey * | 1216 PK11SymKey *PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, |
1314 PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem, | 1217 SECItem *pwitem, PRBool faulty3DES, void *wincx) { |
1315 » »» » » » PRBool faulty3DES, void *wincx) | 1218 CK_MECHANISM_TYPE type; |
1316 { | 1219 SECItem *param = NULL; |
1317 CK_MECHANISM_TYPE type; | 1220 PK11SymKey *symKey = NULL; |
1318 SECItem *param = NULL; | 1221 SECOidTag pbeAlg; |
1319 PK11SymKey *symKey = NULL; | 1222 CK_KEY_TYPE keyType = -1; |
1320 SECOidTag» pbeAlg; | 1223 int keyLen = 0; |
1321 CK_KEY_TYPE keyType = -1; | 1224 |
1322 int keyLen = 0; | 1225 pbeAlg = SECOID_GetAlgorithmTag(algid); |
1323 | 1226 /* if we're using PKCS5v2, extract the additional information we need |
1324 pbeAlg = SECOID_GetAlgorithmTag(algid); | 1227 * (key length, key type, and pbeAlg). */ |
1325 /* if we're using PKCS5v2, extract the additional information we need | 1228 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { |
1326 * (key length, key type, and pbeAlg). */ | 1229 CK_MECHANISM_TYPE cipherMech; |
1327 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { | 1230 sec_pkcs5V2Parameter *pbeV2_param; |
1328 » CK_MECHANISM_TYPE cipherMech; | 1231 |
1329 » sec_pkcs5V2Parameter *pbeV2_param; | 1232 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); |
1330 | 1233 if (pbeV2_param == NULL) { |
1331 » pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); | 1234 return NULL; |
1332 » if (pbeV2_param == NULL) { | 1235 } |
1333 » return NULL; | 1236 cipherMech = PK11_AlgtagToMechanism( |
1334 » } | 1237 SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); |
1335 » cipherMech = PK11_AlgtagToMechanism( | 1238 pbeAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId); |
1336 » » SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); | 1239 param = PK11_ParamFromAlgid(&pbeV2_param->pbeAlgId); |
1337 » pbeAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId); | 1240 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); |
1338 » param = PK11_ParamFromAlgid(&pbeV2_param->pbeAlgId); | 1241 keyLen = SEC_PKCS5GetKeyLength(algid); |
1339 » sec_pkcs5_v2_destroy_v2_param(pbeV2_param); | 1242 if (keyLen == -1) { |
1340 » keyLen = SEC_PKCS5GetKeyLength(algid); | 1243 keyLen = 0; |
1341 » if (keyLen == -1) { | 1244 } |
1342 » keyLen = 0; | 1245 keyType = PK11_GetKeyType(cipherMech, keyLen); |
1343 » } | 1246 } else { |
1344 » keyType = PK11_GetKeyType(cipherMech, keyLen); | 1247 param = PK11_ParamFromAlgid(algid); |
1345 } else { | 1248 } |
1346 » param = PK11_ParamFromAlgid(algid); | 1249 |
1347 } | 1250 if (param == NULL) { |
1348 | 1251 goto loser; |
1349 if(param == NULL) { | 1252 } |
1350 » goto loser; | 1253 |
1351 } | 1254 type = PK11_AlgtagToMechanism(pbeAlg); |
1352 | 1255 if (type == CKM_INVALID_MECHANISM) { |
1353 type = PK11_AlgtagToMechanism(pbeAlg);»····· | 1256 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
1354 if (type == CKM_INVALID_MECHANISM) { | 1257 goto loser; |
1355 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 1258 } |
1356 » goto loser; | 1259 if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { |
1357 } | 1260 type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; |
1358 if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { | 1261 } |
1359 » type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; | 1262 symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen, |
1360 } | 1263 pwitem, wincx); |
1361 symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen,· | |
1362 » » » » » pwitem, wincx); | |
1363 | 1264 |
1364 loser: | 1265 loser: |
1365 if (param) { | 1266 if (param) { |
1366 » SECITEM_ZfreeItem(param, PR_TRUE); | 1267 SECITEM_ZfreeItem(param, PR_TRUE); |
1367 } | 1268 } |
1368 return symKey; | 1269 return symKey; |
1369 } | 1270 } |
1370 | 1271 |
1371 /* | 1272 /* |
1372 * public, supports pkcs5v2 | 1273 * public, supports pkcs5v2 |
1373 */ | 1274 */ |
1374 SECItem * | 1275 SECItem *PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem) { |
1375 PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem) | 1276 return SEC_PKCS5GetIV(algid, pwitem, PR_FALSE); |
1376 { | |
1377 return SEC_PKCS5GetIV(algid, pwitem, PR_FALSE); | |
1378 } | 1277 } |
1379 | 1278 |
1380 CK_MECHANISM_TYPE | 1279 CK_MECHANISM_TYPE |
1381 pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,· | 1280 pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, |
1382 » » » SECItem *pbe_pwd, PRBool faulty3DES) | 1281 SECItem *pbe_pwd, PRBool faulty3DES) { |
1383 { | 1282 int keyLen = 0; |
1384 int keyLen = 0; | 1283 SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid); |
1385 SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid); | 1284 CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag); |
1386 CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag); | 1285 CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM; |
1387 CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM; | 1286 SECItem *iv = NULL; |
1388 SECItem *iv = NULL; | 1287 |
1389 | 1288 if (mech == CKM_INVALID_MECHANISM) { |
1390 if (mech == CKM_INVALID_MECHANISM) { | 1289 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
1391 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 1290 goto loser; |
1392 » goto loser; | 1291 } |
1393 } | 1292 if (PK11_GetIVLength(mech)) { |
1394 if (PK11_GetIVLength(mech)) { | 1293 iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES); |
1395 » iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES); | 1294 if (iv == NULL) { |
1396 » if (iv == NULL) { | 1295 goto loser; |
1397 » goto loser; | 1296 } |
1398 » } | 1297 } |
1399 } | 1298 |
1400 | 1299 keyLen = SEC_PKCS5GetKeyLength(algid); |
1401 keyLen = SEC_PKCS5GetKeyLength(algid); | 1300 |
1402 | 1301 *param = pk11_ParamFromIVWithLen(mech, iv, keyLen); |
1403 *param = pk11_ParamFromIVWithLen(mech, iv, keyLen); | 1302 if (*param == NULL) { |
1404 if (*param == NULL) { | 1303 goto loser; |
1405 » goto loser; | 1304 } |
1406 } | 1305 returnedMechanism = mech; |
1407 returnedMechanism = mech; | |
1408 | 1306 |
1409 loser: | 1307 loser: |
1410 if (iv) { | 1308 if (iv) { |
1411 » SECITEM_FreeItem(iv,PR_TRUE); | 1309 SECITEM_FreeItem(iv, PR_TRUE); |
1412 } | 1310 } |
1413 return returnedMechanism; | 1311 return returnedMechanism; |
1414 } | 1312 } |
1415 | 1313 |
1416 /* | 1314 /* |
1417 * Public, supports pkcs5 v2 | 1315 * Public, supports pkcs5 v2 |
1418 * | 1316 * |
1419 * Get the crypto mechanism directly from the pbe algorithmid. | 1317 * Get the crypto mechanism directly from the pbe algorithmid. |
1420 * | 1318 * |
1421 * It's important to go directly from the algorithm id so that we can | 1319 * It's important to go directly from the algorithm id so that we can |
1422 * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases. | 1320 * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases. |
1423 * | 1321 * |
1424 * This function returns both the mechanism and the parameter for the mechanism. | 1322 * This function returns both the mechanism and the parameter for the mechanism. |
1425 * The caller is responsible for freeing the parameter. | 1323 * The caller is responsible for freeing the parameter. |
1426 */ | 1324 */ |
1427 CK_MECHANISM_TYPE | 1325 CK_MECHANISM_TYPE |
1428 PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,· | 1326 PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, |
1429 » » » SECItem *pbe_pwd) | 1327 SECItem *pbe_pwd) { |
1430 { | 1328 return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE); |
1431 return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE); | 1329 } |
1432 } | |
OLD | NEW |