/// <summary> /// Reads value of attribute and returns it as NativeULong array /// </summary> /// <param name="attribute">Attribute whose value should be read</param> /// <param name="value">Location that receives attribute value</param> public static void ConvertValue(ref CK_ATTRIBUTE attribute, out NativeULong[] value) { int ckmSize = UnmanagedMemory.SizeOf(typeof(NativeULong)); int attrCount = ConvertUtils.UInt64ToInt32(attribute.valueLen) / ckmSize; int attrCountMod = ConvertUtils.UInt64ToInt32(attribute.valueLen) % ckmSize; if (attrCountMod != 0) { throw new Exception("Unable to convert attribute value to NativeULong array"); } if (attrCount == 0) { value = null; } else { NativeULong[] attrs = new NativeULong[attrCount]; for (int i = 0; i < attrCount; i++) { IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckmSize)); attrs[i] = ConvertUtils.UInt64FromBytes(UnmanagedMemory.Read(tempPointer, ckmSize)); } value = attrs; } }
/// <summary> /// Reads value of attribute and returns it as attribute array /// </summary> /// <param name="attribute">Attribute whose value should be read</param> /// <param name="value">Location that receives attribute value</param> public static void ConvertValue(ref CK_ATTRIBUTE attribute, out CK_ATTRIBUTE[] value) { int ckAttributeSize = UnmanagedMemory.SizeOf(typeof(CK_ATTRIBUTE)); int attrCount = ConvertUtils.UInt32ToInt32(attribute.valueLen) / ckAttributeSize; int attrCountMod = ConvertUtils.UInt32ToInt32(attribute.valueLen) % ckAttributeSize; if (attrCountMod != 0) { throw new Exception("Unable to convert attribute value to attribute array"); } if (attrCount == 0) { value = null; } else { CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[attrCount]; for (int i = 0; i < attrCount; i++) { IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckAttributeSize)); attrs[i] = (CK_ATTRIBUTE)UnmanagedMemory.Read(tempPointer, typeof(CK_ATTRIBUTE)); } value = attrs; } }
public void Benchmark_ReadWrite() { Int64 size = 100 * 1000000; using (SmartPtr p = UnmanagedMemory.AllocHGlobalExSmartPtr(size)) { string fileName = Path.GetTempFileName(); if (File.Exists(fileName)) { File.Delete(fileName); } DateTime start = DateTime.Now; using (BinaryWriter w = new BinaryWriter(File.Open(fileName, FileMode.CreateNew, FileAccess.Write))) { UnmanagedMemory.Write(w, p, size); } double time = (DateTime.Now - start).TotalSeconds; Console.WriteLine("{0:#,#} bytes written to disk in {1:0.00000} s, {2:#,#} b/s", size, time, size / time); start = DateTime.Now; using (BinaryReader r = new BinaryReader(File.Open(fileName, FileMode.Open, FileAccess.Read))) { UnmanagedMemory.Read(r, p, size); } time = (DateTime.Now - start).TotalSeconds; Console.WriteLine("{0:#,#} bytes read from disk in {1:0.00000} s, {2:#,#} b/s", size, time, size / time); File.Delete(fileName); } }
public void _10_CustomAttributeTest() { Helpers.CheckPlatform(); byte[] originalValue = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; // Create attribute without the value CK_ATTRIBUTE attr = CkaUtils.CreateAttribute(CKA.CKA_VALUE); Assert.IsTrue(attr.type == ConvertUtils.UInt64FromCKA(CKA.CKA_VALUE)); Assert.IsTrue(attr.value == IntPtr.Zero); Assert.IsTrue(attr.valueLen == 0); // Allocate unmanaged memory for attribute value.. attr.value = UnmanagedMemory.Allocate(originalValue.Length); // ..then set the value of attribute.. UnmanagedMemory.Write(attr.value, originalValue); // ..and finally set the length of attribute value. attr.valueLen = ConvertUtils.UInt64FromInt32(originalValue.Length); Assert.IsTrue(attr.type == ConvertUtils.UInt64FromCKA(CKA.CKA_VALUE)); Assert.IsTrue(attr.value != IntPtr.Zero); Assert.IsTrue(attr.valueLen == ConvertUtils.UInt64FromInt32(originalValue.Length)); // Read the value of attribute byte[] recoveredValue = UnmanagedMemory.Read(attr.value, ConvertUtils.UInt64ToInt32(attr.valueLen)); Assert.IsTrue(ConvertUtils.BytesToBase64String(originalValue) == ConvertUtils.BytesToBase64String(recoveredValue)); // Free attribute value UnmanagedMemory.Free(ref attr.value); attr.valueLen = 0; Assert.IsTrue(attr.type == ConvertUtils.UInt64FromCKA(CKA.CKA_VALUE)); Assert.IsTrue(attr.value == IntPtr.Zero); Assert.IsTrue(attr.valueLen == 0); }
/// <summary> /// Copies attribute value from unmanaged memory to managed byte array /// </summary> /// <param name="attribute">Attribute whose value should be read</param> /// <returns>Managed copy of attribute value</returns> private static byte[] ConvertValue(ref CK_ATTRIBUTE attribute) { byte[] value = null; if (attribute.value != IntPtr.Zero) { value = UnmanagedMemory.Read(attribute.value, Convert.ToInt32(attribute.valueLen)); } return(value); }
/// <summary> /// Initializes a new instance of the CkOtpSignatureInfo class. /// </summary> /// <param name='signature'>Signature value returned by all OTP mechanisms in successful calls to Sign method</param> public CkOtpSignatureInfo(byte[] signature) { if (signature == null) { throw new ArgumentNullException("signature"); } // PKCS#11 v2.20a1 page 14: // Since C_Sign and C_SignFinal follows the convention described in Section 11.2 of [1] // on producing output, a call to C_Sign (or C_SignFinal) with pSignature set to // NULL_PTR will return (in the pulSignatureLen parameter) the required number of bytes // to hold the CK_OTP_SIGNATURE_INFO structure as well as all the data in all its // CK_OTP_PARAM components. If an application allocates a memory block based on this // information, it shall therefore not subsequently de-allocate components of such a received // value but rather de-allocate the complete CK_OTP_PARAMS structure itself. A // Cryptoki library that is called with a non-NULL pSignature pointer will assume that it // points to a contiguous memory block of the size indicated by the pulSignatureLen // parameter. // Create CK_OTP_SIGNATURE_INFO from C_Sign or C_SignFinal output // TODO : This may require different low level delegate with IntPtr as output // but currently I am not aware of any implementation I could test with. IntPtr tmpSignature = IntPtr.Zero; try { tmpSignature = UnmanagedMemory.Allocate(signature.Length); UnmanagedMemory.Write(tmpSignature, signature); UnmanagedMemory.Read(tmpSignature, _lowLevelStruct); } finally { UnmanagedMemory.Free(ref tmpSignature); } // Read all CK_OTP_PARAMs from CK_OTP_SIGNATURE_INFO int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM)); for (int i = 0; i < ConvertUtils.UInt32ToInt32(_lowLevelStruct.Count); i++) { // Read CK_OTP_PARAM from CK_OTP_SIGNATURE_INFO IntPtr tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt64() + (i * ckOtpParamSize)); CK_OTP_PARAM ckOtpParam = new CK_OTP_PARAM(); UnmanagedMemory.Read(tempPointer, ckOtpParam); // Read members of CK_OTP_PARAM structure NativeULong ckOtpParamType = ckOtpParam.Type; byte[] ckOtpParamValue = UnmanagedMemory.Read(ckOtpParam.Value, ConvertUtils.UInt32ToInt32(ckOtpParam.ValueLen)); // Construct new high level CkOtpParam object (creates copy of CK_OTP_PARAM structure which is good) _params.Add(new CkOtpParam(ckOtpParamType, ckOtpParamValue)); } }
/// <summary> /// Get delegates with C_GetFunctionList function from the statically linked PKCS#11 library /// </summary> private void InitializeWithGetFunctionList() { IntPtr functionList = IntPtr.Zero; CKR rv = (CKR)Convert.ToUInt32(NativeMethods.C_GetFunctionList(out functionList)); if ((rv != CKR.CKR_OK) || (functionList == IntPtr.Zero)) { throw new Pkcs11Exception("C_GetFunctionList", rv); } CK_FUNCTION_LIST ckFunctionList = (CK_FUNCTION_LIST)UnmanagedMemory.Read(functionList, typeof(CK_FUNCTION_LIST)); Initialize(ckFunctionList); }
private void ReadInternal(BinaryReader r) { Version = new BdsVersion(); Version.Read(r); int serFmtVer = r.ReadInt32(); _nodesByteSize = r.ReadInt64(); _nodesCount = r.ReadInt64(); _nodeByteSize = (int)(_nodesByteSize / _nodesCount); Allocate(_nodesCount, _nodeByteSize); UnmanagedMemory.Read(r, _depthPtr, _nodesCount); UnmanagedMemory.Read(r, _nodesPtr, _nodesByteSize); ReadUserData(r); AfterRead(); }
/// <summary> /// Get delegates with C_GetFunctionList function from the dynamically loaded shared PKCS#11 library /// </summary> /// <param name="libraryHandle">Handle to the PKCS#11 library</param> private void InitializeWithGetFunctionList(IntPtr libraryHandle) { IntPtr cGetFunctionListPtr = UnmanagedLibrary.GetFunctionPointer(libraryHandle, "C_GetFunctionList"); C_GetFunctionListDelegate cGetFunctionList = UnmanagedLibrary.GetDelegateForFunctionPointer <C_GetFunctionListDelegate>(cGetFunctionListPtr); IntPtr functionList = IntPtr.Zero; CKR rv = (CKR)Convert.ToUInt32(cGetFunctionList(out functionList)); if ((rv != CKR.CKR_OK) || (functionList == IntPtr.Zero)) { throw new Pkcs11Exception("C_GetFunctionList", rv); } CK_FUNCTION_LIST ckFunctionList = (CK_FUNCTION_LIST)UnmanagedMemory.Read(functionList, typeof(CK_FUNCTION_LIST)); Initialize(ckFunctionList); }
static LutEvaluator7() { string fileName = LutPath; Exception exception = null; try { using (FileStream file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader r = new BinaryReader(file)) { BdsVersion version = new BdsVersion(); version.Read(r); UInt32 formatId = r.ReadUInt32(); UInt32 lutSize = r.ReadUInt32(); UInt32 lutByteSize = lutSize * 4; _lutPtr = UnmanagedMemory.AllocHGlobalExSmartPtr(lutByteSize); pLut = (UInt32 *)_lutPtr; UnmanagedMemory.Read(r, _lutPtr, lutByteSize); } } } catch (Exception e) { exception = e; } if (exception != null) { if (_lutPtr != null) { _lutPtr.Dispose(); _lutPtr = null; } pLut = (UInt32 *)IntPtr.Zero.ToPointer(); // If IO error occured leave the class uninitialized. This is a normal case for table generation. // If the application tries to use an uninitialized class, an exception will be thrown somewhere. // Otherwise rethrow the exception. if (!(exception is IOException)) { throw exception; } } }
public void GetNode(Int64 nodeIdx, void *node) { // Do only an assertion to get the max. performance Debug.Assert(nodeIdx < _nodesCount, "Index out of range"); if (_nodesPtr != null) { byte *p = ((byte *)_nodesPtr) + nodeIdx * _nodeByteSize; byte *n = (byte *)node; for (int i = 0; i < _nodeByteSize; ++i) { n[i] = p[i]; } } else { _fdaReader.BaseStream.Seek(this._nodesFilePos + nodeIdx * _nodeByteSize, SeekOrigin.Begin); UnmanagedMemory.Read(_fdaReader, new IntPtr(node), _nodeByteSize); } }
public void _01_AllocateAndFreeTest() { Helpers.CheckPlatform(); byte[] originalValue = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; byte[] recoveredValue = null; IntPtr ptr = IntPtr.Zero; ptr = UnmanagedMemory.Allocate(originalValue.Length); Assert.IsTrue(ptr != IntPtr.Zero); UnmanagedMemory.Write(ptr, originalValue); recoveredValue = UnmanagedMemory.Read(ptr, originalValue.Length); Assert.IsTrue(recoveredValue != null); Assert.IsTrue(ConvertUtils.BytesToBase64String(originalValue) == ConvertUtils.BytesToBase64String(recoveredValue)); UnmanagedMemory.Free(ref ptr); Assert.IsTrue(ptr == IntPtr.Zero); }
void DoTestReadWrite(IntPtr p, Int64 size) { MemoryStream ms = new MemoryStream(); BinaryWriter w = new BinaryWriter(ms); UnmanagedMemory.Write(w, p, size); byte[] buffer = ms.ToArray(); ms = new MemoryStream(buffer); using (SmartPtr p1 = UnmanagedMemory.AllocHGlobalExSmartPtr(size)) { BinaryReader r = new BinaryReader(ms); UnmanagedMemory.Read(r, p1.Ptr, size); byte *pBytes = (byte *)p; byte *pBytes1 = (byte *)p1; for (Int64 i = 0; i < size; ++i) { Assert.AreEqual(pBytes[i], pBytes1[i], String.Format("Values differ at pos {0}, size {1}", i, size)); } p1.Dispose(); } }
public void _01_AllocateAndFreeTest() { if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } byte[] originalValue = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; byte[] recoveredValue = null; IntPtr ptr = IntPtr.Zero; ptr = UnmanagedMemory.Allocate(originalValue.Length); Assert.IsTrue(ptr != IntPtr.Zero); UnmanagedMemory.Write(ptr, originalValue); recoveredValue = UnmanagedMemory.Read(ptr, originalValue.Length); Assert.IsTrue(recoveredValue != null); Assert.IsTrue(Convert.ToBase64String(originalValue) == Convert.ToBase64String(recoveredValue)); UnmanagedMemory.Free(ref ptr); Assert.IsTrue(ptr == IntPtr.Zero); }
public void _10_CustomAttributeTest() { if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } byte[] originalValue = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; // Create attribute without the value CK_ATTRIBUTE attr = CkaUtils.CreateAttribute(CKA.CKA_VALUE); Assert.IsTrue(attr.type == (uint)CKA.CKA_VALUE); Assert.IsTrue(attr.value == IntPtr.Zero); Assert.IsTrue(attr.valueLen == 0); // Allocate unmanaged memory for attribute value.. attr.value = UnmanagedMemory.Allocate(originalValue.Length); // ..then set the value of attribute.. UnmanagedMemory.Write(attr.value, originalValue); // ..and finally set the length of attribute value. attr.valueLen = (uint)originalValue.Length; Assert.IsTrue(attr.type == (uint)CKA.CKA_VALUE); Assert.IsTrue(attr.value != IntPtr.Zero); Assert.IsTrue(attr.valueLen == originalValue.Length); // Read the value of attribute byte[] recoveredValue = UnmanagedMemory.Read(attr.value, Convert.ToInt32(attr.valueLen)); Assert.IsTrue(Convert.ToBase64String(originalValue) == Convert.ToBase64String(recoveredValue)); // Free attribute value UnmanagedMemory.Free(ref attr.value); attr.valueLen = 0; Assert.IsTrue(attr.type == (uint)CKA.CKA_VALUE); Assert.IsTrue(attr.value == IntPtr.Zero); Assert.IsTrue(attr.valueLen == 0); }
/// <summary> /// Initializes a new instance of the CkOtpSignatureInfo class. /// </summary> /// <param name='signature'>Signature value returned by all OTP mechanisms in successful calls to Sign method</param> public CkOtpSignatureInfo(byte[] signature) { if (signature == null) { return; } int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM)); if (signature.Length % ckOtpParamSize != 0) { throw new ArgumentException("Invalid array length", "signature"); } // Copy signature to unmanaged memory _signature = UnmanagedMemory.Allocate(signature.Length); UnmanagedMemory.Write(_signature, signature); // Read CK_OTP_SIGNATURE_INFO from unmanaged memory UnmanagedMemory.Read(_signature, _lowLevelStruct); for (int i = 0; i < _lowLevelStruct.Count; i++) { // Read CK_OTP_PARAM from CK_OTP_SIGNATURE_INFO IntPtr tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt32() + (i * ckOtpParamSize)); CK_OTP_PARAM ckOtpParam = new CK_OTP_PARAM(); UnmanagedMemory.Read(tempPointer, ckOtpParam); // Read members of CK_OTP_PARAM structure uint ckOtpParamType = ckOtpParam.Type; byte[] ckOtpParamValue = UnmanagedMemory.Read(ckOtpParam.Value, (int)ckOtpParam.ValueLen); // Construct high level CkOtpParam class _params.Add(new CkOtpParam(ckOtpParamType, ckOtpParamValue)); } }
public void _LL_25_26_02_DeriveAndWrap_VKO_Gost3410_12_Test() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (RutokenPkcs11Library pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { // Инициализация библиотеки rv = pkcs11.C_Initialize(Settings.InitArgs81); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); // Открытие RW сессии NativeULong 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()); } // Выполнение аутентификации пользователя rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация параметра для структуры типа CK_GOSTR3410_DERIVE_PARAMS // для выработки общего ключа byte[] ukm = new byte[Settings.UKM_LENGTH]; rv = pkcs11.C_GenerateRandom(session, ukm, Convert.ToUInt64(ukm.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация значения сессионного ключа byte[] sessionKeyValue = new byte[Settings.GOST_28147_KEY_SIZE]; rv = pkcs11.C_GenerateRandom(session, sessionKeyValue, Convert.ToUInt64(sessionKeyValue.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары ГОСТ Р 34.10-2012 отправителя NativeULong senderPubKeyId = CK.CK_INVALID_HANDLE; NativeULong senderPrivKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost512KeyPair(pkcs11, session, ref senderPubKeyId, ref senderPrivKeyId, Settings.Gost512KeyPairId1); // Генерация ключевой пары ГОСТ Р 34.10-2012 получателя NativeULong recipientPubKeyId = CK.CK_INVALID_HANDLE; NativeULong recipientPrivKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost512KeyPair(pkcs11, session, ref recipientPubKeyId, ref recipientPrivKeyId, Settings.Gost512KeyPairId2); // Выработка общего ключа на стороне отправителя NativeULong senderDerivedKeyId = CK.CK_INVALID_HANDLE; Helpers.Derive_GostR3410_12_Key(pkcs11, session, recipientPubKeyId, senderPrivKeyId, ukm, ref senderDerivedKeyId); // Шаблон для создания маскируемого ключа CK_ATTRIBUTE[] sessionKeyTemplate = new CK_ATTRIBUTE[9]; sessionKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); sessionKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.WrappedGost28147_89KeyLabel); sessionKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GOST28147); sessionKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, false); sessionKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_MODIFIABLE, true); sessionKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, true); sessionKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_VALUE, sessionKeyValue); sessionKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true); sessionKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, false); // Выработка ключа, который будет замаскирован NativeULong sessionKeyId = CK.CK_INVALID_HANDLE; rv = pkcs11.C_CreateObject(session, sessionKeyTemplate, Convert.ToUInt64(sessionKeyTemplate.Length), ref sessionKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(sessionKeyId != CK.CK_INVALID_HANDLE); // Определение параметров механизма маскирования // В LowLevelAPI выделенная для параметров память должны быть освобождена после использования CK_KEY_DERIVATION_STRING_DATA wrapMechanismParams = new CK_KEY_DERIVATION_STRING_DATA(); wrapMechanismParams.Data = UnmanagedMemory.Allocate(ukm.Length); UnmanagedMemory.Write(wrapMechanismParams.Data, ukm); wrapMechanismParams.Len = Convert.ToUInt64(ukm.Length); CK_MECHANISM wrapMechanism = CkmUtils.CreateMechanism(CKM.CKM_GOST28147_KEY_WRAP, wrapMechanismParams); // Получение длины маскированного ключа NativeULong wrappedKeyLen = 0; rv = pkcs11.C_WrapKey(session, ref wrapMechanism, senderDerivedKeyId, sessionKeyId, null, ref wrappedKeyLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(wrappedKeyLen > 0); byte[] wrappedKey = new byte[wrappedKeyLen]; // Маскирование ключа на общем ключе, выработанном на стороне отправителя rv = pkcs11.C_WrapKey(session, ref wrapMechanism, senderDerivedKeyId, sessionKeyId, wrappedKey, ref wrappedKeyLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Выработка общего ключа на стороне получателя NativeULong recipientDerivedKeyId = CK.CK_INVALID_HANDLE; Helpers.Derive_GostR3410_12_Key(pkcs11, session, senderPubKeyId, recipientPrivKeyId, ukm, ref recipientDerivedKeyId); // Шаблон демаскированного ключа CK_ATTRIBUTE[] unwrappedKeyTemplate = new CK_ATTRIBUTE[8]; unwrappedKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); unwrappedKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.UnwrappedGost28147_89KeyLabel); unwrappedKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GOST28147); unwrappedKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, false); unwrappedKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_MODIFIABLE, true); unwrappedKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, false); unwrappedKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true); unwrappedKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, false); // Демаскирование сессионного ключа с помощью общего выработанного // ключа на стороне получателя NativeULong unwrappedKeyId = 0; rv = pkcs11.C_UnwrapKey(session, ref wrapMechanism, recipientDerivedKeyId, wrappedKey, wrappedKeyLen, unwrappedKeyTemplate, Convert.ToUInt64(unwrappedKeyTemplate.Length), ref unwrappedKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } CK_ATTRIBUTE[] valueTemplate = new CK_ATTRIBUTE[1]; valueTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_VALUE); // In LowLevelAPI we have to allocate unmanaged memory for attribute value valueTemplate[0].value = UnmanagedMemory.Allocate(Convert.ToInt32(32)); valueTemplate[0].valueLen = 32; // Get attribute value in second call rv = pkcs11.C_GetAttributeValue(session, unwrappedKeyId, valueTemplate, Convert.ToUInt64(valueTemplate.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Сравнение ключа byte[] unwrappedKey = UnmanagedMemory.Read(valueTemplate[0].value, Convert.ToInt32(valueTemplate[0].valueLen)); Assert.IsTrue(Convert.ToBase64String(sessionKeyValue) == Convert.ToBase64String(unwrappedKey)); // Освобождение выделенной памяти для параметров механизма UnmanagedMemory.Free(ref wrapMechanismParams.Data); wrapMechanismParams.Len = 0; UnmanagedMemory.Free(ref wrapMechanism.Parameter); wrapMechanism.ParameterLen = 0; // Удаляем созданные пары ключей rv = pkcs11.C_DestroyObject(session, senderPrivKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, senderPubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientPrivKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientPubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Удаляем сессионный ключ rv = pkcs11.C_DestroyObject(session, sessionKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Удаляем наследованные ключи rv = pkcs11.C_DestroyObject(session, senderDerivedKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientDerivedKeyId); 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_GetAttributeValueTest() { 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()); } // Prepare list of empty attributes we want to read CK_ATTRIBUTE[] template = new CK_ATTRIBUTE[2]; template[0] = CkaUtils.CreateAttribute(CKA.CKA_LABEL); template[1] = CkaUtils.CreateAttribute(CKA.CKA_VALUE); // Get size of each individual attribute value in first call rv = pkcs11.C_GetAttributeValue(session, objectId, template, Convert.ToUInt64(template.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // In LowLevelAPI we have to allocate unmanaged memory for attribute value for (int i = 0; i < template.Length; i++) { template[i].value = UnmanagedMemory.Allocate(Convert.ToInt32(template[i].valueLen)); } // Get attribute value in second call rv = pkcs11.C_GetAttributeValue(session, objectId, template, Convert.ToUInt64(template.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with attribute value byte[] ckaLabel = UnmanagedMemory.Read(template[0].value, Convert.ToInt32(template[0].valueLen)); Assert.IsTrue(Convert.ToBase64String(ckaLabel) == Convert.ToBase64String(Settings.ApplicationNameArray)); // 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, 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 _LL_25_26_03_KegKexp15KuznechikTwisted_Test() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (var pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { // Инициализация библиотеки rv = pkcs11.C_Initialize(Settings.InitArgs81); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); // Открытие RW сессии NativeULong 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()); } // Выполнение аутентификации пользователя rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация параметра для структуры типа CK_VENDOR_GOST_KEG_PARAMS // для выработки двойственного ключа экспорта byte[] ukm = new byte[Settings.KEG_256_UKM_LENGTH]; rv = pkcs11.C_GenerateRandom(session, ukm, Convert.ToUInt64(ukm.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация значения сессионного ключа byte[] sessionKeyValue = new byte[Settings.GOST_28147_KEY_SIZE]; rv = pkcs11.C_GenerateRandom(session, sessionKeyValue, Convert.ToUInt64(sessionKeyValue.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары ГОСТ Р 34.10-2012(256) отправителя NativeULong senderPubKeyId = CK.CK_INVALID_HANDLE; NativeULong senderPrivKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost256KeyPair(pkcs11, session, ref senderPubKeyId, ref senderPrivKeyId, Settings.GostKeyPairId1); // Генерация ключевой пары ГОСТ Р 34.10-2012(256) получателя NativeULong recipientPubKeyId = CK.CK_INVALID_HANDLE; NativeULong recipientPrivKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost256KeyPair(pkcs11, session, ref recipientPubKeyId, ref recipientPrivKeyId, Settings.GostKeyPairId2); // Выработка общего ключа на стороне отправителя NativeULong senderDerivedKeyId = CK.CK_INVALID_HANDLE; Helpers.DeriveKuznechikTwin_GostR3410_12_Key(pkcs11, session, recipientPubKeyId, senderPrivKeyId, ukm, ref senderDerivedKeyId); // Шаблон для создания маскируемого ключа CK_ATTRIBUTE[] sessionKeyTemplate = new CK_ATTRIBUTE[9]; sessionKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); sessionKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.WrappedKuznechikKeyLabel); sessionKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, (CKK)Extended_CKK.CKK_KUZNECHIK); sessionKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, false); sessionKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_MODIFIABLE, true); sessionKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, true); sessionKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_VALUE, sessionKeyValue); sessionKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true); sessionKeyTemplate[8] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, false); // Выработка ключа, который будет замаскирован NativeULong sessionKeyId = CK.CK_INVALID_HANDLE; rv = pkcs11.C_CreateObject(session, sessionKeyTemplate, Convert.ToUInt64(sessionKeyTemplate.Length), ref sessionKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(sessionKeyId != CK.CK_INVALID_HANDLE); // Генерация имитовставки для алгоритма экспорта ключей KExp15 byte[] kexp15Ukm = new byte[Settings.KEXP15_KUZNECHIK_TWIN_UKM_LENGTH]; rv = pkcs11.C_GenerateRandom(session, kexp15Ukm, Convert.ToUInt64(kexp15Ukm.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } CK_MECHANISM wrapMechanism = CkmUtils.CreateMechanism((NativeULong)Extended_CKM.CKM_KUZNECHIK_KEXP_15_WRAP, kexp15Ukm); // Получение длины маскированного ключа NativeULong wrappedKeyLen = 0; rv = pkcs11.C_WrapKey(session, ref wrapMechanism, senderDerivedKeyId, sessionKeyId, null, ref wrappedKeyLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(wrappedKeyLen > 0); byte[] wrappedKey = new byte[wrappedKeyLen]; // Маскирование ключа на общем ключе, выработанном на стороне отправителя rv = pkcs11.C_WrapKey(session, ref wrapMechanism, senderDerivedKeyId, sessionKeyId, wrappedKey, ref wrappedKeyLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Выработка общего ключа на стороне получателя NativeULong recipientDerivedKeyId = CK.CK_INVALID_HANDLE; Helpers.DeriveKuznechikTwin_GostR3410_12_Key(pkcs11, session, senderPubKeyId, recipientPrivKeyId, ukm, ref recipientDerivedKeyId); // Шаблон демаскированного ключа CK_ATTRIBUTE[] unwrappedKeyTemplate = new CK_ATTRIBUTE[8]; unwrappedKeyTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY); unwrappedKeyTemplate[1] = CkaUtils.CreateAttribute(CKA.CKA_LABEL, Settings.UnwrappedGost28147_89KeyLabel); unwrappedKeyTemplate[2] = CkaUtils.CreateAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_GOST28147); unwrappedKeyTemplate[3] = CkaUtils.CreateAttribute(CKA.CKA_TOKEN, false); unwrappedKeyTemplate[4] = CkaUtils.CreateAttribute(CKA.CKA_MODIFIABLE, true); unwrappedKeyTemplate[5] = CkaUtils.CreateAttribute(CKA.CKA_PRIVATE, false); unwrappedKeyTemplate[6] = CkaUtils.CreateAttribute(CKA.CKA_EXTRACTABLE, true); unwrappedKeyTemplate[7] = CkaUtils.CreateAttribute(CKA.CKA_SENSITIVE, false); // Демаскирование сессионного ключа с помощью общего выработанного // ключа на стороне получателя NativeULong unwrappedKeyId = 0; rv = pkcs11.C_UnwrapKey(session, ref wrapMechanism, recipientDerivedKeyId, wrappedKey, wrappedKeyLen, unwrappedKeyTemplate, Convert.ToUInt64(unwrappedKeyTemplate.Length), ref unwrappedKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } CK_ATTRIBUTE[] valueTemplate = new CK_ATTRIBUTE[1]; valueTemplate[0] = CkaUtils.CreateAttribute(CKA.CKA_VALUE); valueTemplate[0].value = UnmanagedMemory.Allocate(Convert.ToInt32(32)); valueTemplate[0].valueLen = 32; rv = pkcs11.C_GetAttributeValue(session, unwrappedKeyId, valueTemplate, Convert.ToUInt64(valueTemplate.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Сравнение ключа byte[] unwrappedKey = UnmanagedMemory.Read(valueTemplate[0].value, Convert.ToInt32(valueTemplate[0].valueLen)); Assert.IsTrue(Convert.ToBase64String(sessionKeyValue) == Convert.ToBase64String(unwrappedKey)); // Освобождение выделенной памяти под аттрибуты for (int i = 0; i < valueTemplate.Length; i++) { UnmanagedMemory.Free(ref valueTemplate[i].value); valueTemplate[i].valueLen = 0; } for (int i = 0; i < sessionKeyTemplate.Length; i++) { UnmanagedMemory.Free(ref sessionKeyTemplate[i].value); sessionKeyTemplate[i].valueLen = 0; } for (int i = 0; i < unwrappedKeyTemplate.Length; i++) { UnmanagedMemory.Free(ref unwrappedKeyTemplate[i].value); unwrappedKeyTemplate[i].valueLen = 0; } // Удаляем созданные пары ключей rv = pkcs11.C_DestroyObject(session, senderPrivKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, senderPubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientPrivKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientPubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Удаляем сессионный ключ rv = pkcs11.C_DestroyObject(session, sessionKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Удаляем наследованные ключи rv = pkcs11.C_DestroyObject(session, senderDerivedKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, recipientDerivedKeyId); 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()); } } }