public void _02_ReadWriteSessionTest() { 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); // Open RW (read-write) session 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()); // Do something interesting in RW session 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 _03_SingleThreadedInitializeTest() { 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)) { // PKCS#11 library needs to be initialized with C_Initialize method. // If an application will not be accessing PKCS#11 library from multiple threads // simultaneously, it can generally call C_Initialize with initArgs parameter set to null. rv = pkcs11.C_Initialize(null); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) Assert.Fail(rv.ToString()); // Do something interesting // C_Finalize is called to indicate that an application is finished // with the PKCS#11 library. It should be the last call made by an application. rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _01_BasicGetInfoTest() { 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()); CK_INFO info = new CK_INFO(); rv = pkcs11.C_GetInfo(ref info); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with library information Assert.IsFalse(String.IsNullOrEmpty(ConvertUtils.BytesToUtf8String(info.ManufacturerId))); rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _01_BasicTokenInfoTest() { 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); CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO(); rv = pkcs11.C_GetTokenInfo(slotId, ref tokenInfo); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with token info Assert.IsFalse(String.IsNullOrEmpty(ConvertUtils.BytesToUtf8String(tokenInfo.ManufacturerId))); rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
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()); } }
/// <summary> /// Finds slot containing the token that matches criteria specified in Settings class /// </summary> /// <param name='pkcs11'>Initialized PKCS11 wrapper</param> /// <returns>Slot containing the token that matches criteria</returns> public static ulong GetUsableSlot(Pkcs11 pkcs11) { CKR rv = CKR.CKR_OK; // Get list of available slots with token present ulong slotCount = 0; rv = pkcs11.C_GetSlotList(true, null, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(slotCount > 0); ulong[] slotList = new ulong[slotCount]; rv = pkcs11.C_GetSlotList(true, slotList, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Return first slot with token present when both TokenSerial and TokenLabel are null... if (Settings.TokenSerial == null && Settings.TokenLabel == null) return slotList[0]; // First slot with token present is OK... ulong? matchingSlot = slotList[0]; // ...unless there are matching criteria specified in Settings class if (Settings.TokenSerial != null || Settings.TokenLabel != null) { matchingSlot = null; foreach (uint slot in slotList) { CK_TOKEN_INFO tokenInfo = new CK_TOKEN_INFO(); rv = pkcs11.C_GetTokenInfo(slot, ref tokenInfo); if (rv != CKR.CKR_OK) { if (rv == CKR.CKR_TOKEN_NOT_RECOGNIZED || rv == CKR.CKR_TOKEN_NOT_PRESENT) continue; else Assert.Fail(rv.ToString()); } if (!string.IsNullOrEmpty(Settings.TokenSerial)) if (0 != string.Compare(Settings.TokenSerial, ConvertUtils.BytesToUtf8String(tokenInfo.SerialNumber, true), StringComparison.Ordinal)) continue; if (!string.IsNullOrEmpty(Settings.TokenLabel)) if (0 != string.Compare(Settings.TokenLabel, ConvertUtils.BytesToUtf8String(tokenInfo.Label, true), StringComparison.Ordinal)) continue; matchingSlot = slot; break; } } Assert.IsTrue(matchingSlot != null, "Token matching criteria specified in Settings class is not present"); return matchingSlot.Value; }
public void _02_UsingPkcs11DisposeTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) Assert.Inconclusive("Test cannot be executed on this platform"); // Pkcs11 class can be used in using statement which defines a scope // at the end of which an object will be disposed. using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath)) { // Do something interesting } }
public void _01_BasicOperationStateTest() { 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); // Open RO (read-only) session ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, CKF.CKF_SERIAL_SESSION, IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Get length of state in first call ulong stateLen = 0; rv = pkcs11.C_GetOperationState(session, null, ref stateLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(stateLen > 0); // Allocate array for state byte[] state = new byte[stateLen]; // Get state in second call rv = pkcs11.C_GetOperationState(session, state, ref stateLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Let's set state so the test is complete rv = pkcs11.C_SetOperationState(session, state, Convert.ToUInt64(state.Length), CK.CK_INVALID_HANDLE, CK.CK_INVALID_HANDLE); 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 _01_BasicPkcs11DisposeTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) Assert.Inconclusive("Test cannot be executed on this platform"); // Unmanaged PKCS#11 library is loaded by the constructor of Pkcs11 class // and unloaded by Dispose() method. Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath); // Do something interesting pkcs11.Dispose(); }
public void _01_BasicSetPinTest() { 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); // Open RW session 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()); // Set new pin for the logged in user rv = pkcs11.C_SetPIN(session, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length), Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length)); 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 _01_BasicMechanismListAndInfoTest() { 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); // Get number of supported mechanisms in first call ulong mechanismCount = 0; rv = pkcs11.C_GetMechanismList(slotId, null, ref mechanismCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(mechanismCount > 0); // Allocate array for supported mechanisms CKM[] mechanismList = new CKM[mechanismCount]; // Get supported mechanisms in second call rv = pkcs11.C_GetMechanismList(slotId, mechanismList, ref mechanismCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Analyze first supported mechanism CK_MECHANISM_INFO mechanismInfo = new CK_MECHANISM_INFO(); rv = pkcs11.C_GetMechanismInfo(slotId, mechanismList[0], ref mechanismInfo); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with mechanism info rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _02_BasicSlotListAndInfoTest() { 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()); // Get number of slots in first call ulong slotCount = 0; rv = pkcs11.C_GetSlotList(true, null, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(slotCount > 0); // Allocate array for slot IDs ulong[] slotList = new ulong[slotCount]; // Get slot IDs in second call rv = pkcs11.C_GetSlotList(true, slotList, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Analyze first slot CK_SLOT_INFO slotInfo = new CK_SLOT_INFO(); rv = pkcs11.C_GetSlotInfo(slotList[0], ref slotInfo); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with slot info Assert.IsFalse(String.IsNullOrEmpty(ConvertUtils.BytesToUtf8String(slotInfo.ManufacturerId))); rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _02_GenerateRandomTest() { 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); // Open RO (read-only) session ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, CKF.CKF_SERIAL_SESSION, IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Allocate array for random bytes byte[] randomData = new byte[256]; // Get random or pseudo-random data rv = pkcs11.C_GenerateRandom(session, randomData, Convert.ToUInt64(randomData.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with random data 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_SeedRandomTest() { 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); // Open RO (read-only) session ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, CKF.CKF_SERIAL_SESSION, IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Mix additional seed material into the token's random number generator byte[] seed = ConvertUtils.Utf8StringToBytes("Additional seed material"); rv = pkcs11.C_SeedRandom(session, seed, Convert.ToUInt64(seed.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with random number generator 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()); } }
/// <summary> /// Obtains a list of unmanaged struct sizes. /// This method should be used only for testing purposes with PKCS11-MOCK module. /// </summary> /// <param name="pkcs11">Instance of the extended class</param> /// <param name="sizeList"> /// If set to null then the number of sizes is returned in "count" parameter, without actually returning a list of sizes. /// If not set to null then "count" parameter must contain the lenght of sizeList array and size list is returned in "sizeList" parameter. /// </param> /// <param name="count">Location that receives the number of sizes</param> /// <returns>CKR_ARGUMENTS_BAD, CKR_BUFFER_TOO_SMALL, CKR_OK</returns> public static CKR C_GetUnmanagedStructSizeList(this LLA80.Pkcs11 pkcs11, ulong[] sizeList, ref ulong count) { if (pkcs11.Disposed) { throw new ObjectDisposedException(pkcs11.GetType().FullName); } Delegates.C_GetUnmanagedStructSizeListDelegate8x cGetUnmanagedStructSizeList = null; if (pkcs11.LibraryHandle != IntPtr.Zero) { IntPtr cGetUnmanagedStructSizeListPtr = UnmanagedLibrary.GetFunctionPointer(pkcs11.LibraryHandle, "C_GetUnmanagedStructSizeList"); cGetUnmanagedStructSizeList = UnmanagedLibrary.GetDelegateForFunctionPointer <Delegates.C_GetUnmanagedStructSizeListDelegate8x>(cGetUnmanagedStructSizeListPtr); } else { cGetUnmanagedStructSizeList = NativeMethods.C_GetUnmanagedStructSizeList8x; } ulong rv = cGetUnmanagedStructSizeList(sizeList, ref count); return((CKR)Convert.ToUInt32(rv)); }
/// <summary> /// Ejects token from slot. /// This method should be used only for testing purposes with PKCS11-MOCK module. /// </summary> /// <param name="pkcs11">Instance of the extended class</param> /// <param name="slotId">The ID of the token's slot</param> /// <returns>CKR_CRYPTOKI_NOT_INITIALIZED, CKR_SLOT_ID_INVALID, CKR_OK</returns> public static CKR C_EjectToken(this LLA80.Pkcs11 pkcs11, ulong slotId) { if (pkcs11.Disposed) { throw new ObjectDisposedException(pkcs11.GetType().FullName); } Delegates.C_EjectToken8x cEjectToken = null; if (pkcs11.LibraryHandle != IntPtr.Zero) { IntPtr cEjectTokenPtr = UnmanagedLibrary.GetFunctionPointer(pkcs11.LibraryHandle, "C_EjectToken"); cEjectToken = UnmanagedLibrary.GetDelegateForFunctionPointer <Delegates.C_EjectToken8x>(cEjectTokenPtr); } else { cEjectToken = NativeMethods.C_EjectToken8x; } ulong rv = cEjectToken(slotId); return((CKR)Convert.ToUInt32(rv)); }
public void _02_CancelFunctionTest() { 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); // Open RO (read-only) session ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slotId, CKF.CKF_SERIAL_SESSION, IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Legacy functions should always return CKR_FUNCTION_NOT_PARALLEL rv = pkcs11.C_CancelFunction(session); if (rv != CKR.CKR_FUNCTION_NOT_PARALLEL) 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 _01_SlotListTest() { 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()); // Get number of slots in first call ulong slotCount = 0; rv = pkcs11.C_GetSlotList(true, null, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(slotCount > 0); // Allocate array for slot IDs ulong[] slotList = new ulong[slotCount]; // Get slot IDs in second call rv = pkcs11.C_GetSlotList(true, slotList, ref slotCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with slots rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _01_CreateDestroyObjectTest() { 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()); // Prepare attribute template of new data object CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[5]; template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_DATA); template[1] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true); template[2] = CkaUtils.CreateAttribute(CKA.CKA_APPLICATION, Settings.ApplicationName); template[3] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName); template[4] = CkaUtils.CreateAttribute(CKA.CKA_VALUE, "Data object content"); // Create object ulong objectId = CK.CK_INVALID_HANDLE; rv = pkcs11.C_CreateObject(session, template, Convert.ToUInt64(template.Length), ref objectId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // In LowLevelAPI we have to free unmanaged memory taken by attributes for (int i = 0; i < template.Length; i++) { UnmanagedMemory.Free(ref template[i].value); template[i].valueLen = 0; } // Do something interesting with new object // Destroy object rv = pkcs11.C_DestroyObject(session, objectId); 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 _01_BasicWrapAndUnwrapKeyTest() { 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 asymetric key pair ulong pubKeyId = CK.CK_INVALID_HANDLE; ulong privKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKeyPair(pkcs11, session, ref pubKeyId, ref privKeyId); 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 wrapping mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS); // Get length of wrapped key in first call ulong wrappedKeyLen = 0; rv = pkcs11.C_WrapKey(session, ref mechanism, pubKeyId, keyId, null, ref wrappedKeyLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(wrappedKeyLen > 0); // Allocate array for wrapped key byte[] wrappedKey = new byte[wrappedKeyLen]; // Get wrapped key in second call rv = pkcs11.C_WrapKey(session, ref mechanism, pubKeyId, keyId, wrappedKey, ref wrappedKeyLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with wrapped key // Define attributes for unwrapped key CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[6]; template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); template[1] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3); template[2] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true); template[3] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true); template[4] = CkaUtils.CreateAttribute(CKA.CKA_DERIVE, true); template[5] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true); // Unwrap key ulong unwrappedKeyId = 0; rv = pkcs11.C_UnwrapKey(session, ref mechanism, privKeyId, wrappedKey, wrappedKeyLen, template, Convert.ToUInt64(template.Length), ref unwrappedKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with unwrapped key rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, pubKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); 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()); } }
/// <summary> /// Creates the PKCS#1 v1.5 RSA signature with SHA-1 mechanism /// </summary> /// <param name="data">Data that should be signed</param> /// <param name="uri">PKCS#11 URI identifying PKCS#11 library, token and private key</param> /// <returns>PKCS#1 v1.5 RSA signature</returns> private byte[] SignData(byte[] data, string uri) { // Verify input parameters if (data == null) throw new ArgumentNullException("data"); if (string.IsNullOrEmpty(uri)) throw new ArgumentNullException("uri"); // Parse PKCS#11 URI Pkcs11Uri pkcs11Uri = new Pkcs11Uri(uri); // Verify that URI contains all information required to perform this operation if (pkcs11Uri.ModulePath == null) throw new Exception("PKCS#11 URI does not specify PKCS#11 library"); if (pkcs11Uri.PinValue == null) throw new Exception("PKCS#11 URI does not specify PIN"); if (!pkcs11Uri.DefinesObject || pkcs11Uri.Type != CKO.CKO_PRIVATE_KEY) throw new Exception("PKCS#11 URI does not specify private key"); // Load and initialize PKCS#11 library specified by URI CKR rv = CKR.CKR_OK; using (Pkcs11 pkcs11 = new Pkcs11(pkcs11Uri.ModulePath, true)) { rv = pkcs11.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) Assert.Fail(rv.ToString()); // Obtain a list of all slots with tokens that match URI ulong[] slots = null; rv = Pkcs11UriUtils.GetMatchingSlotList(pkcs11Uri, pkcs11, true, out slots); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); if ((slots == null) || (slots.Length == 0)) throw new Exception("None of the slots matches PKCS#11 URI"); // Open read only session with first token that matches URI ulong session = CK.CK_INVALID_HANDLE; rv = pkcs11.C_OpenSession(slots[0], (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 with PIN acquired from URI byte[] pinValue = ConvertUtils.Utf8StringToBytes(pkcs11Uri.PinValue); rv = pkcs11.C_Login(session, CKU.CKU_USER, pinValue, Convert.ToUInt64(pinValue.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Get list of object attributes for the private key specified by URI CK_ATTRIBUTE[] attributes = null; Pkcs11UriUtils.GetObjectAttributes(pkcs11Uri, out attributes); // Find private key specified by URI ulong foundObjectCount = 0; ulong[] foundObjectIds = new ulong[] { CK.CK_INVALID_HANDLE }; rv = pkcs11.C_FindObjectsInit(session, attributes, Convert.ToUInt64(attributes.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_FindObjects(session, foundObjectIds, Convert.ToUInt64(foundObjectIds.Length), ref foundObjectCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_FindObjectsFinal(session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); if ((foundObjectCount == 0) || (foundObjectIds[0] == CK.CK_INVALID_HANDLE)) throw new Exception("None of the private keys match PKCS#11 URI"); // Create signature with the private key specified by URI CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA1_RSA_PKCS); rv = pkcs11.C_SignInit(session, ref mechanism, foundObjectIds[0]); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); ulong signatureLen = 0; rv = pkcs11.C_Sign(session, data, Convert.ToUInt64(data.Length), null, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(signatureLen > 0); byte[] signature = new byte[signatureLen]; rv = pkcs11.C_Sign(session, data, Convert.ToUInt64(data.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); if (signature.Length != Convert.ToInt32(signatureLen)) Array.Resize(ref signature, Convert.ToInt32(signatureLen)); // Release PKCS#11 resources 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()); return signature; } }
public void _02_SignAndVerifyMultiPartTest() { 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 asymetric key pair ulong pubKeyId = CK.CK_INVALID_HANDLE; ulong privKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKeyPair(pkcs11, 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_SHA1_RSA_PKCS); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); byte[] signature = null; // Multipart signature functions C_SignUpdate and C_SignFinal can be used i.e. for signing of streamed data using (MemoryStream inputStream = new MemoryStream(sourceData)) { // Initialize signing operation rv = pkcs11.C_SignInit(session, ref mechanism, privKeyId); 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) { // Process each individual source data part rv = pkcs11.C_SignUpdate(session, part, Convert.ToUInt64(bytesRead)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } // Get the length of signature in first call ulong signatureLen = 0; rv = pkcs11.C_SignFinal(session, null, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(signatureLen > 0); // Allocate array for signature signature = new byte[signatureLen]; // Get signature in second call rv = pkcs11.C_SignFinal(session, signature, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } // Do something interesting with signature // Multipart verification functions C_VerifyUpdate and C_VerifyFinal can be used i.e. for signature verification of streamed data using (MemoryStream inputStream = new MemoryStream(sourceData)) { // Initialize verification operation rv = pkcs11.C_VerifyInit(session, ref mechanism, pubKeyId); 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) { // Process each individual source data part rv = pkcs11.C_VerifyUpdate(session, part, Convert.ToUInt64(bytesRead)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } // Verify signature rv = pkcs11.C_VerifyFinal(session, signature, Convert.ToUInt64(signature.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } // Do something interesting with verification result rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, pubKeyId); 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 _01_BasicDeriveKeyTest() { 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); // Open RW session 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 baseKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKey(pkcs11, session, ref baseKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Generate random data needed for key derivation byte[] data = new byte[24]; rv = pkcs11.C_GenerateRandom(session, data, Convert.ToUInt64(data.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Specify mechanism parameters // Note that we are allocating unmanaged memory that will have to be freed later CK_KEY_DERIVATION_STRING_DATA mechanismParams = new CK_KEY_DERIVATION_STRING_DATA(); mechanismParams.Data = UnmanagedMemory.Allocate(data.Length); UnmanagedMemory.Write(mechanismParams.Data, data); mechanismParams.Len = Convert.ToUInt64(data.Length); // Specify derivation mechanism with parameters // Note that CkmUtils.CreateMechanism() automaticaly copies mechanismParams into newly allocated unmanaged memory CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_XOR_BASE_AND_DATA, mechanismParams); // Derive key ulong derivedKey = CK.CK_INVALID_HANDLE; rv = pkcs11.C_DeriveKey(session, ref mechanism, baseKeyId, null, 0, ref derivedKey); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with derived key Assert.IsTrue(derivedKey != CK.CK_INVALID_HANDLE); // In LowLevelAPI we have to free all unmanaged memory we previously allocated UnmanagedMemory.Free(ref mechanismParams.Data); mechanismParams.Len = 0; // In LowLevelAPI we have to free unmanaged memory taken by mechanism parameter UnmanagedMemory.Free(ref mechanism.Parameter); mechanism.ParameterLen = 0; rv = pkcs11.C_DestroyObject(session, baseKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, derivedKey); 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 _06_Pkcs11WithoutGetFunctionListTest() { if (Platform.UnmanagedLongSize != 8 || Platform.StructPackingSize != 0) Assert.Inconclusive("Test cannot be executed on this platform"); // Before an application can perform any cryptographic operations with Cryptoki library // it has to obtain function pointers for all the Cryptoki API routines present in the library. // This can be done either via C_GetFunctionList() function or via platform specific native // function - GetProcAddress() on Windows and dlsym() on Unix. // The most simple constructor of Net.Pkcs11Interop.LowLevelAPI80.Pkcs11 class uses // C_GetFunctionList() approach but Pkcs11Interop also provides an alternative constructor // that can specify which approach should be used. using (Pkcs11 pkcs11 = new Pkcs11(Settings.Pkcs11LibraryPath, false)) { // Do something interesting } }
public void _04_MultiThreadedInitializeTest() { 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)) { // If an application will be accessing PKCS#11 library from multiple threads // simultaneously, it has to provide initArgs parameter to C_Initialize method. // The easiest way is to set CKF_OS_LOCKING_OK flag, which will indicate that // PKCS#11 library can use the native operation system threading model for locking. CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS(); initArgs.Flags = CKF.CKF_OS_LOCKING_OK; rv = pkcs11.C_Initialize(initArgs); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) Assert.Fail(rv.ToString()); // Do something interesting rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }
public void _01_BasicObjectFindingTest() { 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()); // Let's create two objects so we can find something ulong objectId1 = CK.CK_INVALID_HANDLE; rv = Helpers.CreateDataObject(pkcs11, session, ref objectId1); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); ulong objectId2 = CK.CK_INVALID_HANDLE; rv = Helpers.CreateDataObject(pkcs11, session, ref objectId2); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Prepare attribute template that defines search criteria CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[2]; template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_DATA); template[1] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true); // Initialize searching rv = pkcs11.C_FindObjectsInit(session, template, Convert.ToUInt64(template.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Get search results ulong foundObjectCount = 0; ulong[] foundObjectIds = new ulong[2]; foundObjectIds[0] = CK.CK_INVALID_HANDLE; foundObjectIds[1] = CK.CK_INVALID_HANDLE; rv = pkcs11.C_FindObjects(session, foundObjectIds, Convert.ToUInt64(foundObjectIds.Length), ref foundObjectCount); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Terminate searching rv = pkcs11.C_FindObjectsFinal(session); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with found objects Assert.IsTrue((foundObjectIds[0] != CK.CK_INVALID_HANDLE) && (foundObjectIds[1] != CK.CK_INVALID_HANDLE)); // In LowLevelAPI we have to free unmanaged memory taken by attributes for (int i = 0; i < template.Length; i++) { UnmanagedMemory.Free(ref template[i].value); template[i].valueLen = 0; } rv = pkcs11.C_DestroyObject(session, objectId2); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, objectId1); 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 _03_GetObjectSizeTest() { 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()); // Create object ulong objectId = CK.CK_INVALID_HANDLE; rv = Helpers.CreateDataObject(pkcs11, session, ref objectId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Determine object size ulong objectSize = 0; rv = pkcs11.C_GetObjectSize(session, objectId, ref objectSize); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(objectSize > 0); rv = pkcs11.C_DestroyObject(session, objectId); 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 _01_GenerateKeyTest() { 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()); // Prepare attribute template of new key CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[4]; template[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); template[1] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3); template[2] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true); template[3] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true); // Specify key generation mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_DES3_KEY_GEN); // Generate key ulong keyId = CK.CK_INVALID_HANDLE; rv = pkcs11.C_GenerateKey(session, ref mechanism, template, Convert.ToUInt64(template.Length), ref keyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // In LowLevelAPI we have to free unmanaged memory taken by attributes for (int i = 0; i < template.Length; i++) { UnmanagedMemory.Free(ref template[i].value); template[i].valueLen = 0; } // Do something interesting with generated key // Destroy object 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_GenerateKeyPairTest() { 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()); // The CKA_ID attribute is intended as a means of distinguishing multiple key pairs held by the same subject byte[] ckaId = new byte[20]; rv = pkcs11.C_GenerateRandom(session, ckaId, Convert.ToUInt64(ckaId.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Prepare attribute template of new public key CK_ATTRIBUTE[] pubKeyTemplate = new CK_ATTRIBUTE[10]; pubKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true); pubKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, false); pubKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName); pubKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_ID, ckaId); pubKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_ENCRYPT, true); pubKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_VERIFY, true); pubKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_VERIFY_RECOVER, true); pubKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_WRAP, true); pubKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_MODULUS_BITS, 1024); pubKeyTemplate[9] = CkaUtils.CreateAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }); // Prepare attribute template of new private key CK_ATTRIBUTE[] privKeyTemplate = new CK_ATTRIBUTE[9]; privKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, true); privKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, true); privKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.ApplicationName); privKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_ID, ckaId); privKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, true); privKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_DECRYPT, true); privKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_SIGN, true); privKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_SIGN_RECOVER, true); privKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_UNWRAP, true); // Specify key generation mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN); // Generate key pair ulong pubKeyId = CK.CK_INVALID_HANDLE; ulong privKeyId = CK.CK_INVALID_HANDLE; rv = pkcs11.C_GenerateKeyPair(session, ref mechanism, pubKeyTemplate, Convert.ToUInt64(pubKeyTemplate.Length), privKeyTemplate, Convert.ToUInt64(privKeyTemplate.Length), ref pubKeyId, ref privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // In LowLevelAPI we have to free unmanaged memory taken by attributes for (int i = 0; i < privKeyTemplate.Length; i++) { UnmanagedMemory.Free(ref privKeyTemplate[i].value); privKeyTemplate[i].valueLen = 0; } for (int i = 0; i < pubKeyTemplate.Length; i++) { UnmanagedMemory.Free(ref pubKeyTemplate[i].value); pubKeyTemplate[i].valueLen = 0; } // Do something interesting with generated key pair // Destroy object rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, pubKeyId); 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 _01_BasicSignEncryptAndDecryptVerifyTest() { 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 asymetric key pair ulong pubKeyId = CK.CK_INVALID_HANDLE; ulong privKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKeyPair(pkcs11, 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 signingMechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA1_RSA_PKCS); // 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()); // Generate random initialization vector byte[] iv = new byte[8]; rv = pkcs11.C_GenerateRandom(session, iv, Convert.ToUInt64(iv.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Specify encryption mechanism with initialization vector as parameter. // Note that CkmUtils.CreateMechanism() automaticaly copies iv into newly allocated unmanaged memory. CK_MECHANISM encryptionMechanism = CkmUtils.CreateMechanism(CKM.CKM_DES3_CBC, iv); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Passw0rd"); byte[] signature = null; byte[] encryptedData = null; byte[] decryptedData = null; // Multipart signing and encryption function C_SignEncryptUpdate can be used i.e. for signing and encryption of streamed data using (MemoryStream inputStream = new MemoryStream(sourceData), outputStream = new MemoryStream()) { // Initialize signing operation rv = pkcs11.C_SignInit(session, ref signingMechanism, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Initialize encryption operation rv = pkcs11.C_EncryptInit(session, ref encryptionMechanism, keyId); 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]; // Prepare buffer for encrypted data part // Note that in real world application we would rather use bigger buffer i.e. 4096 bytes long byte[] encryptedPart = new byte[8]; ulong encryptedPartLen = Convert.ToUInt64(encryptedPart.Length); // Read input stream with source data int bytesRead = 0; while ((bytesRead = inputStream.Read(part, 0, part.Length)) > 0) { // Process each individual source data part encryptedPartLen = Convert.ToUInt64(encryptedPart.Length); rv = pkcs11.C_SignEncryptUpdate(session, part, Convert.ToUInt64(bytesRead), encryptedPart, ref encryptedPartLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Append encrypted data part to the output stream outputStream.Write(encryptedPart, 0, Convert.ToInt32(encryptedPartLen)); } // Get the length of signature in first call ulong signatureLen = 0; rv = pkcs11.C_SignFinal(session, null, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); Assert.IsTrue(signatureLen > 0); // Allocate array for signature signature = new byte[signatureLen]; // Get signature in second call rv = pkcs11.C_SignFinal(session, signature, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Get the length of last encrypted data part in first call byte[] lastEncryptedPart = null; ulong lastEncryptedPartLen = 0; rv = pkcs11.C_EncryptFinal(session, null, ref lastEncryptedPartLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Allocate array for the last encrypted data part lastEncryptedPart = new byte[lastEncryptedPartLen]; // Get the last encrypted data part in second call rv = pkcs11.C_EncryptFinal(session, lastEncryptedPart, ref lastEncryptedPartLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Append the last encrypted data part to the output stream outputStream.Write(lastEncryptedPart, 0, Convert.ToInt32(lastEncryptedPartLen)); // Read whole output stream to the byte array so we can compare results more easily encryptedData = outputStream.ToArray(); } // Do something interesting with signature and encrypted data // Multipart decryption and verification function C_DecryptVerifyUpdate can be used i.e. for decryption and signature verification of streamed data using (MemoryStream inputStream = new MemoryStream(encryptedData), outputStream = new MemoryStream()) { // Initialize decryption operation rv = pkcs11.C_DecryptInit(session, ref encryptionMechanism, keyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Initialize verification operation rv = pkcs11.C_VerifyInit(session, ref signingMechanism, pubKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Prepare buffer for encrypted data part // Note that in real world application we would rather use bigger buffer i.e. 4096 bytes long byte[] encryptedPart = new byte[8]; // Prepare buffer for decrypted data part // Note that in real world application we would rather use bigger buffer i.e. 4096 bytes long byte[] part = new byte[8]; ulong partLen = Convert.ToUInt64(part.Length); // Read input stream with encrypted data int bytesRead = 0; while ((bytesRead = inputStream.Read(encryptedPart, 0, encryptedPart.Length)) > 0) { // Process each individual encrypted data part partLen = Convert.ToUInt64(part.Length); rv = pkcs11.C_DecryptVerifyUpdate(session, encryptedPart, Convert.ToUInt64(bytesRead), part, ref partLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Append decrypted data part to the output stream outputStream.Write(part, 0, Convert.ToInt32(partLen)); } // Get the length of last decrypted data part in first call byte[] lastPart = null; ulong lastPartLen = 0; rv = pkcs11.C_DecryptFinal(session, null, ref lastPartLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Allocate array for the last decrypted data part lastPart = new byte[lastPartLen]; // Get the last decrypted data part in second call rv = pkcs11.C_DecryptFinal(session, lastPart, ref lastPartLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Append the last decrypted data part to the output stream outputStream.Write(lastPart, 0, Convert.ToInt32(lastPartLen)); // Read whole output stream to the byte array so we can compare results more easily decryptedData = outputStream.ToArray(); // Verify signature rv = pkcs11.C_VerifyFinal(session, signature, Convert.ToUInt64(signature.Length)); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } // Do something interesting with decrypted data and verification result Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); // In LowLevelAPI we have to free unmanaged memory taken by mechanism parameter (iv in this case) UnmanagedMemory.Free(ref encryptionMechanism.Parameter); encryptionMechanism.ParameterLen = 0; rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, pubKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); 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 _01_BasicSignAndVerifyRecoverTest() { 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 asymetric key pair ulong pubKeyId = CK.CK_INVALID_HANDLE; ulong privKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKeyPair(pkcs11, 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 = pkcs11.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 ulong signatureLen = 0; rv = pkcs11.C_SignRecover(session, sourceData, Convert.ToUInt64(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 = pkcs11.C_SignRecover(session, sourceData, Convert.ToUInt64(sourceData.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Do something interesting with signature // Initialize verification operation rv = pkcs11.C_VerifyRecoverInit(session, ref mechanism, pubKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); // Get length of recovered data in first call ulong recoveredDataLen = 0; rv = pkcs11.C_VerifyRecover(session, signature, Convert.ToUInt64(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 = pkcs11.C_VerifyRecover(session, signature, Convert.ToUInt64(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(Convert.ToBase64String(sourceData) == Convert.ToBase64String(recoveredData)); rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); rv = pkcs11.C_DestroyObject(session, pubKeyId); 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 _03_WaitForSlotEventTest() { 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()); // Wait for a slot event ulong slot = 0; rv = pkcs11.C_WaitForSlotEvent(CKF.CKF_DONT_BLOCK, ref slot, IntPtr.Zero); if (rv != CKR.CKR_NO_EVENT) Assert.Fail(rv.ToString()); rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) Assert.Fail(rv.ToString()); } }