OLD | NEW |
1 /* | 1 /* |
2 * Platform specific crypto wrappers | 2 * Platform specific crypto wrappers |
3 * | 3 * |
4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
6 * | 6 * |
7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 PRBool isTLS, KeyType keyType) | 205 PRBool isTLS, KeyType keyType) |
206 { | 206 { |
207 SECStatus rv = SECFailure; | 207 SECStatus rv = SECFailure; |
208 SECURITY_STATUS ncrypt_status; | 208 SECURITY_STATUS ncrypt_status; |
209 PRBool doDerEncode = PR_FALSE; | 209 PRBool doDerEncode = PR_FALSE; |
210 SECItem hashItem; | 210 SECItem hashItem; |
211 DWORD signatureLen = 0; | 211 DWORD signatureLen = 0; |
212 DWORD dwFlags = 0; | 212 DWORD dwFlags = 0; |
213 VOID *pPaddingInfo = NULL; | 213 VOID *pPaddingInfo = NULL; |
214 | 214 |
215 /* Always encode using PKCS#1 block type, with no OID/encoded DigestInfo */ | 215 /* Always encode using PKCS#1 block type. */ |
216 BCRYPT_PKCS1_PADDING_INFO rsaPaddingInfo; | 216 BCRYPT_PKCS1_PADDING_INFO rsaPaddingInfo; |
217 rsaPaddingInfo.pszAlgId = NULL; | |
218 | 217 |
219 if (key->dwKeySpec != CERT_NCRYPT_KEY_SPEC) { | 218 if (key->dwKeySpec != CERT_NCRYPT_KEY_SPEC) { |
220 PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); | 219 PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); |
221 return SECFailure; | 220 return SECFailure; |
222 } | 221 } |
223 if (ssl_InitCng() != SECSuccess) { | 222 if (ssl_InitCng() != SECSuccess) { |
224 PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); | 223 PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); |
225 return SECFailure; | 224 return SECFailure; |
226 } | 225 } |
227 | 226 |
228 switch (keyType) { | 227 switch (keyType) { |
229 case rsaKey: | 228 case rsaKey: |
230 hashItem.data = hash->md5; | 229 switch (hash->hashAlg) { |
231 hashItem.len = sizeof(SSL3Hashes); | 230 case SEC_OID_UNKNOWN: |
| 231 /* No OID/encoded DigestInfo. */ |
| 232 rsaPaddingInfo.pszAlgId = NULL; |
| 233 break; |
| 234 case SEC_OID_SHA1: |
| 235 rsaPaddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; |
| 236 break; |
| 237 case SEC_OID_SHA256: |
| 238 rsaPaddingInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM; |
| 239 break; |
| 240 case SEC_OID_SHA384: |
| 241 rsaPaddingInfo.pszAlgId = BCRYPT_SHA384_ALGORITHM; |
| 242 break; |
| 243 case SEC_OID_SHA512: |
| 244 rsaPaddingInfo.pszAlgId = BCRYPT_SHA512_ALGORITHM; |
| 245 break; |
| 246 default: |
| 247 PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 248 return SECFailure; |
| 249 } |
| 250 hashItem.data = hash->u.raw; |
| 251 hashItem.len = hash->len; |
232 dwFlags = BCRYPT_PAD_PKCS1; | 252 dwFlags = BCRYPT_PAD_PKCS1; |
233 pPaddingInfo = &rsaPaddingInfo; | 253 pPaddingInfo = &rsaPaddingInfo; |
234 break; | 254 break; |
235 case dsaKey: | 255 case dsaKey: |
236 case ecKey: | 256 case ecKey: |
237 if (keyType == ecKey) { | 257 if (keyType == ecKey) { |
238 doDerEncode = PR_TRUE; | 258 doDerEncode = PR_TRUE; |
239 } else { | 259 } else { |
240 doDerEncode = isTLS; | 260 doDerEncode = isTLS; |
241 } | 261 } |
242 hashItem.data = hash->sha; | 262 if (hash->hashAlg == SEC_OID_UNKNOWN) { |
243 hashItem.len = sizeof(hash->sha); | 263 hashItem.data = hash->u.s.sha; |
| 264 hashItem.len = sizeof(hash->u.s.sha); |
| 265 } else { |
| 266 hashItem.data = hash->u.raw; |
| 267 hashItem.len = hash->len; |
| 268 } |
244 break; | 269 break; |
245 default: | 270 default: |
246 PORT_SetError(SEC_ERROR_INVALID_KEY); | 271 PORT_SetError(SEC_ERROR_INVALID_KEY); |
247 goto done; | 272 goto done; |
248 } | 273 } |
249 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); | 274 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); |
250 | 275 |
251 ncrypt_status = (*pNCryptSignHash)(key->hNCryptKey, pPaddingInfo, | 276 ncrypt_status = (*pNCryptSignHash)(key->hNCryptKey, pPaddingInfo, |
252 (PBYTE)hashItem.data, hashItem.len, | 277 (PBYTE)hashItem.data, hashItem.len, |
253 NULL, 0, &signatureLen, dwFlags); | 278 NULL, 0, &signatureLen, dwFlags); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 SECItem hashItem; | 333 SECItem hashItem; |
309 DWORD argLen = 0; | 334 DWORD argLen = 0; |
310 DWORD signatureLen = 0; | 335 DWORD signatureLen = 0; |
311 ALG_ID hashAlg = 0; | 336 ALG_ID hashAlg = 0; |
312 HCRYPTHASH hHash = 0; | 337 HCRYPTHASH hHash = 0; |
313 DWORD hashLen = 0; | 338 DWORD hashLen = 0; |
314 unsigned int i = 0; | 339 unsigned int i = 0; |
315 | 340 |
316 buf->data = NULL; | 341 buf->data = NULL; |
317 | 342 |
| 343 switch (hash->hashAlg) { |
| 344 case SEC_OID_UNKNOWN: |
| 345 hashAlg = 0; |
| 346 break; |
| 347 case SEC_OID_SHA1: |
| 348 hashAlg = CALG_SHA1; |
| 349 break; |
| 350 case SEC_OID_SHA256: |
| 351 hashAlg = CALG_SHA_256; |
| 352 break; |
| 353 case SEC_OID_SHA384: |
| 354 hashAlg = CALG_SHA_384; |
| 355 break; |
| 356 case SEC_OID_SHA512: |
| 357 hashAlg = CALG_SHA_512; |
| 358 break; |
| 359 default: |
| 360 PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 361 return SECFailure; |
| 362 } |
| 363 |
318 switch (keyType) { | 364 switch (keyType) { |
319 case rsaKey: | 365 case rsaKey: |
320 hashAlg = CALG_SSL3_SHAMD5; | 366 if (hashAlg == 0) { |
321 hashItem.data = hash->md5; | 367 hashAlg = CALG_SSL3_SHAMD5; |
322 hashItem.len = sizeof(SSL3Hashes); | 368 } |
| 369 hashItem.data = hash->u.raw; |
| 370 hashItem.len = hash->len; |
323 break; | 371 break; |
324 case dsaKey: | 372 case dsaKey: |
325 case ecKey: | 373 case ecKey: |
326 if (keyType == ecKey) { | 374 if (keyType == ecKey) { |
327 doDerEncode = PR_TRUE; | 375 doDerEncode = PR_TRUE; |
328 } else { | 376 } else { |
329 doDerEncode = isTLS; | 377 doDerEncode = isTLS; |
330 } | 378 } |
331 hashAlg = CALG_SHA1; | 379 if (hashAlg == 0) { |
332 hashItem.data = hash->sha; | 380 hashAlg = CALG_SHA1; |
333 hashItem.len = sizeof(hash->sha); | 381 hashItem.data = hash->u.s.sha; |
| 382 hashItem.len = sizeof(hash->u.s.sha); |
| 383 } else { |
| 384 hashItem.data = hash->u.raw; |
| 385 hashItem.len = hash->len; |
| 386 } |
334 break; | 387 break; |
335 default: | 388 default: |
336 PORT_SetError(SEC_ERROR_INVALID_KEY); | 389 PORT_SetError(SEC_ERROR_INVALID_KEY); |
337 goto done; | 390 goto done; |
338 } | 391 } |
339 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); | 392 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); |
340 | 393 |
341 if (!CryptCreateHash(key->hCryptProv, hashAlg, 0, 0, &hHash)) { | 394 if (!CryptCreateHash(key->hCryptProv, hashAlg, 0, 0, &hHash)) { |
342 PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError()); | 395 PR_SetError(SSL_ERROR_SIGN_HASHES_FAILURE, GetLastError()); |
343 goto done; | 396 goto done; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 if (signatureLen == 0) { | 514 if (signatureLen == 0) { |
462 PORT_SetError(SEC_ERROR_INVALID_KEY); | 515 PORT_SetError(SEC_ERROR_INVALID_KEY); |
463 goto done; | 516 goto done; |
464 } | 517 } |
465 | 518 |
466 buf->data = (unsigned char *)PORT_Alloc(signatureLen); | 519 buf->data = (unsigned char *)PORT_Alloc(signatureLen); |
467 if (!buf->data) | 520 if (!buf->data) |
468 goto done; /* error code was set. */ | 521 goto done; /* error code was set. */ |
469 | 522 |
470 sigAlg = cssmKey->KeyHeader.AlgorithmId; | 523 sigAlg = cssmKey->KeyHeader.AlgorithmId; |
| 524 if (keyType == rsaKey) { |
| 525 PORT_Assert(sigAlg == CSSM_ALGID_RSA); |
| 526 switch (hash->hashAlg) { |
| 527 case SEC_OID_UNKNOWN: |
| 528 break; |
| 529 case SEC_OID_SHA1: |
| 530 sigAlg = CSSM_ALGID_SHA1WithRSA; |
| 531 break; |
| 532 case SEC_OID_SHA224: |
| 533 sigAlg = CSSM_ALGID_SHA224WithRSA; |
| 534 break; |
| 535 case SEC_OID_SHA256: |
| 536 sigAlg = CSSM_ALGID_SHA256WithRSA; |
| 537 break; |
| 538 case SEC_OID_SHA384: |
| 539 sigAlg = CSSM_ALGID_SHA384WithRSA; |
| 540 break; |
| 541 case SEC_OID_SHA512: |
| 542 sigAlg = CSSM_ALGID_SHA512WithRSA; |
| 543 break; |
| 544 default: |
| 545 PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM); |
| 546 goto done; |
| 547 } |
| 548 } |
| 549 |
471 switch (keyType) { | 550 switch (keyType) { |
472 case rsaKey: | 551 case rsaKey: |
473 PORT_Assert(sigAlg == CSSM_ALGID_RSA); | 552 hashData.Data = hash->u.raw; |
474 hashData.Data = hash->md5; | 553 hashData.Length = hash->len; |
475 hashData.Length = sizeof(SSL3Hashes); | |
476 break; | 554 break; |
477 case dsaKey: | 555 case dsaKey: |
478 case ecKey: | 556 case ecKey: |
479 if (keyType == ecKey) { | 557 if (keyType == ecKey) { |
480 PORT_Assert(sigAlg == CSSM_ALGID_ECDSA); | 558 PORT_Assert(sigAlg == CSSM_ALGID_ECDSA); |
481 doDerEncode = PR_TRUE; | 559 doDerEncode = PR_TRUE; |
482 } else { | 560 } else { |
483 PORT_Assert(sigAlg == CSSM_ALGID_DSA); | 561 PORT_Assert(sigAlg == CSSM_ALGID_DSA); |
484 doDerEncode = isTLS; | 562 doDerEncode = isTLS; |
485 } | 563 } |
486 hashData.Data = hash->sha; | 564 if (hash->hashAlg == SEC_OID_UNKNOWN) { |
487 hashData.Length = sizeof(hash->sha); | 565 hashData.Data = hash->u.s.sha; |
| 566 hashData.Length = sizeof(hash->u.s.sha); |
| 567 } else { |
| 568 hashData.Data = hash->u.raw; |
| 569 hashData.Length = hash->len; |
| 570 } |
488 break; | 571 break; |
489 default: | 572 default: |
490 PORT_SetError(SEC_ERROR_INVALID_KEY); | 573 PORT_SetError(SEC_ERROR_INVALID_KEY); |
491 goto done; | 574 goto done; |
492 } | 575 } |
493 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashData.Data, hashData.Length
)); | 576 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashData.Data, hashData.Length
)); |
494 | 577 |
495 /* TODO(rsleevi): Should it be kSecCredentialTypeNoUI? In Win32, at least, | 578 /* TODO(rsleevi): Should it be kSecCredentialTypeNoUI? In Win32, at least, |
496 * you can prevent the UI by setting the provider handle on the | 579 * you can prevent the UI by setting the provider handle on the |
497 * certificate to be opened with CRYPT_SILENT, but is there an equivalent? | 580 * certificate to be opened with CRYPT_SILENT, but is there an equivalent? |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 SECStatus | 657 SECStatus |
575 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, | 658 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, |
576 PRBool isTLS, KeyType keyType) | 659 PRBool isTLS, KeyType keyType) |
577 { | 660 { |
578 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | 661 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
579 return SECFailure; | 662 return SECFailure; |
580 } | 663 } |
581 #endif | 664 #endif |
582 | 665 |
583 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 666 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
OLD | NEW |