diff options
author | Stef Walter <stefw@gnome.org> | 2013-03-18 20:05:52 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2013-03-18 21:53:24 +0100 |
commit | 1ad9f98b11f3f0d411bf9517f1dc8985ea3dbe2a (patch) | |
tree | e93f94fbe7522db404bca4c6794e8c3ae65ba341 | |
parent | f40e5f7129ece4b74aa2cb23b28b24b381bbe223 (diff) |
trust: Handle incorrectly encoded CKA_SERIAL_NUMBER lookups
Handle lookups for trust objects (by NSS) which expect CKA_SERIAL_NUMBER
attributes without appropriate DER encoding.
In addition allow creation of NSS trust objects as PKCS#11 session
objects, so that we can test this behavior.
-rw-r--r-- | trust/builder.c | 2 | ||||
-rw-r--r-- | trust/module.c | 47 | ||||
-rw-r--r-- | trust/tests/test-module.c | 66 |
3 files changed, 114 insertions, 1 deletions
diff --git a/trust/builder.c b/trust/builder.c index 65aa5dd..0a020cf 100644 --- a/trust/builder.c +++ b/trust/builder.c | |||
@@ -728,7 +728,7 @@ build_for_schema (p11_builder *builder, | |||
728 | if (attrs != NULL) | 728 | if (attrs != NULL) |
729 | attrs_filter_if_unchanged (attrs, merge); | 729 | attrs_filter_if_unchanged (attrs, merge); |
730 | 730 | ||
731 | if (creating) { | 731 | if (creating && (builder->flags & P11_BUILDER_FLAG_TOKEN)) { |
732 | if (schema->build_flags & GENERATED_CLASS) { | 732 | if (schema->build_flags & GENERATED_CLASS) { |
733 | p11_message ("objects of this type cannot be created"); | 733 | p11_message ("objects of this type cannot be created"); |
734 | return CKR_TEMPLATE_INCONSISTENT; | 734 | return CKR_TEMPLATE_INCONSISTENT; |
diff --git a/trust/module.c b/trust/module.c index dcf4e8f..3ef4034 100644 --- a/trust/module.c +++ b/trust/module.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "module.h" | 45 | #include "module.h" |
46 | #include "parser.h" | 46 | #include "parser.h" |
47 | #include "pkcs11.h" | 47 | #include "pkcs11.h" |
48 | #include "pkcs11x.h" | ||
48 | #include "session.h" | 49 | #include "session.h" |
49 | #include "token.h" | 50 | #include "token.h" |
50 | 51 | ||
@@ -1047,6 +1048,49 @@ sys_C_SetAttributeValue (CK_SESSION_HANDLE handle, | |||
1047 | return rv; | 1048 | return rv; |
1048 | } | 1049 | } |
1049 | 1050 | ||
1051 | static CK_ATTRIBUTE * | ||
1052 | work_around_broken_nss_serial_number_lookups (CK_ATTRIBUTE *attrs) | ||
1053 | { | ||
1054 | /* | ||
1055 | * WORKAROUND: NSS calls us asking for CKA_SERIAL_NUMBER items that are | ||
1056 | * not DER encoded. It shouldn't be doing this. We never return any certificate | ||
1057 | * serial numbers that are not DER encoded. | ||
1058 | * | ||
1059 | * So work around the issue here while the NSS guys fix this issue. | ||
1060 | * This code should be removed in future versions. | ||
1061 | */ | ||
1062 | |||
1063 | CK_OBJECT_CLASS klass; | ||
1064 | CK_ATTRIBUTE *serial; | ||
1065 | unsigned char *der; | ||
1066 | size_t der_len; | ||
1067 | int len_len; | ||
1068 | |||
1069 | if (!p11_attrs_find_ulong (attrs, CKA_CLASS, &klass) || | ||
1070 | klass != CKO_NSS_TRUST) | ||
1071 | return attrs; | ||
1072 | |||
1073 | serial = p11_attrs_find_valid (attrs, CKA_SERIAL_NUMBER); | ||
1074 | if (!serial || p11_asn1_tlv_length (serial->pValue, serial->ulValueLen) >= 0) | ||
1075 | return attrs; | ||
1076 | |||
1077 | p11_debug ("working around serial number lookup that's not DER encoded"); | ||
1078 | |||
1079 | /* Assumption that 32 bytes is more than enough to store a ulong */ | ||
1080 | der_len = 1 + 32 + serial->ulValueLen; | ||
1081 | der = malloc (der_len); | ||
1082 | return_val_if_fail (der != NULL, NULL); | ||
1083 | |||
1084 | der[0] = ASN1_TAG_INTEGER | ASN1_CLASS_UNIVERSAL; | ||
1085 | len_len = der_len - 1; | ||
1086 | asn1_length_der (serial->ulValueLen, der + 1, &len_len); | ||
1087 | assert (len_len < der_len - serial->ulValueLen); | ||
1088 | memcpy (der + 1 + len_len, serial->pValue, serial->ulValueLen); | ||
1089 | der_len = 1 + len_len + serial->ulValueLen; | ||
1090 | |||
1091 | return p11_attrs_take (attrs, CKA_SERIAL_NUMBER, der, der_len); | ||
1092 | } | ||
1093 | |||
1050 | static CK_RV | 1094 | static CK_RV |
1051 | sys_C_FindObjectsInit (CK_SESSION_HANDLE handle, | 1095 | sys_C_FindObjectsInit (CK_SESSION_HANDLE handle, |
1052 | CK_ATTRIBUTE_PTR template, | 1096 | CK_ATTRIBUTE_PTR template, |
@@ -1095,6 +1139,9 @@ sys_C_FindObjectsInit (CK_SESSION_HANDLE handle, | |||
1095 | find->match = p11_attrs_buildn (NULL, template, count); | 1139 | find->match = p11_attrs_buildn (NULL, template, count); |
1096 | warn_if_fail (find->match != NULL); | 1140 | warn_if_fail (find->match != NULL); |
1097 | 1141 | ||
1142 | find->match = work_around_broken_nss_serial_number_lookups (find->match); | ||
1143 | warn_if_fail (find->match != NULL); | ||
1144 | |||
1098 | /* Build a session snapshot of all objects */ | 1145 | /* Build a session snapshot of all objects */ |
1099 | find->iterator = 0; | 1146 | find->iterator = 0; |
1100 | find->snapshot = p11_index_snapshot (indices[0], indices[1], template, count); | 1147 | find->snapshot = p11_index_snapshot (indices[0], indices[1], template, count); |
diff --git a/trust/tests/test-module.c b/trust/tests/test-module.c index 4606a31..de0a3b1 100644 --- a/trust/tests/test-module.c +++ b/trust/tests/test-module.c | |||
@@ -788,6 +788,71 @@ test_session_remove (CuTest *cu) | |||
788 | teardown (cu); | 788 | teardown (cu); |
789 | } | 789 | } |
790 | 790 | ||
791 | static void | ||
792 | test_find_serial_der_decoded (CuTest *cu) | ||
793 | { | ||
794 | CK_OBJECT_CLASS nss_trust = CKO_NSS_TRUST; | ||
795 | |||
796 | CK_ATTRIBUTE object[] = { | ||
797 | { CKA_CLASS, &nss_trust, sizeof (nss_trust) }, | ||
798 | { CKA_SERIAL_NUMBER, "\x02\x03\x01\x02\x03", 5 }, | ||
799 | { CKA_INVALID } | ||
800 | }; | ||
801 | |||
802 | CK_ATTRIBUTE match_decoded[] = { | ||
803 | { CKA_CLASS, &nss_trust, sizeof (nss_trust) }, | ||
804 | { CKA_SERIAL_NUMBER, "\x01\x02\x03", 3 }, | ||
805 | { CKA_INVALID } | ||
806 | }; | ||
807 | |||
808 | CK_SESSION_HANDLE session; | ||
809 | CK_OBJECT_HANDLE handle; | ||
810 | CK_OBJECT_HANDLE check; | ||
811 | CK_ULONG count; | ||
812 | CK_RV rv; | ||
813 | |||
814 | /* | ||
815 | * WORKAROUND: NSS calls us asking for CKA_SERIAL_NUMBER items that are | ||
816 | * not DER encoded. It shouldn't be doing this. We never return any certificate | ||
817 | * serial numbers that are not DER encoded. | ||
818 | * | ||
819 | * So work around the issue here while the NSS guys fix this issue. | ||
820 | * This code should be removed in future versions. | ||
821 | * | ||
822 | * See work_around_broken_nss_serial_number_lookups(). | ||
823 | */ | ||
824 | |||
825 | setup (cu); | ||
826 | |||
827 | rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION, NULL, NULL, &session); | ||
828 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
829 | |||
830 | rv = test.module->C_CreateObject (session, object, 2, &handle); | ||
831 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
832 | |||
833 | /* Do a standard find for the same object */ | ||
834 | rv = test.module->C_FindObjectsInit (session, object, 2); | ||
835 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
836 | rv = test.module->C_FindObjects (session, &check, 1, &count); | ||
837 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
838 | CuAssertIntEquals (cu, 1, count); | ||
839 | CuAssertIntEquals (cu, handle, check); | ||
840 | rv = test.module->C_FindObjectsFinal (session); | ||
841 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
842 | |||
843 | /* Do a find for the serial number decoded */ | ||
844 | rv = test.module->C_FindObjectsInit (session, match_decoded, 2); | ||
845 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
846 | rv = test.module->C_FindObjects (session, &check, 1, &count); | ||
847 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
848 | CuAssertIntEquals (cu, 1, count); | ||
849 | CuAssertIntEquals (cu, handle, check); | ||
850 | rv = test.module->C_FindObjectsFinal (session); | ||
851 | CuAssertIntEquals (cu, CKR_OK, rv); | ||
852 | |||
853 | teardown (cu); | ||
854 | } | ||
855 | |||
791 | int | 856 | int |
792 | main (void) | 857 | main (void) |
793 | { | 858 | { |
@@ -814,6 +879,7 @@ main (void) | |||
814 | SUITE_ADD_TEST (suite, test_session_copy); | 879 | SUITE_ADD_TEST (suite, test_session_copy); |
815 | SUITE_ADD_TEST (suite, test_session_remove); | 880 | SUITE_ADD_TEST (suite, test_session_remove); |
816 | SUITE_ADD_TEST (suite, test_session_setattr); | 881 | SUITE_ADD_TEST (suite, test_session_setattr); |
882 | SUITE_ADD_TEST (suite, test_find_serial_der_decoded); | ||
817 | 883 | ||
818 | CuSuiteRun (suite); | 884 | CuSuiteRun (suite); |
819 | CuSuiteSummary (suite, output); | 885 | CuSuiteSummary (suite, output); |