OLD | NEW |
1 /* ***** BEGIN LICENSE BLOCK ***** | 1 /* ***** BEGIN LICENSE BLOCK ***** |
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
3 * | 3 * |
4 * The contents of this file are subject to the Mozilla Public License Version | 4 * The contents of this file are subject to the Mozilla Public License Version |
5 * 1.1 (the "License"); you may not use this file except in compliance with | 5 * 1.1 (the "License"); you may not use this file except in compliance with |
6 * the License. You may obtain a copy of the License at | 6 * the License. You may obtain a copy of the License at |
7 * http://www.mozilla.org/MPL/ | 7 * http://www.mozilla.org/MPL/ |
8 * | 8 * |
9 * Software distributed under the License is distributed on an "AS IS" basis, | 9 * Software distributed under the License is distributed on an "AS IS" basis, |
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 * The caller is expected to abort any transaction he was in in the | 502 * The caller is expected to abort any transaction he was in in the |
503 * event of a failure of this function. | 503 * event of a failure of this function. |
504 */ | 504 */ |
505 static CK_RV | 505 static CK_RV |
506 sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle, | 506 sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle, |
507 PRBool mayBeUpdateDB, | 507 PRBool mayBeUpdateDB, |
508 CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template, | 508 CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template, |
509 CK_ULONG count) | 509 CK_ULONG count) |
510 { | 510 { |
511 int i; | 511 int i; |
| 512 CK_RV crv; |
512 SFTKDBHandle *keyHandle = handle; | 513 SFTKDBHandle *keyHandle = handle; |
513 SDB *keyTarget = NULL; | 514 SDB *keyTarget = NULL; |
| 515 PRBool usingPeerDB = PR_FALSE; |
| 516 PRBool inPeerDBTransaction = PR_FALSE; |
514 | 517 |
515 PORT_Assert(handle); | 518 PORT_Assert(handle); |
516 | 519 |
517 if (handle->type != SFTK_KEYDB_TYPE) { | 520 if (handle->type != SFTK_KEYDB_TYPE) { |
518 keyHandle = handle->peerDB; | 521 keyHandle = handle->peerDB; |
| 522 usingPeerDB = PR_TRUE; |
519 } | 523 } |
520 | 524 |
521 /* no key DB defined? then no need to sign anything */ | 525 /* no key DB defined? then no need to sign anything */ |
522 if (keyHandle == NULL) { | 526 if (keyHandle == NULL) { |
523 » return CKR_OK; | 527 » crv = CKR_OK; |
| 528 » goto loser; |
524 } | 529 } |
525 | 530 |
526 /* When we are in a middle of an update, we have an update database set, | 531 /* When we are in a middle of an update, we have an update database set, |
527 * but we want to write to the real database. The bool mayBeUpdateDB is | 532 * but we want to write to the real database. The bool mayBeUpdateDB is |
528 * set to TRUE if it's possible that we want to write an update database | 533 * set to TRUE if it's possible that we want to write an update database |
529 * rather than a primary */ | 534 * rather than a primary */ |
530 keyTarget = (mayBeUpdateDB && keyHandle->update) ? | 535 keyTarget = (mayBeUpdateDB && keyHandle->update) ? |
531 keyHandle->update : keyHandle->db; | 536 keyHandle->update : keyHandle->db; |
532 | 537 |
533 /* skip the the database does not support meta data */ | 538 /* skip the the database does not support meta data */ |
534 if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) { | 539 if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) { |
535 » return CKR_OK; | 540 » crv = CKR_OK; |
| 541 » goto loser; |
| 542 } |
| 543 |
| 544 /* If we had to switch databases, we need to initialize a transaction. */ |
| 545 if (usingPeerDB) { |
| 546 » crv = (*keyTarget->sdb_Begin)(keyTarget); |
| 547 » if (crv != CKR_OK) { |
| 548 » goto loser; |
| 549 » } |
| 550 » inPeerDBTransaction = PR_TRUE; |
536 } | 551 } |
537 | 552 |
538 for (i=0; i < count; i ++) { | 553 for (i=0; i < count; i ++) { |
539 if (sftkdb_isAuthenticatedAttribute(template[i].type)) { | 554 if (sftkdb_isAuthenticatedAttribute(template[i].type)) { |
540 SECStatus rv; | 555 SECStatus rv; |
541 SECItem *signText; | 556 SECItem *signText; |
542 SECItem plainText; | 557 SECItem plainText; |
543 | 558 |
544 plainText.data = template[i].pValue; | 559 plainText.data = template[i].pValue; |
545 plainText.len = template[i].ulValueLen; | 560 plainText.len = template[i].ulValueLen; |
546 PZ_Lock(keyHandle->passwordLock); | 561 PZ_Lock(keyHandle->passwordLock); |
547 if (keyHandle->passwordKey.data == NULL) { | 562 if (keyHandle->passwordKey.data == NULL) { |
548 PZ_Unlock(keyHandle->passwordLock); | 563 PZ_Unlock(keyHandle->passwordLock); |
549 » » return CKR_USER_NOT_LOGGED_IN; | 564 » » crv = CKR_USER_NOT_LOGGED_IN; |
| 565 » » goto loser; |
550 } | 566 } |
551 rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey, | 567 rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey, |
552 objectID, template[i].type, | 568 objectID, template[i].type, |
553 &plainText, &signText); | 569 &plainText, &signText); |
554 PZ_Unlock(keyHandle->passwordLock); | 570 PZ_Unlock(keyHandle->passwordLock); |
555 if (rv != SECSuccess) { | 571 if (rv != SECSuccess) { |
556 » » return CKR_GENERAL_ERROR; /* better error code here? */ | 572 » » crv = CKR_GENERAL_ERROR; /* better error code here? */ |
| 573 » » goto loser; |
557 } | 574 } |
558 rv = sftkdb_PutAttributeSignature(handle, keyTarget, | 575 rv = sftkdb_PutAttributeSignature(handle, keyTarget, |
559 objectID, template[i].type, signText); | 576 objectID, template[i].type, signText); |
560 if (rv != SECSuccess) { | 577 if (rv != SECSuccess) { |
561 » » return CKR_GENERAL_ERROR; /* better error code here? */ | 578 » » crv = CKR_GENERAL_ERROR; /* better error code here? */ |
| 579 » » goto loser; |
562 } | 580 } |
563 } | 581 } |
564 } | 582 } |
565 return CKR_OK; | 583 crv = CKR_OK; |
| 584 |
| 585 /* If necessary, commit the transaction */ |
| 586 if (inPeerDBTransaction) { |
| 587 » crv = (*keyTarget->sdb_Commit)(keyTarget); |
| 588 » if (crv != CKR_OK) { |
| 589 » goto loser; |
| 590 » } |
| 591 » inPeerDBTransaction = PR_FALSE; |
| 592 } |
| 593 |
| 594 loser: |
| 595 if (inPeerDBTransaction) { |
| 596 » /* The transaction must have failed. Abort. */ |
| 597 » (*keyTarget->sdb_Abort)(keyTarget); |
| 598 » PORT_Assert(crv != CKR_OK); |
| 599 » if (crv == CKR_OK) crv = CKR_GENERAL_ERROR; |
| 600 } |
| 601 return crv; |
566 } | 602 } |
567 | 603 |
568 static CK_RV | 604 static CK_RV |
569 sftkdb_CreateObject(PRArenaPool *arena, SFTKDBHandle *handle, | 605 sftkdb_CreateObject(PRArenaPool *arena, SFTKDBHandle *handle, |
570 SDB *db, CK_OBJECT_HANDLE *objectID, | 606 SDB *db, CK_OBJECT_HANDLE *objectID, |
571 CK_ATTRIBUTE *template, CK_ULONG count) | 607 CK_ATTRIBUTE *template, CK_ULONG count) |
572 { | 608 { |
573 PRBool inTransaction = PR_FALSE; | 609 PRBool inTransaction = PR_FALSE; |
574 CK_RV crv; | 610 CK_RV crv; |
575 | 611 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 count = 3; | 795 count = 3; |
760 break; | 796 break; |
761 | 797 |
762 case CKO_PRIVATE_KEY: | 798 case CKO_PRIVATE_KEY: |
763 case CKO_PUBLIC_KEY: | 799 case CKO_PUBLIC_KEY: |
764 case CKO_SECRET_KEY: | 800 case CKO_SECRET_KEY: |
765 attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, len); | 801 attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, len); |
766 if (attr == NULL) { | 802 if (attr == NULL) { |
767 return CKR_TEMPLATE_INCOMPLETE; | 803 return CKR_TEMPLATE_INCOMPLETE; |
768 } | 804 } |
| 805 if (attr->ulValueLen == 0) { |
| 806 /* key is too generic to determine that it's unique, usually |
| 807 * happens in the key gen case */ |
| 808 return CKR_OBJECT_HANDLE_INVALID; |
| 809 } |
| 810 |
769 findTemplate[1] = *attr; | 811 findTemplate[1] = *attr; |
770 count = 2; | 812 count = 2; |
771 break; | 813 break; |
772 | 814 |
773 case CKO_NSS_CRL: | 815 case CKO_NSS_CRL: |
774 attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len); | 816 attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len); |
775 if (attr == NULL) { | 817 if (attr == NULL) { |
776 return CKR_TEMPLATE_INCOMPLETE; | 818 return CKR_TEMPLATE_INCOMPLETE; |
777 } | 819 } |
778 findTemplate[1] = *attr; | 820 findTemplate[1] = *attr; |
(...skipping 21 matching lines...) Expand all Loading... |
800 findTemplate[1] = *attr; | 842 findTemplate[1] = *attr; |
801 count = 2; | 843 count = 2; |
802 break; | 844 break; |
803 } | 845 } |
804 *findCount = count; | 846 *findCount = count; |
805 | 847 |
806 return CKR_OK; | 848 return CKR_OK; |
807 } | 849 } |
808 | 850 |
809 /* | 851 /* |
810 * look to see if this object already exists and return it's object ID if | 852 * look to see if this object already exists and return its object ID if |
811 * it does. | 853 * it does. |
812 */ | 854 */ |
813 static CK_RV | 855 static CK_RV |
814 sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType, | 856 sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType, |
815 CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len) | 857 CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len) |
816 { | 858 { |
817 CK_ATTRIBUTE findTemplate[3]; | 859 CK_ATTRIBUTE findTemplate[3]; |
818 CK_ULONG count = 1; | 860 CK_ULONG count = 1; |
819 CK_ULONG objCount = 0; | 861 CK_ULONG objCount = 0; |
820 SDBFind *find = NULL; | 862 SDBFind *find = NULL; |
821 unsigned char objTypeData[SDB_ULONG_SIZE]; | 863 unsigned char objTypeData[SDB_ULONG_SIZE]; |
822 CK_RV crv; | 864 CK_RV crv; |
823 | 865 |
824 *id = CK_INVALID_HANDLE; | 866 *id = CK_INVALID_HANDLE; |
825 if (objectType == CKO_NSS_CRL) { | 867 if (objectType == CKO_NSS_CRL) { |
826 return CKR_OK; | 868 return CKR_OK; |
827 } | 869 } |
828 crv = sftkdb_getFindTemplate(objectType, objTypeData, | 870 crv = sftkdb_getFindTemplate(objectType, objTypeData, |
829 findTemplate, &count, ptemplate, len); | 871 findTemplate, &count, ptemplate, len); |
| 872 |
| 873 if (crv == CKR_OBJECT_HANDLE_INVALID) { |
| 874 /* key is too generic to determine that it's unique, usually |
| 875 * happens in the key gen case, tell the caller to go ahead |
| 876 * and just create it */ |
| 877 return CKR_OK; |
| 878 } |
830 if (crv != CKR_OK) { | 879 if (crv != CKR_OK) { |
831 return crv; | 880 return crv; |
832 } | 881 } |
833 | 882 |
834 /* use the raw find, so we get the correct database */ | 883 /* use the raw find, so we get the correct database */ |
835 crv = (*db->sdb_FindObjectsInit)(db, findTemplate, count, &find); | 884 crv = (*db->sdb_FindObjectsInit)(db, findTemplate, count, &find); |
836 if (crv != CKR_OK) { | 885 if (crv != CKR_OK) { |
837 return crv; | 886 return crv; |
838 } | 887 } |
839 (*db->sdb_FindObjects)(db, find, id, 1, &objCount); | 888 (*db->sdb_FindObjects)(db, find, id, 1, &objCount); |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2711 } | 2760 } |
2712 | 2761 |
2713 CK_RV | 2762 CK_RV |
2714 sftkdb_Shutdown(void) | 2763 sftkdb_Shutdown(void) |
2715 { | 2764 { |
2716 s_shutdown(); | 2765 s_shutdown(); |
2717 sftkdbCall_Shutdown(); | 2766 sftkdbCall_Shutdown(); |
2718 return CKR_OK; | 2767 return CKR_OK; |
2719 } | 2768 } |
2720 | 2769 |
OLD | NEW |