summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-18 20:05:52 +0100
committerStef Walter <stefw@gnome.org>2013-03-18 21:53:24 +0100
commit1ad9f98b11f3f0d411bf9517f1dc8985ea3dbe2a (patch)
treee93f94fbe7522db404bca4c6794e8c3ae65ba341
parentf40e5f7129ece4b74aa2cb23b28b24b381bbe223 (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.c2
-rw-r--r--trust/module.c47
-rw-r--r--trust/tests/test-module.c66
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
1051static CK_ATTRIBUTE *
1052work_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
1050static CK_RV 1094static CK_RV
1051sys_C_FindObjectsInit (CK_SESSION_HANDLE handle, 1095sys_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
791static void
792test_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
791int 856int
792main (void) 857main (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);