public void _02_SecurityOfficerLoginTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as SO (security officer) session.Login(CKU.CKU_SO, Settings.SecurityOfficerPin); // Do something interesting as security officer session.Logout(); } } }
public void _01_BasicMechanismListAndInfoTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Get supported mechanisms List <CKM> mechanisms = slot.GetMechanismList(); Assert.IsTrue(mechanisms.Count > 0); // Analyze first supported mechanism IMechanismInfo mechanismInfo = slot.GetMechanismInfo(mechanisms[0]); // Do something interesting with mechanism info Assert.IsNotNull(mechanismInfo.MechanismFlags); } }
public void _01_NormalUserLoginTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Do something interesting as normal user session.Logout(); } } }
public void _07_SessionInfoTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO (read-only) session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Get session details ISessionInfo sessionInfo = session.GetSessionInfo(); // Do something interesting with session info Assert.IsTrue(sessionInfo.SlotId == slot.SlotId); Assert.IsNotNull(sessionInfo.SessionFlags); } } }
public void _01_BasicSignAndVerifyRecoverTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Generate key pair IObjectHandle publicKey = null; IObjectHandle privateKey = null; Helpers.GenerateKeyPair(session, out publicKey, out privateKey); // Specify signing mechanism IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_RSA_PKCS); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); // Sign data byte[] signature = session.SignRecover(mechanism, privateKey, sourceData); // Do something interesting with signature // Verify signature bool isValid = false; byte[] recoveredData = session.VerifyRecover(mechanism, publicKey, signature, out isValid); // Do something interesting with verification result and recovered data Assert.IsTrue(isValid); Assert.IsTrue(ConvertUtils.BytesToBase64String(sourceData) == ConvertUtils.BytesToBase64String(recoveredData)); session.DestroyObject(privateKey); session.DestroyObject(publicKey); session.Logout(); } } }
public void _01_BasicSetPinTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Set new pin for the logged in user session.SetPin(Settings.NormalUserPin, Settings.NormalUserPin); session.Logout(); } } }
public void _01_BasicObjectFindingTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Let's create two objects so we can find something IObjectHandle objectHandle1 = Helpers.CreateDataObject(session); IObjectHandle objectHandle2 = Helpers.CreateDataObject(session); // Prepare attribute template that defines search criteria List <IObjectAttribute> objectAttributes = new List <IObjectAttribute>(); objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_CLASS, CKO.CKO_DATA)); objectAttributes.Add(Settings.Factories.ObjectAttributeFactory.CreateObjectAttribute(CKA.CKA_TOKEN, true)); // Initialize searching session.FindObjectsInit(objectAttributes); // Get search results List <IObjectHandle> foundObjects = session.FindObjects(2); // Terminate searching session.FindObjectsFinal(); // Do something interesting with found objects Assert.IsTrue(foundObjects.Count == 2); Assert.IsTrue((foundObjects[0].ObjectId != CK.CK_INVALID_HANDLE) && (foundObjects[1].ObjectId != CK.CK_INVALID_HANDLE)); session.DestroyObject(objectHandle2); session.DestroyObject(objectHandle1); session.Logout(); } } }
public void _03_InteractiveLoginTest() { using (IPkcs11 pkcs11 = _mockFactories.Pkcs11Factory.CreatePkcs11(_mockFactories, Settings.Pkcs11LibraryPath, Settings.AppType)) { ILibraryInfo libraryInfo = pkcs11.GetInfo(); if (libraryInfo.LibraryDescription != "Mock module" && libraryInfo.ManufacturerId != "Pkcs11Interop Project") { Assert.Inconclusive("Test cannot be executed with this PKCS#11 library"); } // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Login interactively via vendor specific function C_EjectToken ((IMockSession)session).InteractiveLogin(); } } }
public void _01_EncryptAndDecryptSinglePartTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Generate symetric key IObjectHandle generatedKey = Helpers.GenerateKey(session); // Generate random initialization vector byte[] iv = session.GenerateRandom(8); // Specify encryption mechanism with initialization vector as parameter IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_DES3_CBC, iv); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Our new password"); // Encrypt data byte[] encryptedData = session.Encrypt(mechanism, generatedKey, sourceData); // Do something interesting with encrypted data // Decrypt data byte[] decryptedData = session.Decrypt(mechanism, generatedKey, encryptedData); // Do something interesting with decrypted data Assert.IsTrue(ConvertUtils.BytesToBase64String(sourceData) == ConvertUtils.BytesToBase64String(decryptedData)); session.DestroyObject(generatedKey); session.Logout(); } } }
public void _01_BasicOperationStateTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO (read-only) session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Get operation state byte[] state = session.GetOperationState(); // Do something interesting with operation state Assert.IsNotNull(state); // Let's set state so the test is complete // Note that CK_INVALID_HANDLE is passed in as encryptionKey and authenticationKey session.SetOperationState(state, Settings.Factories.ObjectHandleFactory.CreateObjectHandle(), Settings.Factories.ObjectHandleFactory.CreateObjectHandle()); } } }
public void _01_DigestSinglePartTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Specify digesting mechanism IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_SHA_1); byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); // Digest data byte[] digest = session.Digest(mechanism, sourceData); // Do something interesting with digest value Assert.IsTrue(ConvertUtils.BytesToBase64String(digest) == "e1AsOh9IyGCa4hLN+2Od7jlnP14="); } } }
public void _01_BasicDeriveKeyTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Generate symetric key IObjectHandle baseKey = Helpers.GenerateKey(session); // Generate random data needed for key derivation byte[] data = session.GenerateRandom(24); // Specify mechanism parameters ICkKeyDerivationStringData mechanismParams = Settings.Factories.MechanismParamsFactory.CreateCkKeyDerivationStringData(data); // Specify derivation mechanism with parameters IMechanism mechanism = Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_XOR_BASE_AND_DATA, mechanismParams); // Derive key IObjectHandle derivedKey = session.DeriveKey(mechanism, baseKey, null); // Do something interesting with derived key Assert.IsTrue(derivedKey.ObjectId != CK.CK_INVALID_HANDLE); session.DestroyObject(baseKey); session.DestroyObject(derivedKey); session.Logout(); } } }
public void _02_GetInvalidAttributeValueTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RW session using (ISession session = slot.OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, Settings.NormalUserPin); // Generate key pair IObjectHandle publicKey = null; IObjectHandle privateKey = null; Helpers.GenerateKeyPair(session, out publicKey, out privateKey); // Prepare list of empty attributes we want to read List <CKA> attributes = new List <CKA>(); attributes.Add(CKA.CKA_LABEL); attributes.Add(CKA.CKA_VALUE); // Get value of specified attributes List <IObjectAttribute> objectAttributes = session.GetAttributeValue(privateKey, attributes); // Do something interesting with attribute value Assert.IsTrue(objectAttributes[0].GetValueAsString() == Settings.ApplicationName); Assert.IsTrue(objectAttributes[1].CannotBeRead == true); session.DestroyObject(privateKey); session.DestroyObject(publicKey); session.Logout(); } } }
public void _01_StructSizeListTest() { using (IPkcs11 pkcs11 = _mockFactories.Pkcs11Factory.CreatePkcs11(_mockFactories, Settings.Pkcs11LibraryPath, Settings.AppType)) { ILibraryInfo libraryInfo = pkcs11.GetInfo(); if (libraryInfo.LibraryDescription != "Mock module" && libraryInfo.ManufacturerId != "Pkcs11Interop Project") { Assert.Inconclusive("Test cannot be executed with this PKCS#11 library"); } // Obtain a list of unmanaged struct sizes via vendor specific function C_GetUnmanagedStructSizeList List <ulong> unmanagedSizes = ((IMockPkcs11)pkcs11).GetUnmanagedStructSizeList(); // Obtain a list of managed struct sizes List <ulong> managedSizes = GetManagedStructSizeList(); // Compare sizes of unmanaged and managed structs Assert.IsTrue(unmanagedSizes.Count == managedSizes.Count); for (int i = 0; i < unmanagedSizes.Count; i++) { Assert.IsTrue(unmanagedSizes[i] == managedSizes[i]); } } }
public void _02_CancelFunctionTest() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { // Find first slot with token present ISlot slot = Helpers.GetUsableSlot(pkcs11); // Open RO (read-only) session using (ISession session = slot.OpenSession(SessionType.ReadOnly)) { // Legacy functions should always return CKR_FUNCTION_NOT_PARALLEL try { session.CancelFunction(); } catch (Pkcs11Exception ex) { if (ex.RV != CKR.CKR_FUNCTION_NOT_PARALLEL) { throw; } } } } }
/// <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 using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, pkcs11Uri.ModulePath, AppType.MultiThreaded)) { // Obtain a list of all slots with tokens that match URI List <ISlot> slots = Pkcs11UriUtils.GetMatchingSlotList(pkcs11Uri, pkcs11, SlotsType.WithTokenPresent); if ((slots == null) || (slots.Count == 0)) { throw new Exception("None of the slots matches PKCS#11 URI"); } // Open read only session with first token that matches URI using (ISession session = slots[0].OpenSession(SessionType.ReadOnly)) { // Login as normal user with PIN acquired from URI session.Login(CKU.CKU_USER, pkcs11Uri.PinValue); // Get list of object attributes for the private key specified by URI List <IObjectAttribute> searchTemplate = Pkcs11UriUtils.GetObjectAttributes(pkcs11Uri, Settings.Factories.ObjectAttributeFactory); // Find private key specified by URI List <IObjectHandle> foundObjects = session.FindAllObjects(searchTemplate); if ((foundObjects == null) || (foundObjects.Count == 0)) { throw new Exception("None of the private keys match PKCS#11 URI"); } // Create signature with the private key specified by URI return(session.Sign(Settings.Factories.MechanismFactory.CreateMechanism(CKM.CKM_SHA1_RSA_PKCS), foundObjects[0], data)); } } }
public void _04_TokenInfoMatches() { using (IPkcs11 pkcs11 = Settings.Factories.Pkcs11Factory.CreatePkcs11(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType)) { List <ISlot> slots = pkcs11.GetSlotList(SlotsType.WithTokenPresent); Assert.IsTrue(slots != null && slots.Count > 0); ITokenInfo tokenInfo = slots[0].GetTokenInfo(); // Empty URI Pkcs11Uri pkcs11uri = new Pkcs11Uri(@"pkcs11:"); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Unknown path attribute in URI pkcs11uri = new Pkcs11Uri(@"pkcs11:vendor=foobar"); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // All attributes matching Pkcs11UriBuilder pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.Token = tokenInfo.Label; pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId; pkcs11UriBuilder.Serial = tokenInfo.SerialNumber; pkcs11UriBuilder.Model = tokenInfo.Model; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); Assert.IsTrue(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Token nonmatching pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.Token = "foobar"; pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId; pkcs11UriBuilder.Serial = tokenInfo.SerialNumber; pkcs11UriBuilder.Model = tokenInfo.Model; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Manufacturer nonmatching pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.Token = tokenInfo.Label; pkcs11UriBuilder.Manufacturer = "foobar"; pkcs11UriBuilder.Serial = tokenInfo.SerialNumber; pkcs11UriBuilder.Model = tokenInfo.Model; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Serial nonmatching pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.Token = tokenInfo.Label; pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId; pkcs11UriBuilder.Serial = "foobar"; pkcs11UriBuilder.Model = tokenInfo.Model; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); // Model nonmatching pkcs11UriBuilder = new Pkcs11UriBuilder(); pkcs11UriBuilder.Token = tokenInfo.Label; pkcs11UriBuilder.Manufacturer = tokenInfo.ManufacturerId; pkcs11UriBuilder.Serial = tokenInfo.SerialNumber; pkcs11UriBuilder.Model = "foobar"; pkcs11uri = pkcs11UriBuilder.ToPkcs11Uri(); Assert.IsFalse(Pkcs11UriUtils.Matches(pkcs11uri, tokenInfo)); } }
/// <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 ISlot GetUsableSlot(IPkcs11 pkcs11) { // Get list of available slots with token present List <ISlot> slots = pkcs11.GetSlotList(SlotsType.WithTokenPresent); Assert.IsNotNull(slots); Assert.IsTrue(slots.Count > 0); // First slot with token present is OK... ISlot matchingSlot = slots[0]; // ...unless there are matching criteria specified in Settings class if (Settings.TokenSerial != null || Settings.TokenLabel != null) { matchingSlot = null; foreach (ISlot slot in slots) { ITokenInfo tokenInfo = null; try { tokenInfo = slot.GetTokenInfo(); } catch (Pkcs11Exception ex) { if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT) { throw; } } if (tokenInfo == null) { continue; } if (!string.IsNullOrEmpty(Settings.TokenSerial)) { if (0 != string.Compare(Settings.TokenSerial, tokenInfo.SerialNumber, StringComparison.Ordinal)) { continue; } } if (!string.IsNullOrEmpty(Settings.TokenLabel)) { if (0 != string.Compare(Settings.TokenLabel, tokenInfo.Label, StringComparison.Ordinal)) { continue; } } matchingSlot = slot; break; } } Assert.IsTrue(matchingSlot != null, "Token matching criteria specified in Settings class is not present"); return(matchingSlot); }