| 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 * This file manages object type indepentent functions. | 5 * This file manages object type indepentent functions. |
| 6 */ | 6 */ |
| 7 #include "seccomon.h" | 7 #include "seccomon.h" |
| 8 #include "secmod.h" | 8 #include "secmod.h" |
| 9 #include "secmodi.h" | 9 #include "secmodi.h" |
| 10 #include "secmodti.h" | 10 #include "secmodti.h" |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 return len; | 512 return len; |
| 513 } | 513 } |
| 514 | 514 |
| 515 /* | 515 /* |
| 516 * get the length of a signature object based on the key | 516 * get the length of a signature object based on the key |
| 517 */ | 517 */ |
| 518 int | 518 int |
| 519 PK11_SignatureLen(SECKEYPrivateKey *key) | 519 PK11_SignatureLen(SECKEYPrivateKey *key) |
| 520 { | 520 { |
| 521 int val; | 521 int val; |
| 522 CK_ATTRIBUTE theTemplate = { CKA_EC_PARAMS, NULL, 0 }; | 522 SECItem attributeItem = {siBuffer, NULL, 0}; |
| 523 SECItem params = {siBuffer, NULL, 0}; | 523 SECStatus rv; |
| 524 int length; | 524 int length; |
| 525 | 525 |
| 526 switch (key->keyType) { | 526 switch (key->keyType) { |
| 527 case rsaKey: | 527 case rsaKey: |
| 528 val = PK11_GetPrivateModulusLen(key); | 528 val = PK11_GetPrivateModulusLen(key); |
| 529 if (val == -1) { | 529 if (val == -1) { |
| 530 return pk11_backupGetSignLength(key); | 530 return pk11_backupGetSignLength(key); |
| 531 } | 531 } |
| 532 return (unsigned long) val; | 532 return (unsigned long) val; |
| 533 | 533 |
| 534 case fortezzaKey: | 534 case fortezzaKey: |
| 535 return 40; |
| 536 |
| 535 case dsaKey: | 537 case dsaKey: |
| 536 » return 40; | 538 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_SUBPRIME, |
| 539 » » » » NULL, &attributeItem); |
| 540 if (rv == SECSuccess) { |
| 541 » length = attributeItem.len; |
| 542 » if ((length > 0) && attributeItem.data[0] == 0) { |
| 543 » » length--; |
| 544 » } |
| 545 » PORT_Free(attributeItem.data); |
| 546 » return length*2; |
| 547 » } |
| 548 » return pk11_backupGetSignLength(key); |
| 549 |
| 537 case ecKey: | 550 case ecKey: |
| 538 » if (PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID, | 551 rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS, |
| 539 » » » &theTemplate, 1) == CKR_OK) { | 552 » » » » NULL, &attributeItem); |
| 540 » if (theTemplate.pValue != NULL) { | 553 » if (rv == SECSuccess) { |
| 541 » params.len = theTemplate.ulValueLen; | 554 » length = SECKEY_ECParamsToBasePointOrderLen(&attributeItem); |
| 542 » » params.data = (unsigned char *) theTemplate.pValue; | 555 » PORT_Free(attributeItem.data); |
| 543 » length = SECKEY_ECParamsToBasePointOrderLen(¶ms); | 556 » if (length != 0) { |
| 544 » PORT_Free(theTemplate.pValue); | |
| 545 » » if (length == 0) { | |
| 546 » » return pk11_backupGetSignLength(key); | |
| 547 » » } | |
| 548 length = ((length + 7)/8) * 2; | 557 length = ((length + 7)/8) * 2; |
| 549 return length; | 558 return length; |
| 550 } | 559 } |
| 551 } | 560 } |
| 552 » break; | 561 » return pk11_backupGetSignLength(key); |
| 553 default: | 562 default: |
| 554 break; | 563 break; |
| 555 } | 564 } |
| 556 PORT_SetError( SEC_ERROR_INVALID_KEY ); | 565 PORT_SetError( SEC_ERROR_INVALID_KEY ); |
| 557 return 0; | 566 return 0; |
| 558 } | 567 } |
| 559 | 568 |
| 560 /* | 569 /* |
| 561 * copy a key (or any other object) on a token | 570 * copy a key (or any other object) on a token |
| 562 */ | 571 */ |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 PK11SlotInfo *slot = key->pkcs11Slot; | 664 PK11SlotInfo *slot = key->pkcs11Slot; |
| 656 CK_OBJECT_HANDLE id = key->pkcs11ID; | 665 CK_OBJECT_HANDLE id = key->pkcs11ID; |
| 657 CK_MECHANISM mech = {0, NULL, 0 }; | 666 CK_MECHANISM mech = {0, NULL, 0 }; |
| 658 PRBool owner = PR_TRUE; | 667 PRBool owner = PR_TRUE; |
| 659 CK_SESSION_HANDLE session; | 668 CK_SESSION_HANDLE session; |
| 660 CK_RV crv; | 669 CK_RV crv; |
| 661 | 670 |
| 662 mech.mechanism = PK11_MapSignKeyType(key->keyType); | 671 mech.mechanism = PK11_MapSignKeyType(key->keyType); |
| 663 | 672 |
| 664 if (slot == NULL) { | 673 if (slot == NULL) { |
| 665 » slot = PK11_GetBestSlot(mech.mechanism,wincx); | 674 » if ((mech.mechanism == CKM_DSA) && |
| 675 » » » » /* 129 is 1024 bits translated to bytes and |
| 676 » » » » * padded with an optional '0' to maintain a |
| 677 » » » » * positive sign */ |
| 678 » » » » (key->u.dsa.params.prime.len > 129)) { |
| 679 » /* we need to get a slot that not only can do DSA, but can do DSA2 |
| 680 » * key lengths */ |
| 681 » unsigned int length = key->u.dsa.params.prime.len; |
| 682 » if (length > 0 && key->u.dsa.params.prime.data[0] == 0) { |
| 683 » » length --; |
| 684 » } |
| 685 » slot = PK11_GetBestSlotWithKeySize(mech.mechanism, |
| 686 » » » » » » length*BITS_PER_BYTE, wincx); |
| 687 » } else { |
| 688 » slot = PK11_GetBestSlot(mech.mechanism,wincx); |
| 689 » } |
| 666 | 690 |
| 667 if (slot == NULL) { | 691 if (slot == NULL) { |
| 668 PORT_SetError( SEC_ERROR_NO_MODULE ); | 692 PORT_SetError( SEC_ERROR_NO_MODULE ); |
| 669 return SECFailure; | 693 return SECFailure; |
| 670 } | 694 } |
| 671 id = PK11_ImportPublicKey(slot,key,PR_FALSE); | 695 id = PK11_ImportPublicKey(slot,key,PR_FALSE); |
| 672 | 696 |
| 673 } else { | 697 } else { |
| 674 PK11_ReferenceSlot(slot); | 698 PK11_ReferenceSlot(slot); |
| 675 } | 699 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 | 747 |
| 724 session = pk11_GetNewSession(slot,&owner); | 748 session = pk11_GetNewSession(slot,&owner); |
| 725 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 749 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 726 crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); | 750 crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); |
| 727 if (crv != CKR_OK) { | 751 if (crv != CKR_OK) { |
| 728 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 752 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 729 pk11_CloseSession(slot,session,owner); | 753 pk11_CloseSession(slot,session,owner); |
| 730 PORT_SetError( PK11_MapError(crv) ); | 754 PORT_SetError( PK11_MapError(crv) ); |
| 731 return SECFailure; | 755 return SECFailure; |
| 732 } | 756 } |
| 757 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then |
| 758 * do C_Login with CKU_CONTEXT_SPECIFIC |
| 759 * between C_SignInit and C_Sign */ |
| 760 if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_ALWAYS_AUTHENTICATE)) { |
| 761 PK11_DoPassword(slot, PR_FALSE, key->wincx, PR_TRUE); |
| 762 } |
| 733 len = sig->len; | 763 len = sig->len; |
| 734 crv = PK11_GETTAB(slot)->C_Sign(session,hash->data, | 764 crv = PK11_GETTAB(slot)->C_Sign(session,hash->data, |
| 735 hash->len, sig->data, &len); | 765 hash->len, sig->data, &len); |
| 736 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 766 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 737 pk11_CloseSession(slot,session,owner); | 767 pk11_CloseSession(slot,session,owner); |
| 738 sig->len = len; | 768 sig->len = len; |
| 739 if (crv != CKR_OK) { | 769 if (crv != CKR_OK) { |
| 740 PORT_SetError( PK11_MapError(crv) ); | 770 PORT_SetError( PK11_MapError(crv) ); |
| 741 return SECFailure; | 771 return SECFailure; |
| 742 } | 772 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 } | 805 } |
| 776 session = pk11_GetNewSession(slot,&owner); | 806 session = pk11_GetNewSession(slot,&owner); |
| 777 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); | 807 if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); |
| 778 crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID); | 808 crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID); |
| 779 if (crv != CKR_OK) { | 809 if (crv != CKR_OK) { |
| 780 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 810 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 781 pk11_CloseSession(slot,session,owner); | 811 pk11_CloseSession(slot,session,owner); |
| 782 PORT_SetError( PK11_MapError(crv) ); | 812 PORT_SetError( PK11_MapError(crv) ); |
| 783 return SECFailure; | 813 return SECFailure; |
| 784 } | 814 } |
| 815 /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then |
| 816 * do C_Login with CKU_CONTEXT_SPECIFIC |
| 817 * between C_DecryptInit and C_Decrypt */ |
| 818 /* But see note above about servers */ |
| 819 if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_ALWAYS_AUTHENTICATE)) { |
| 820 PK11_DoPassword(slot, PR_FALSE, key->wincx, PR_TRUE); |
| 821 } |
| 785 crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, data, &out); | 822 crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, data, &out); |
| 786 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); | 823 if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); |
| 787 pk11_CloseSession(slot,session,owner); | 824 pk11_CloseSession(slot,session,owner); |
| 788 *outLen = out; | 825 *outLen = out; |
| 789 if (crv != CKR_OK) { | 826 if (crv != CKR_OK) { |
| 790 PORT_SetError( PK11_MapError(crv) ); | 827 PORT_SetError( PK11_MapError(crv) ); |
| 791 return SECFailure; | 828 return SECFailure; |
| 792 } | 829 } |
| 793 return SECSuccess; | 830 return SECSuccess; |
| 794 } | 831 } |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 PORT_SetError( PK11_MapError(crv) ); | 1827 PORT_SetError( PK11_MapError(crv) ); |
| 1791 return NULL; | 1828 return NULL; |
| 1792 } | 1829 } |
| 1793 | 1830 |
| 1794 item->data = (unsigned char*) theTemplate[0].pValue; | 1831 item->data = (unsigned char*) theTemplate[0].pValue; |
| 1795 item->len =theTemplate[0].ulValueLen; | 1832 item->len =theTemplate[0].ulValueLen; |
| 1796 | 1833 |
| 1797 return item; | 1834 return item; |
| 1798 } | 1835 } |
| 1799 | 1836 |
| OLD | NEW |