public void _01_DigestSinglePartTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath)) { rv = pkcs11.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present ulong slotId = Helpers.GetUsableSlot(pkcs11); ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Specify digesting mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA_1); // Initialize digesting operation rv = pkcs11.C_DigestInit(session, ref mechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); // Get length of digest value in first call ulong digestLen = 0; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), null, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(digestLen > 0); // Allocate array for digest value byte[] digest = new byte[digestLen]; // Get digest value in second call rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with digest value rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _01_BasicSignAndVerifyRecoverTest() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (Pkcs11Library pkcs11Library = new Pkcs11Library(Settings.Pkcs11LibraryPath)) { rv = pkcs11Library.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present NativeULong slotId = Helpers.GetUsableSlot(pkcs11Library); NativeULong session = CK.CK_INVALID_HANDLE; rv = pkcs11Library.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Login as normal user rv = pkcs11Library.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, ConvertUtils.UInt64FromInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Generate asymetric key pair NativeULong pubKeyId = CK.CK_INVALID_HANDLE; NativeULong privKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKeyPair(pkcs11Library, session, ref pubKeyId, ref privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Specify signing mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS); // Initialize signing operation rv = pkcs11Library.C_SignRecoverInit(session, ref mechanism, privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); // Get length of signature in first call NativeULong signatureLen = 0; rv = pkcs11Library.C_SignRecover(session, sourceData, ConvertUtils.UInt64FromInt32(sourceData.Length), null, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(signatureLen > 0); // Allocate array for signature byte[] signature = new byte[signatureLen]; // Get signature in second call rv = pkcs11Library.C_SignRecover(session, sourceData, ConvertUtils.UInt64FromInt32(sourceData.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with signature // Initialize verification operation rv = pkcs11Library.C_VerifyRecoverInit(session, ref mechanism, pubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Get length of recovered data in first call NativeULong recoveredDataLen = 0; rv = pkcs11Library.C_VerifyRecover(session, signature, ConvertUtils.UInt64FromInt32(signature.Length), null, ref recoveredDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(recoveredDataLen > 0); // Allocate array for recovered data byte[] recoveredData = new byte[recoveredDataLen]; // Verify signature and get recovered data in second call rv = pkcs11Library.C_VerifyRecover(session, signature, ConvertUtils.UInt64FromInt32(signature.Length), recoveredData, ref recoveredDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with verification result and recovered data Assert.IsTrue(ConvertUtils.BytesToBase64String(sourceData) == ConvertUtils.BytesToBase64String(recoveredData)); rv = pkcs11Library.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_DestroyObject(session, pubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _03_DigestKeyTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath)) { rv = pkcs11.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present ulong slotId = Helpers.GetUsableSlot(pkcs11); ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Login as normal user rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Generate symetric key ulong keyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKey(pkcs11, session, ref keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Specify digesting mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA_1); // Initialize digesting operation rv = pkcs11.C_DigestInit(session, ref mechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Digest key rv = pkcs11.C_DigestKey(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Get length of digest value in first call ulong digestLen = 0; rv = pkcs11.C_DigestFinal(session, null, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(digestLen > 0); // Allocate array for digest value byte[] digest = new byte[digestLen]; // Get digest value in second call rv = pkcs11.C_DigestFinal(session, digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with digest value rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _02_DigestMultiPartTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath)) { rv = pkcs11.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present ulong slotId = Helpers.GetUsableSlot(pkcs11); ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Specify digesting mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA_1); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); byte[] digest = null; // Multipart digesting functions C_DigestUpdate and C_DigestFinal can be used i.e. for digesting of streamed data using (MemoryStream inputStream = new MemoryStream(sourceData)) { // Initialize digesting operation rv = pkcs11.C_DigestInit(session, ref mechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Prepare buffer for source data part // Note that in real world application we would rather use bigger buffer i.e. 4096 bytes long byte[] part = new byte[8]; // Read input stream with source data int bytesRead = 0; while ((bytesRead = inputStream.Read(part, 0, part.Length)) > 0) { // Digest each individual source data part rv = pkcs11.C_DigestUpdate(session, part, Convert.ToUInt64(bytesRead)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } // Get length of digest value in first call ulong digestLen = 0; rv = pkcs11.C_DigestFinal(session, null, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(digestLen > 0); // Allocate array for digest value digest = new byte[digestLen]; // Get digest value in second call rv = pkcs11.C_DigestFinal(session, digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } // Do something interesting with digest value rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _06_GetMatchingSlotList() { Helpers.CheckPlatform(); using (Pkcs11Library pkcs11Library = new Pkcs11Library(Settings.Pkcs11LibraryPath)) { CKR rv = pkcs11Library.C_Initialize(Settings.InitArgs80); Assert.IsTrue(rv == CKR.CKR_OK); // Get all slots NativeULong allSlotsCount = 0; rv = pkcs11Library.C_GetSlotList(true, null, ref allSlotsCount); Assert.IsTrue(rv == CKR.CKR_OK); Assert.IsTrue(allSlotsCount > 0); NativeULong[] allSlots = new NativeULong[allSlotsCount]; rv = pkcs11Library.C_GetSlotList(true, allSlots, ref allSlotsCount); Assert.IsTrue(rv == CKR.CKR_OK); // Empty URI Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:"); NativeULong[] matchedSlots = null; rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11Library, true, out matchedSlots); Assert.IsTrue(rv == CKR.CKR_OK); Assert.IsTrue(matchedSlots.Length == allSlots.Length); // Unknown path attribute in URI pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar"); rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11Library, true, out matchedSlots); Assert.IsTrue(rv == CKR.CKR_OK); Assert.IsTrue(matchedSlots.Length == 0); // All attributes matching one slot CK_INFO libraryInfo = new CK_INFO(); rv = pkcs11Library.C_GetInfo(ref libraryInfo); Assert.IsTrue(rv == CKR.CKR_OK); CK_SLOT_INFO slotInfo = new CK_SLOT_INFO(); rv = pkcs11Library.C_GetSlotInfo(allSlots[0], ref slotInfo); Assert.IsTrue(rv == CKR.CKR_OK); CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO(); rv = pkcs11Library.C_GetTokenInfo(allSlots[0], ref tokenInfo); Assert.IsTrue(rv == CKR.CKR_OK); Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.LibraryManufacturer = ConvertUtils.BytesToUtf8String(libraryInfo.ManufacturerId, true); pkcs11UriBuilder.LibraryDescription = ConvertUtils.BytesToUtf8String(libraryInfo.LibraryDescription, true); pkcs11UriBuilder.LibraryVersion = libraryInfo.LibraryVersion.ToString(); pkcs11UriBuilder.SlotManufacturer = ConvertUtils.BytesToUtf8String(slotInfo.ManufacturerId, true); pkcs11UriBuilder.SlotDescription = ConvertUtils.BytesToUtf8String(slotInfo.SlotDescription, true); pkcs11UriBuilder.SlotId = allSlots[0]; pkcs11UriBuilder.Token = ConvertUtils.BytesToUtf8String(tokenInfo.Label, true); pkcs11UriBuilder.Manufacturer = ConvertUtils.BytesToUtf8String(tokenInfo.ManufacturerId, true); pkcs11UriBuilder.Serial = ConvertUtils.BytesToUtf8String(tokenInfo.SerialNumber, true); pkcs11UriBuilder.Model = ConvertUtils.BytesToUtf8String(tokenInfo.Model, true); pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11Library, true, out matchedSlots); Assert.IsTrue(rv == CKR.CKR_OK); Assert.IsTrue(matchedSlots.Length == 1); // One attribute nonmatching pkcs11UriBuilder.Serial = "foobar"; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11uri, pkcs11Library, true, out matchedSlots); Assert.IsTrue(rv == CKR.CKR_OK); Assert.IsTrue(matchedSlots.Length == 0); rv = pkcs11Library.C_Finalize(IntPtr.Zero); Assert.IsTrue(rv == CKR.CKR_OK); } }
public void _05_ObjectAttributesMatches() { Helpers.CheckPlatform(); // Empty URI Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:"); List<CK_ATTRIBUTE> objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // Empty attribute pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, string.Empty)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // Unknown path attribute in URI pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03;foo=bar"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // All attributes matching pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // Type nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // Object nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foo bar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); // Id nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 })); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes)); try { // Type present in URI but missing in list pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_LABEL, "foobar")); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes); Assert.Fail("Exception expected but not thrown"); } catch (Exception ex) { Assert.IsTrue(ex is Pkcs11UriException); } try { // Object present in URI but missing in list pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x01, 0x02, 0x03 })); Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes); Assert.Fail("Exception expected but not thrown"); } catch (Exception ex) { Assert.IsTrue(ex is Pkcs11UriException); } try { // Id present in URI but missing in list pkcs11uri = new Pkcs11Uri(@"pkcs11:type=private;object=foobar;id=%01%02%03"); objectAttributes = new List<CK_ATTRIBUTE>(); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY)); objectAttributes.Add(CkaUtils.CreateAttribute(CKA.CKA_ID, new byte[] { 0x04, 0x05, 0x06 })); Pkcs11UriUtils.Matches(pkcs11uri, objectAttributes); Assert.Fail("Exception expected but not thrown"); } catch (Exception ex) { Assert.IsTrue(ex is Pkcs11UriException); } }
public void _04_TokenInfoMatches() { Helpers.CheckPlatform(); // Empty URI Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:"); CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Empty attribute pkcs11uri = new Pkcs11Uri(@"pkcs11:token=;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes(" "); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Unknown path attribute in URI pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar;foo=bar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // All attributes matching pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Label nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // ManufacturerId nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // SerialNumber nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("012"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foobar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Model nonmatching pkcs11uri = new Pkcs11Uri(@"pkcs11:token=foo;manufacturer=bar;serial=123;model=foobar"); tokenInfo = new CK_TOKEN_INFO(); tokenInfo.Label = ConvertUtils.Utf8StringToBytes("foo"); tokenInfo.ManufacturerId = ConvertUtils.Utf8StringToBytes("bar"); tokenInfo.SerialNumber = ConvertUtils.Utf8StringToBytes("123"); tokenInfo.Model = ConvertUtils.Utf8StringToBytes("foo bar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); }