OLD | NEW |
1 /* | 1 /* |
2 * Signature stuff. | 2 * Signature stuff. |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include "cryptohi.h" | 9 #include "cryptohi.h" |
10 #include "sechash.h" | 10 #include "sechash.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 SECStatus rv; | 33 SECStatus rv; |
34 | 34 |
35 /* OK, map a PKCS #7 hash and encrypt algorithm into | 35 /* OK, map a PKCS #7 hash and encrypt algorithm into |
36 * a standard hashing algorithm. Why did we pass in the whole | 36 * a standard hashing algorithm. Why did we pass in the whole |
37 * PKCS #7 algTag if we were just going to change here you might | 37 * PKCS #7 algTag if we were just going to change here you might |
38 * ask. Well the answer is for some cards we may have to do the | 38 * ask. Well the answer is for some cards we may have to do the |
39 * hashing on card. It may not support CKM_RSA_PKCS sign algorithm, | 39 * hashing on card. It may not support CKM_RSA_PKCS sign algorithm, |
40 * it may just support CKM_SHA1_RSA_PKCS and/or CKM_MD5_RSA_PKCS. | 40 * it may just support CKM_SHA1_RSA_PKCS and/or CKM_MD5_RSA_PKCS. |
41 */ | 41 */ |
42 /* we have a private key, not a public key, so don't pass it in */ | 42 /* we have a private key, not a public key, so don't pass it in */ |
43 rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg); | 43 rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg); |
44 if (rv != SECSuccess) { | 44 if (rv != SECSuccess) { |
45 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 45 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
46 » return 0; | 46 return 0; |
47 } | 47 } |
48 keyType = seckey_GetKeyType(signalg); | 48 keyType = seckey_GetKeyType(signalg); |
49 | 49 |
50 /* verify our key type */ | 50 /* verify our key type */ |
51 if (key->keyType != keyType && | 51 if (key->keyType != keyType && |
52 » !((key->keyType == dsaKey) && (keyType == fortezzaKey)) ) { | 52 !((key->keyType == dsaKey) && (keyType == fortezzaKey))) { |
53 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); | 53 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
54 » return 0; | 54 return 0; |
55 } | 55 } |
56 | 56 |
57 cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext)); | 57 cx = (SGNContext *)PORT_ZAlloc(sizeof(SGNContext)); |
58 if (cx) { | 58 if (cx) { |
59 » cx->hashalg = hashalg; | 59 cx->hashalg = hashalg; |
60 » cx->signalg = signalg; | 60 cx->signalg = signalg; |
61 » cx->key = key; | 61 cx->key = key; |
62 } | 62 } |
63 return cx; | 63 return cx; |
64 } | 64 } |
65 | 65 |
66 void | 66 void |
67 SGN_DestroyContext(SGNContext *cx, PRBool freeit) | 67 SGN_DestroyContext(SGNContext *cx, PRBool freeit) |
68 { | 68 { |
69 if (cx) { | 69 if (cx) { |
70 » if (cx->hashcx != NULL) { | 70 if (cx->hashcx != NULL) { |
71 » (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); | 71 (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); |
72 » cx->hashcx = NULL; | 72 cx->hashcx = NULL; |
73 » } | 73 } |
74 » if (freeit) { | 74 if (freeit) { |
75 » PORT_ZFree(cx, sizeof(SGNContext)); | 75 PORT_ZFree(cx, sizeof(SGNContext)); |
76 » } | 76 } |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 SECStatus | 80 SECStatus |
81 SGN_Begin(SGNContext *cx) | 81 SGN_Begin(SGNContext *cx) |
82 { | 82 { |
83 if (cx->hashcx != NULL) { | 83 if (cx->hashcx != NULL) { |
84 » (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); | 84 (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); |
85 » cx->hashcx = NULL; | 85 cx->hashcx = NULL; |
86 } | 86 } |
87 | 87 |
88 cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashalg); | 88 cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashalg); |
89 if (!cx->hashobj) | 89 if (!cx->hashobj) |
90 » return SECFailure;» /* error code is already set */ | 90 return SECFailure; /* error code is already set */ |
91 | 91 |
92 cx->hashcx = (*cx->hashobj->create)(); | 92 cx->hashcx = (*cx->hashobj->create)(); |
93 if (cx->hashcx == NULL) | 93 if (cx->hashcx == NULL) |
94 » return SECFailure; | 94 return SECFailure; |
95 | 95 |
96 (*cx->hashobj->begin)(cx->hashcx); | 96 (*cx->hashobj->begin)(cx->hashcx); |
97 return SECSuccess; | 97 return SECSuccess; |
98 } | 98 } |
99 | 99 |
100 SECStatus | 100 SECStatus |
101 SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen) | 101 SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen) |
102 { | 102 { |
103 if (cx->hashcx == NULL) { | 103 if (cx->hashcx == NULL) { |
104 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 104 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
105 » return SECFailure; | 105 return SECFailure; |
106 } | 106 } |
107 (*cx->hashobj->update)(cx->hashcx, input, inputLen); | 107 (*cx->hashobj->update)(cx->hashcx, input, inputLen); |
108 return SECSuccess; | 108 return SECSuccess; |
109 } | 109 } |
110 | 110 |
111 /* XXX Old template; want to expunge it eventually. */ | 111 /* XXX Old template; want to expunge it eventually. */ |
112 static DERTemplate SECAlgorithmIDTemplate[] = { | 112 static DERTemplate SECAlgorithmIDTemplate[] = { |
113 { DER_SEQUENCE, | 113 { DER_SEQUENCE, |
114 » 0, NULL, sizeof(SECAlgorithmID) }, | 114 0, NULL, sizeof(SECAlgorithmID) }, |
115 { DER_OBJECT_ID, | 115 { DER_OBJECT_ID, |
116 » offsetof(SECAlgorithmID,algorithm), }, | 116 offsetof(SECAlgorithmID, algorithm) }, |
117 { DER_OPTIONAL | DER_ANY, | 117 { DER_OPTIONAL | DER_ANY, |
118 » offsetof(SECAlgorithmID,parameters), }, | 118 offsetof(SECAlgorithmID, parameters) }, |
119 { 0, } | 119 { 0 } |
120 }; | 120 }; |
121 | 121 |
122 /* | 122 /* |
123 * XXX OLD Template. Once all uses have been switched over to new one, | 123 * XXX OLD Template. Once all uses have been switched over to new one, |
124 * remove this. | 124 * remove this. |
125 */ | 125 */ |
126 static DERTemplate SGNDigestInfoTemplate[] = { | 126 static DERTemplate SGNDigestInfoTemplate[] = { |
127 { DER_SEQUENCE, | 127 { DER_SEQUENCE, |
128 » 0, NULL, sizeof(SGNDigestInfo) }, | 128 0, NULL, sizeof(SGNDigestInfo) }, |
129 { DER_INLINE, | 129 { DER_INLINE, |
130 » offsetof(SGNDigestInfo,digestAlgorithm), | 130 offsetof(SGNDigestInfo, digestAlgorithm), |
131 » SECAlgorithmIDTemplate, }, | 131 SECAlgorithmIDTemplate }, |
132 { DER_OCTET_STRING, | 132 { DER_OCTET_STRING, |
133 » offsetof(SGNDigestInfo,digest), }, | 133 offsetof(SGNDigestInfo, digest) }, |
134 { 0, } | 134 { 0 } |
135 }; | 135 }; |
136 | 136 |
137 SECStatus | 137 SECStatus |
138 SGN_End(SGNContext *cx, SECItem *result) | 138 SGN_End(SGNContext *cx, SECItem *result) |
139 { | 139 { |
140 unsigned char digest[HASH_LENGTH_MAX]; | 140 unsigned char digest[HASH_LENGTH_MAX]; |
141 unsigned part1; | 141 unsigned part1; |
142 int signatureLen; | 142 int signatureLen; |
143 SECStatus rv; | 143 SECStatus rv; |
144 SECItem digder, sigitem; | 144 SECItem digder, sigitem; |
145 PLArenaPool *arena = 0; | 145 PLArenaPool *arena = 0; |
146 SECKEYPrivateKey *privKey = cx->key; | 146 SECKEYPrivateKey *privKey = cx->key; |
147 SGNDigestInfo *di = 0; | 147 SGNDigestInfo *di = 0; |
148 | 148 |
149 result->data = 0; | 149 result->data = 0; |
150 digder.data = 0; | 150 digder.data = 0; |
151 | 151 |
152 /* Finish up digest function */ | 152 /* Finish up digest function */ |
153 if (cx->hashcx == NULL) { | 153 if (cx->hashcx == NULL) { |
154 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 154 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
155 » return SECFailure; | 155 return SECFailure; |
156 } | 156 } |
157 (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest)); | 157 (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest)); |
158 | 158 |
159 | |
160 if (privKey->keyType == rsaKey) { | 159 if (privKey->keyType == rsaKey) { |
161 | 160 |
162 » arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 161 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
163 » if ( !arena ) { | 162 if (!arena) { |
164 » rv = SECFailure; | 163 rv = SECFailure; |
165 » goto loser; | 164 goto loser; |
166 » } | 165 } |
167 | |
168 » /* Construct digest info */ | |
169 » di = SGN_CreateDigestInfo(cx->hashalg, digest, part1); | |
170 » if (!di) { | |
171 » rv = SECFailure; | |
172 » goto loser; | |
173 » } | |
174 | 166 |
175 » /* Der encode the digest as a DigestInfo */ | 167 /* Construct digest info */ |
| 168 di = SGN_CreateDigestInfo(cx->hashalg, digest, part1); |
| 169 if (!di) { |
| 170 rv = SECFailure; |
| 171 goto loser; |
| 172 } |
| 173 |
| 174 /* Der encode the digest as a DigestInfo */ |
176 rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, | 175 rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, |
177 di); | 176 di); |
178 » if (rv != SECSuccess) { | 177 if (rv != SECSuccess) { |
179 » goto loser; | 178 goto loser; |
180 » } | 179 } |
181 } else { | 180 } else { |
182 » digder.data = digest; | 181 digder.data = digest; |
183 » digder.len = part1; | 182 digder.len = part1; |
184 } | 183 } |
185 | 184 |
186 /* | 185 /* |
187 ** Encrypt signature after constructing appropriate PKCS#1 signature | 186 ** Encrypt signature after constructing appropriate PKCS#1 signature |
188 ** block | 187 ** block |
189 */ | 188 */ |
190 signatureLen = PK11_SignatureLen(privKey); | 189 signatureLen = PK11_SignatureLen(privKey); |
191 if (signatureLen <= 0) { | 190 if (signatureLen <= 0) { |
192 » PORT_SetError(SEC_ERROR_INVALID_KEY); | 191 PORT_SetError(SEC_ERROR_INVALID_KEY); |
193 » rv = SECFailure; | 192 rv = SECFailure; |
194 » goto loser; | 193 goto loser; |
195 } | 194 } |
196 sigitem.len = signatureLen; | 195 sigitem.len = signatureLen; |
197 sigitem.data = (unsigned char*) PORT_Alloc(signatureLen); | 196 sigitem.data = (unsigned char *)PORT_Alloc(signatureLen); |
198 | 197 |
199 if (sigitem.data == NULL) { | 198 if (sigitem.data == NULL) { |
200 » rv = SECFailure; | 199 rv = SECFailure; |
201 » goto loser; | 200 goto loser; |
202 } | 201 } |
203 | 202 |
204 rv = PK11_Sign(privKey, &sigitem, &digder); | 203 rv = PK11_Sign(privKey, &sigitem, &digder); |
205 if (rv != SECSuccess) { | 204 if (rv != SECSuccess) { |
206 » PORT_Free(sigitem.data); | 205 PORT_Free(sigitem.data); |
207 » sigitem.data = NULL; | 206 sigitem.data = NULL; |
208 » goto loser; | 207 goto loser; |
209 } | 208 } |
210 | 209 |
211 if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || | 210 if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || |
212 (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { | 211 (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { |
213 /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ | 212 /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ |
214 » rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); | 213 rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); |
215 » PORT_Free(sigitem.data); | 214 PORT_Free(sigitem.data); |
216 » if (rv != SECSuccess) | 215 if (rv != SECSuccess) |
217 » goto loser; | 216 goto loser; |
218 } else { | 217 } else { |
219 » result->len = sigitem.len; | 218 result->len = sigitem.len; |
220 » result->data = sigitem.data; | 219 result->data = sigitem.data; |
221 } | 220 } |
222 | 221 |
223 loser: | 222 loser: |
224 SGN_DestroyDigestInfo(di); | 223 SGN_DestroyDigestInfo(di); |
225 if (arena != NULL) { | 224 if (arena != NULL) { |
226 » PORT_FreeArena(arena, PR_FALSE); | 225 PORT_FreeArena(arena, PR_FALSE); |
227 } | 226 } |
228 return rv; | 227 return rv; |
229 } | 228 } |
230 | 229 |
231 /************************************************************************/ | 230 /************************************************************************/ |
232 | 231 |
233 /* | 232 /* |
234 ** Sign a block of data returning in result a bunch of bytes that are the | 233 ** Sign a block of data returning in result a bunch of bytes that are the |
235 ** signature. Returns zero on success, an error code on failure. | 234 ** signature. Returns zero on success, an error code on failure. |
236 */ | 235 */ |
237 SECStatus | 236 SECStatus |
238 SEC_SignData(SECItem *res, const unsigned char *buf, int len, | 237 SEC_SignData(SECItem *res, const unsigned char *buf, int len, |
239 » SECKEYPrivateKey *pk, SECOidTag algid) | 238 SECKEYPrivateKey *pk, SECOidTag algid) |
240 { | 239 { |
241 SECStatus rv; | 240 SECStatus rv; |
242 SGNContext *sgn; | 241 SGNContext *sgn; |
243 | 242 |
244 | |
245 sgn = SGN_NewContext(algid, pk); | 243 sgn = SGN_NewContext(algid, pk); |
246 | 244 |
247 if (sgn == NULL) | 245 if (sgn == NULL) |
248 » return SECFailure; | 246 return SECFailure; |
249 | 247 |
250 rv = SGN_Begin(sgn); | 248 rv = SGN_Begin(sgn); |
251 if (rv != SECSuccess) | 249 if (rv != SECSuccess) |
252 » goto loser; | 250 goto loser; |
253 | 251 |
254 rv = SGN_Update(sgn, buf, len); | 252 rv = SGN_Update(sgn, buf, len); |
255 if (rv != SECSuccess) | 253 if (rv != SECSuccess) |
256 » goto loser; | 254 goto loser; |
257 | 255 |
258 rv = SGN_End(sgn, res); | 256 rv = SGN_End(sgn, res); |
259 | 257 |
260 loser: | 258 loser: |
261 SGN_DestroyContext(sgn, PR_TRUE); | 259 SGN_DestroyContext(sgn, PR_TRUE); |
262 return rv; | 260 return rv; |
263 } | 261 } |
264 | 262 |
265 /************************************************************************/ | 263 /************************************************************************/ |
266 | 264 |
267 DERTemplate CERTSignedDataTemplate[] = | 265 DERTemplate CERTSignedDataTemplate[] = |
268 { | 266 { |
269 { DER_SEQUENCE, | 267 { DER_SEQUENCE, |
270 » 0, NULL, sizeof(CERTSignedData) }, | 268 0, NULL, sizeof(CERTSignedData) }, |
271 { DER_ANY, | 269 { DER_ANY, |
272 » offsetof(CERTSignedData,data), }, | 270 offsetof(CERTSignedData, data) }, |
273 { DER_INLINE, | 271 { DER_INLINE, |
274 » offsetof(CERTSignedData,signatureAlgorithm), | 272 offsetof(CERTSignedData, signatureAlgorithm), |
275 » SECAlgorithmIDTemplate, }, | 273 SECAlgorithmIDTemplate }, |
276 { DER_BIT_STRING, | 274 { DER_BIT_STRING, |
277 » offsetof(CERTSignedData,signature), }, | 275 offsetof(CERTSignedData, signature) }, |
278 { 0, } | 276 { 0 } |
279 }; | 277 }; |
280 | 278 |
281 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | 279 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) |
282 | 280 |
283 const SEC_ASN1Template CERT_SignedDataTemplate[] = | 281 const SEC_ASN1Template CERT_SignedDataTemplate[] = |
284 { | 282 { |
285 { SEC_ASN1_SEQUENCE, | 283 { SEC_ASN1_SEQUENCE, |
286 » 0, NULL, sizeof(CERTSignedData) }, | 284 0, NULL, sizeof(CERTSignedData) }, |
287 { SEC_ASN1_ANY, | 285 { SEC_ASN1_ANY, |
288 » offsetof(CERTSignedData,data), }, | 286 offsetof(CERTSignedData, data) }, |
289 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | 287 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, |
290 » offsetof(CERTSignedData,signatureAlgorithm), | 288 offsetof(CERTSignedData, signatureAlgorithm), |
291 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), }, | 289 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, |
292 { SEC_ASN1_BIT_STRING, | 290 { SEC_ASN1_BIT_STRING, |
293 » offsetof(CERTSignedData,signature), }, | 291 offsetof(CERTSignedData, signature) }, |
294 { 0, } | 292 { 0 } |
295 }; | 293 }; |
296 | 294 |
297 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate) | 295 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate) |
298 | 296 |
299 | |
300 SECStatus | 297 SECStatus |
301 SEC_DerSignData(PLArenaPool *arena, SECItem *result, | 298 SEC_DerSignData(PLArenaPool *arena, SECItem *result, |
302 » const unsigned char *buf, int len, SECKEYPrivateKey *pk, | 299 const unsigned char *buf, int len, SECKEYPrivateKey *pk, |
303 » SECOidTag algID) | 300 SECOidTag algID) |
304 { | 301 { |
305 SECItem it; | 302 SECItem it; |
306 CERTSignedData sd; | 303 CERTSignedData sd; |
307 SECStatus rv; | 304 SECStatus rv; |
308 | 305 |
309 it.data = 0; | 306 it.data = 0; |
310 | 307 |
311 /* XXX We should probably have some asserts here to make sure the key type | 308 /* XXX We should probably have some asserts here to make sure the key type |
312 * and algID match | 309 * and algID match |
313 */ | 310 */ |
314 | 311 |
315 if (algID == SEC_OID_UNKNOWN) { | 312 if (algID == SEC_OID_UNKNOWN) { |
316 » switch(pk->keyType) { | 313 switch (pk->keyType) { |
317 » case rsaKey: | 314 case rsaKey: |
318 » algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | 315 algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
319 » break; | 316 break; |
320 » case dsaKey: | 317 case dsaKey: |
321 » /* get Signature length (= q_len*2) and work from there */ | 318 /* get Signature length (= q_len*2) and work from there */ |
322 » switch (PK11_SignatureLen(pk)) { | 319 switch (PK11_SignatureLen(pk)) { |
323 » » case 448: | 320 case 448: |
324 » » algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; | 321 algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; |
325 » » break; | 322 break; |
326 » » case 512: | 323 case 512: |
327 » » algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; | 324 algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; |
328 » » break; | 325 break; |
329 » » default: | 326 default: |
330 » » algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; | 327 algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; |
331 » » break; | 328 break; |
332 » } | 329 } |
333 » break; | 330 break; |
334 » case ecKey: | 331 case ecKey: |
335 » algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; | 332 algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; |
336 » break; | 333 break; |
337 » default: | 334 default: |
338 » PORT_SetError(SEC_ERROR_INVALID_KEY); | 335 PORT_SetError(SEC_ERROR_INVALID_KEY); |
339 » return SECFailure; | 336 return SECFailure; |
340 » } | 337 } |
341 } | 338 } |
342 | 339 |
343 /* Sign input buffer */ | 340 /* Sign input buffer */ |
344 rv = SEC_SignData(&it, buf, len, pk, algID); | 341 rv = SEC_SignData(&it, buf, len, pk, algID); |
345 if (rv) goto loser; | 342 if (rv) |
| 343 goto loser; |
346 | 344 |
347 /* Fill out SignedData object */ | 345 /* Fill out SignedData object */ |
348 PORT_Memset(&sd, 0, sizeof(sd)); | 346 PORT_Memset(&sd, 0, sizeof(sd)); |
349 sd.data.data = (unsigned char*) buf; | 347 sd.data.data = (unsigned char *)buf; |
350 sd.data.len = len; | 348 sd.data.len = len; |
351 sd.signature.data = it.data; | 349 sd.signature.data = it.data; |
352 sd.signature.len = it.len << 3;» » /* convert to bit string */ | 350 sd.signature.len = it.len << 3; /* convert to bit string */ |
353 rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); | 351 rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); |
354 if (rv) goto loser; | 352 if (rv) |
| 353 goto loser; |
355 | 354 |
356 /* DER encode the signed data object */ | 355 /* DER encode the signed data object */ |
357 rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd); | 356 rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd); |
358 /* FALL THROUGH */ | 357 /* FALL THROUGH */ |
359 | 358 |
360 loser: | 359 loser: |
361 PORT_Free(it.data); | 360 PORT_Free(it.data); |
362 return rv; | 361 return rv; |
363 } | 362 } |
364 | 363 |
365 SECStatus | 364 SECStatus |
366 SGN_Digest(SECKEYPrivateKey *privKey, | 365 SGN_Digest(SECKEYPrivateKey *privKey, |
367 » » SECOidTag algtag, SECItem *result, SECItem *digest) | 366 SECOidTag algtag, SECItem *result, SECItem *digest) |
368 { | 367 { |
369 int modulusLen; | 368 int modulusLen; |
370 SECStatus rv; | 369 SECStatus rv; |
371 SECItem digder; | 370 SECItem digder; |
372 PLArenaPool *arena = 0; | 371 PLArenaPool *arena = 0; |
373 SGNDigestInfo *di = 0; | 372 SGNDigestInfo *di = 0; |
374 | 373 |
375 | |
376 result->data = 0; | 374 result->data = 0; |
377 | 375 |
378 if (privKey->keyType == rsaKey) { | 376 if (privKey->keyType == rsaKey) { |
379 | 377 |
380 » arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 378 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
381 » if ( !arena ) { | 379 if (!arena) { |
382 » rv = SECFailure; | 380 rv = SECFailure; |
383 » goto loser; | 381 goto loser; |
384 » } | 382 } |
385 | |
386 » /* Construct digest info */ | |
387 » di = SGN_CreateDigestInfo(algtag, digest->data, digest->len); | |
388 » if (!di) { | |
389 » rv = SECFailure; | |
390 » goto loser; | |
391 » } | |
392 | 383 |
393 » /* Der encode the digest as a DigestInfo */ | 384 /* Construct digest info */ |
| 385 di = SGN_CreateDigestInfo(algtag, digest->data, digest->len); |
| 386 if (!di) { |
| 387 rv = SECFailure; |
| 388 goto loser; |
| 389 } |
| 390 |
| 391 /* Der encode the digest as a DigestInfo */ |
394 rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, | 392 rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, |
395 di); | 393 di); |
396 » if (rv != SECSuccess) { | 394 if (rv != SECSuccess) { |
397 » goto loser; | 395 goto loser; |
398 » } | 396 } |
399 } else { | 397 } else { |
400 » digder.data = digest->data; | 398 digder.data = digest->data; |
401 » digder.len = digest->len; | 399 digder.len = digest->len; |
402 } | 400 } |
403 | 401 |
404 /* | 402 /* |
405 ** Encrypt signature after constructing appropriate PKCS#1 signature | 403 ** Encrypt signature after constructing appropriate PKCS#1 signature |
406 ** block | 404 ** block |
407 */ | 405 */ |
408 modulusLen = PK11_SignatureLen(privKey); | 406 modulusLen = PK11_SignatureLen(privKey); |
409 if (modulusLen <= 0) { | 407 if (modulusLen <= 0) { |
410 » PORT_SetError(SEC_ERROR_INVALID_KEY); | 408 PORT_SetError(SEC_ERROR_INVALID_KEY); |
411 » rv = SECFailure; | 409 rv = SECFailure; |
412 » goto loser; | 410 goto loser; |
413 } | 411 } |
414 result->len = modulusLen; | 412 result->len = modulusLen; |
415 result->data = (unsigned char*) PORT_Alloc(modulusLen); | 413 result->data = (unsigned char *)PORT_Alloc(modulusLen); |
416 result->type = siBuffer; | 414 result->type = siBuffer; |
417 | 415 |
418 if (result->data == NULL) { | 416 if (result->data == NULL) { |
419 » rv = SECFailure; | 417 rv = SECFailure; |
420 » goto loser; | 418 goto loser; |
421 } | 419 } |
422 | 420 |
423 rv = PK11_Sign(privKey, result, &digder); | 421 rv = PK11_Sign(privKey, result, &digder); |
424 if (rv != SECSuccess) { | 422 if (rv != SECSuccess) { |
425 » PORT_Free(result->data); | 423 PORT_Free(result->data); |
426 » result->data = NULL; | 424 result->data = NULL; |
427 } | 425 } |
428 | 426 |
429 loser: | 427 loser: |
430 SGN_DestroyDigestInfo(di); | 428 SGN_DestroyDigestInfo(di); |
431 if (arena != NULL) { | 429 if (arena != NULL) { |
432 » PORT_FreeArena(arena, PR_FALSE); | 430 PORT_FreeArena(arena, PR_FALSE); |
433 } | 431 } |
434 return rv; | 432 return rv; |
435 } | 433 } |
436 | 434 |
437 SECOidTag | 435 SECOidTag |
438 SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) | 436 SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) |
439 { | 437 { |
440 SECOidTag sigTag = SEC_OID_UNKNOWN; | 438 SECOidTag sigTag = SEC_OID_UNKNOWN; |
441 | 439 |
442 switch (keyType) { | 440 switch (keyType) { |
443 case rsaKey: | 441 case rsaKey: |
444 » switch (hashAlgTag) { | 442 switch (hashAlgTag) { |
445 » case SEC_OID_MD2: | 443 case SEC_OID_MD2: |
446 » sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;» break; | 444 sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; |
447 » case SEC_OID_MD5: | 445 break; |
448 » sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;» break; | 446 case SEC_OID_MD5: |
449 » case SEC_OID_SHA1: | 447 sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; |
450 » sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;» break; | 448 break; |
451 » case SEC_OID_SHA224: | 449 case SEC_OID_SHA1: |
452 » sigTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION;» break; | 450 sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
453 » case SEC_OID_UNKNOWN:» /* default for RSA if not specified */ | 451 break; |
454 » case SEC_OID_SHA256: | 452 case SEC_OID_SHA224: |
455 » sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;» break; | 453 sigTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; |
456 » case SEC_OID_SHA384: | 454 break; |
457 » sigTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;» break; | 455 case SEC_OID_UNKNOWN: /* default for RSA if not specified */ |
458 » case SEC_OID_SHA512: | 456 case SEC_OID_SHA256: |
459 » sigTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;» break; | 457 sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; |
460 » default: | 458 break; |
461 » break; | 459 case SEC_OID_SHA384: |
462 » } | 460 sigTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; |
463 » break; | 461 break; |
464 case dsaKey: | 462 case SEC_OID_SHA512: |
465 » switch (hashAlgTag) { | 463 sigTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; |
466 » case SEC_OID_UNKNOWN:» /* default for DSA if not specified */ | 464 break; |
467 » case SEC_OID_SHA1: | 465 default: |
468 » sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; | 466 break; |
469 » case SEC_OID_SHA224: | 467 } |
470 » sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break; | 468 break; |
471 » case SEC_OID_SHA256: | 469 case dsaKey: |
472 » sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break; | 470 switch (hashAlgTag) { |
473 » default: | 471 case SEC_OID_UNKNOWN: /* default for DSA if not specified */ |
474 » break; | 472 case SEC_OID_SHA1: |
475 » } | 473 sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; |
476 » break; | 474 break; |
477 case ecKey: | 475 case SEC_OID_SHA224: |
478 » switch (hashAlgTag) { | 476 sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; |
479 » case SEC_OID_UNKNOWN:» /* default for ECDSA if not specified */ | 477 break; |
480 » case SEC_OID_SHA1: | 478 case SEC_OID_SHA256: |
481 sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; | 479 sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; |
482 » case SEC_OID_SHA224: | 480 break; |
483 sigTag = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; break; | 481 default: |
484 » case SEC_OID_SHA256: | 482 break; |
485 sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break; | 483 } |
486 » case SEC_OID_SHA384: | 484 break; |
487 sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break; | 485 case ecKey: |
488 » case SEC_OID_SHA512: | 486 switch (hashAlgTag) { |
489 sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break; | 487 case SEC_OID_UNKNOWN: /* default for ECDSA if not specified */ |
490 » default: | 488 case SEC_OID_SHA1: |
491 » break; | 489 sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; |
492 » } | 490 break; |
493 default: | 491 case SEC_OID_SHA224: |
494 » break; | 492 sigTag = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; |
| 493 break; |
| 494 case SEC_OID_SHA256: |
| 495 sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; |
| 496 break; |
| 497 case SEC_OID_SHA384: |
| 498 sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; |
| 499 break; |
| 500 case SEC_OID_SHA512: |
| 501 sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; |
| 502 break; |
| 503 default: |
| 504 break; |
| 505 } |
| 506 default: |
| 507 break; |
495 } | 508 } |
496 return sigTag; | 509 return sigTag; |
497 } | 510 } |
OLD | NEW |