/// <summary> /// Initializes a new instance of the CkPkcs5Pbkd2Params2 class. /// </summary> /// <param name='saltSource'>Source of the salt value (CKZ)</param> /// <param name='saltSourceData'>Data used as the input for the salt source</param> /// <param name='iterations'>Number of iterations to perform when generating each block of random data</param> /// <param name='prf'>Pseudo-random function to used to generate the key (CKP)</param> /// <param name='prfData'>Data used as the input for PRF in addition to the salt value</param> /// <param name='password'>Password to be used in the PBE key generation</param> public CkPkcs5Pbkd2Params2(NativeULong saltSource, byte[] saltSourceData, NativeULong iterations, NativeULong prf, byte[] prfData, byte[] password) { _lowLevelStruct.SaltSource = 0; _lowLevelStruct.SaltSourceData = IntPtr.Zero; _lowLevelStruct.SaltSourceDataLen = 0; _lowLevelStruct.Iterations = 0; _lowLevelStruct.Prf = prf; _lowLevelStruct.PrfData = IntPtr.Zero; _lowLevelStruct.PrfDataLen = 0; _lowLevelStruct.Password = IntPtr.Zero; _lowLevelStruct.PasswordLen = 0; _lowLevelStruct.SaltSource = saltSource; if (saltSourceData != null) { _lowLevelStruct.SaltSourceData = UnmanagedMemory.Allocate(saltSourceData.Length); UnmanagedMemory.Write(_lowLevelStruct.SaltSourceData, saltSourceData); _lowLevelStruct.SaltSourceDataLen = NativeLongUtils.ConvertFromInt32(saltSourceData.Length); } _lowLevelStruct.Iterations = iterations; _lowLevelStruct.Prf = prf; if (prfData != null) { _lowLevelStruct.PrfData = UnmanagedMemory.Allocate(prfData.Length); UnmanagedMemory.Write(_lowLevelStruct.PrfData, prfData); _lowLevelStruct.PrfDataLen = NativeLongUtils.ConvertFromInt32(prfData.Length); } if (password != null) { _lowLevelStruct.Password = UnmanagedMemory.Allocate(password.Length); UnmanagedMemory.Write(_lowLevelStruct.Password, password); _lowLevelStruct.PasswordLen = NativeLongUtils.ConvertFromInt32(password.Length); } }
public void _03_StructureParameterTest() { if (Platform.UnmanagedLongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } byte[] data = new byte[24]; System.Random rng = new Random(); rng.NextBytes(data); // Specify mechanism parameters // Note that we are allocating unmanaged memory that will have to be freed later CK_KEY_DERIVATION_STRING_DATA parameter = new CK_KEY_DERIVATION_STRING_DATA(); parameter.Data = UnmanagedMemory.Allocate(data.Length); UnmanagedMemory.Write(parameter.Data, data); parameter.Len = Convert.ToUInt32(data.Length); // Create mechanism with the structure as parameter // Note that CkmUtils.CreateMechanism() automaticaly copies mechanismParams into newly allocated unmanaged memory CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_XOR_BASE_AND_DATA, parameter); Assert.IsTrue(mechanism.Mechanism == (uint)CKM.CKM_XOR_BASE_AND_DATA); Assert.IsTrue(mechanism.Parameter != IntPtr.Zero); Assert.IsTrue(mechanism.ParameterLen == UnmanagedMemory.SizeOf(typeof(CK_KEY_DERIVATION_STRING_DATA))); // Free all unmanaged memory we previously allocated UnmanagedMemory.Free(ref parameter.Data); parameter.Len = 0; // Free unmanaged memory taken by mechanism parameter UnmanagedMemory.Free(ref mechanism.Parameter); mechanism.ParameterLen = 0; Assert.IsTrue(mechanism.Mechanism == (uint)CKM.CKM_XOR_BASE_AND_DATA); Assert.IsTrue(mechanism.Parameter == IntPtr.Zero); Assert.IsTrue(mechanism.ParameterLen == 0); }
public CkVendorVkoGostR3410_2012_512Params(ulong kdf, byte[] publicData, byte[] ukm) { _lowLevelStruct.kdf = 0; _lowLevelStruct.pPublicData = IntPtr.Zero; _lowLevelStruct.ulPublicDataLen = 0; _lowLevelStruct.pUKM = IntPtr.Zero; _lowLevelStruct.ulUKMLen = 0; if (publicData == null) { throw new ArgumentNullException(nameof(publicData)); } if (publicData.Length == 0) { throw new ArgumentOutOfRangeException(nameof(publicData), "Array has to be not null length"); } if (ukm == null) { throw new ArgumentNullException(nameof(ukm)); } if (ukm.Length == 0) { throw new ArgumentOutOfRangeException(nameof(ukm), "has to be not null length"); } _lowLevelStruct.kdf = (NativeULong)kdf; _lowLevelStruct.ulPublicDataLen = (NativeULong)publicData.Length; _lowLevelStruct.pPublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.pPublicData, publicData); _lowLevelStruct.ulUKMLen = (NativeULong)ukm.Length; _lowLevelStruct.pUKM = UnmanagedMemory.Allocate(ukm.Length); UnmanagedMemory.Write(_lowLevelStruct.pUKM, ukm); }
/// <summary> /// Initializes a new instance of the CkGostR3410DeriveParams class. /// </summary> /// <param name="kdf">Additional key diversification algorithm (CKD)</param> /// <param name="publicData">Data with public key of a receiver</param> /// <param name="ukm">UKM data</param> public CkGostR3410DeriveParams(NativeULong kdf, byte[] publicData, byte[] ukm) { _lowLevelStruct.Kdf = 0; _lowLevelStruct.PublicData = IntPtr.Zero; _lowLevelStruct.PublicDataLen = 0; _lowLevelStruct.UKM = IntPtr.Zero; _lowLevelStruct.UKMLen = 0; if (publicData == null) { throw new ArgumentNullException("publicData"); } if (publicData.Length != 64) { throw new ArgumentOutOfRangeException("publicData", "Array has to be 64 bytes long"); } if (ukm == null) { throw new ArgumentNullException("ukm"); } if (ukm.Length != 8) { throw new ArgumentOutOfRangeException("ukm", "Array has to be 8 bytes long"); } _lowLevelStruct.Kdf = kdf; _lowLevelStruct.PublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.PublicData, publicData); _lowLevelStruct.PublicDataLen = NativeLongUtils.ConvertFromInt32(publicData.Length); _lowLevelStruct.UKM = UnmanagedMemory.Allocate(ukm.Length); UnmanagedMemory.Write(_lowLevelStruct.UKM, ukm); _lowLevelStruct.UKMLen = NativeLongUtils.ConvertFromInt32(ukm.Length); }
/// <summary> /// Initializes a new instance of the CkOtpParams class. /// </summary> /// <param name='parameters'>List of OTP parameters</param> public CkOtpParams(List <CkOtpParam> parameters) { _lowLevelStruct.Params = IntPtr.Zero; _lowLevelStruct.Count = 0; if (parameters.Count > 0) { // Keep reference to parameters so GC will not free them while this object exists _parameters = parameters; // Allocate memory for parameters int ckOtpParamSize = UnmanagedMemory.SizeOf(typeof(CK_OTP_PARAM)); _lowLevelStruct.Params = UnmanagedMemory.Allocate(ckOtpParamSize * _parameters.Count); _lowLevelStruct.Count = (uint)_parameters.Count; // Copy paramaters to allocated memory for (int i = 0; i < _parameters.Count; i++) { IntPtr tempPointer = new IntPtr(_lowLevelStruct.Params.ToInt32() + (i * ckOtpParamSize)); UnmanagedMemory.Write(tempPointer, _parameters[i].ToLowLevelParams()); } } }
public void Set <T>(int binding, T data) where T : struct { ThrowIfDisposed(); Entry?entry = GetEntry(binding); if (entry == null) { throw new Exception( $"[{nameof(PushDataContainer)}] Binding '{binding}' unknown"); } #if DEBUG int size = Unsafe.SizeOf <T>(); if (size != entry.Value.Size) { throw new Exception( $"[{nameof(PushDataContainer)}] Binding '{binding}' has different size then provided data"); } #endif memory.Write(data, entry.Value.Offset); }
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); }
/// <summary> /// Initializes a new instance of the CkWtlsPrfParams class. /// </summary> /// <param name='digestMechanism'>Digest mechanism to be used (CKM)</param> /// <param name='seed'>Input seed</param> /// <param name='label'>Identifying label</param> /// <param name='outputLen'>Length in bytes that the output to be created shall have</param> public CkWtlsPrfParams(ulong digestMechanism, byte[] seed, byte[] label, ulong outputLen) { _lowLevelStruct.DigestMechanism = 0; _lowLevelStruct.Seed = IntPtr.Zero; _lowLevelStruct.SeedLen = 0; _lowLevelStruct.Label = IntPtr.Zero; _lowLevelStruct.LabelLen = 0; _lowLevelStruct.Output = IntPtr.Zero; _lowLevelStruct.OutputLen = IntPtr.Zero; _lowLevelStruct.DigestMechanism = digestMechanism; if (seed != null) { _lowLevelStruct.Seed = UnmanagedMemory.Allocate(seed.Length); UnmanagedMemory.Write(_lowLevelStruct.Seed, seed); _lowLevelStruct.SeedLen = Convert.ToUInt64(seed.Length); } if (label != null) { _lowLevelStruct.Label = UnmanagedMemory.Allocate(label.Length); UnmanagedMemory.Write(_lowLevelStruct.Label, label); _lowLevelStruct.LabelLen = Convert.ToUInt64(label.Length); } if (outputLen < 1) { throw new ArgumentException("Value has to be positive number", "outputLen"); } _lowLevelStruct.Output = UnmanagedMemory.Allocate(Convert.ToInt32(outputLen)); byte[] outputLenBytes = ConvertUtils.ULongToBytes(outputLen); _lowLevelStruct.OutputLen = UnmanagedMemory.Allocate(outputLenBytes.Length); UnmanagedMemory.Write(_lowLevelStruct.OutputLen, outputLenBytes); }
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 CkX942Dh1DeriveParams class. /// </summary> /// <param name='kdf'>Key derivation function used on the shared secret value (CKD)</param> /// <param name='otherInfo'>Some data shared between the two parties</param> /// <param name='publicData'>Other party's X9.42 Diffie-Hellman public key value</param> public CkX942Dh1DeriveParams(ulong kdf, byte[] otherInfo, byte[] publicData) { _lowLevelStruct.Kdf = 0; _lowLevelStruct.OtherInfoLen = 0; _lowLevelStruct.OtherInfo = IntPtr.Zero; _lowLevelStruct.PublicDataLen = 0; _lowLevelStruct.PublicData = IntPtr.Zero; _lowLevelStruct.Kdf = kdf; if (otherInfo != null) { _lowLevelStruct.OtherInfo = UnmanagedMemory.Allocate(otherInfo.Length); UnmanagedMemory.Write(_lowLevelStruct.OtherInfo, otherInfo); _lowLevelStruct.OtherInfoLen = Convert.ToUInt64(otherInfo.Length); } if (publicData != null) { _lowLevelStruct.PublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.PublicData, publicData); _lowLevelStruct.PublicDataLen = Convert.ToUInt64(publicData.Length); } }
/// <summary> /// Initializes a new instance of the CkPbeParams class. /// </summary> /// <param name='initVector'>8-byte initialization vector (IV), if an IV is required</param> /// <param name='password'>Password to be used in the PBE key generation</param> /// <param name='salt'>Salt to be used in the PBE key generation</param> /// <param name='iteration'>Number of iterations required for the generation</param> public CkPbeParams(byte[] initVector, byte[] password, byte[] salt, NativeULong iteration) { _lowLevelStruct.InitVector = IntPtr.Zero; _lowLevelStruct.Password = IntPtr.Zero; _lowLevelStruct.PasswordLen = 0; _lowLevelStruct.Salt = IntPtr.Zero; _lowLevelStruct.SaltLen = 0; _lowLevelStruct.Iteration = 0; if (initVector != null) { if (initVector.Length != 8) { throw new ArgumentOutOfRangeException("initVector", "Array has to be 8 bytes long"); } _lowLevelStruct.InitVector = UnmanagedMemory.Allocate(initVector.Length); UnmanagedMemory.Write(_lowLevelStruct.InitVector, initVector); } if (password != null) { _lowLevelStruct.Password = UnmanagedMemory.Allocate(password.Length); UnmanagedMemory.Write(_lowLevelStruct.Password, password); _lowLevelStruct.PasswordLen = ConvertUtils.UInt32FromInt32(password.Length); } if (salt != null) { _lowLevelStruct.Salt = UnmanagedMemory.Allocate(salt.Length); UnmanagedMemory.Write(_lowLevelStruct.Salt, salt); _lowLevelStruct.SaltLen = ConvertUtils.UInt32FromInt32(salt.Length); } _lowLevelStruct.Iteration = iteration; }
/// <summary> /// Initializes a new instance of the CkGostR3410KeyWrapParams class. /// </summary> /// <param name="wrapOID">Data with DER-encoding of the object identifier indicating the data object type of GOST 28147-89</param> /// <param name="ukm">Data with UKM</param> /// <param name="key">Key handle of a sender for wrapping operation or key handle of a receiver for unwrapping operation</param> public CkGostR3410KeyWrapParams(byte[] wrapOID, byte[] ukm, NativeULong key) { _lowLevelStruct.WrapOID = IntPtr.Zero; _lowLevelStruct.WrapOIDLen = 0; _lowLevelStruct.UKM = IntPtr.Zero; _lowLevelStruct.UKMLen = 0; _lowLevelStruct.Key = 0; if (wrapOID != null) { _lowLevelStruct.WrapOID = UnmanagedMemory.Allocate(wrapOID.Length); UnmanagedMemory.Write(_lowLevelStruct.WrapOID, wrapOID); _lowLevelStruct.WrapOIDLen = ConvertUtils.UInt64FromInt32(wrapOID.Length); } if (ukm != null) { _lowLevelStruct.UKM = UnmanagedMemory.Allocate(ukm.Length); UnmanagedMemory.Write(_lowLevelStruct.UKM, ukm); _lowLevelStruct.UKMLen = ConvertUtils.UInt64FromInt32(ukm.Length); } _lowLevelStruct.Key = key; }
/// <summary> /// Creates attribute of given type with ulong array value /// </summary> /// <param name="type">Attribute type</param> /// <param name="value">Attribute value</param> /// <returns>Attribute of given type with ulong array value</returns> public static CK_ATTRIBUTE CreateAttribute(ulong type, ulong[] value) { CK_ATTRIBUTE attribute = new CK_ATTRIBUTE(); attribute.type = type; if ((value != null) && (value.Length > 0)) { int ckmSize = UnmanagedMemory.SizeOf(typeof(ulong)); attribute.value = UnmanagedMemory.Allocate(ckmSize * value.Length); for (int i = 0; i < value.Length; i++) { IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckmSize)); UnmanagedMemory.Write(tempPointer, ConvertUtils.ULongToBytes(value[i])); } attribute.valueLen = Convert.ToUInt64(ckmSize * value.Length); } else { attribute.value = IntPtr.Zero; attribute.valueLen = 0; } return(attribute); }
/// <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)); } }
/// <summary> /// Creates attribute of given type with attribute array value /// </summary> /// <param name="type">Attribute type</param> /// <param name="value">Attribute value</param> /// <returns>Attribute of given type with attribute array value</returns> public static CK_ATTRIBUTE CreateAttribute(NativeULong type, CK_ATTRIBUTE[] value) { CK_ATTRIBUTE attribute = new CK_ATTRIBUTE(); attribute.type = type; if ((value != null) && (value.Length > 0)) { int ckAttributeSize = UnmanagedMemory.SizeOf(typeof(CK_ATTRIBUTE)); attribute.value = UnmanagedMemory.Allocate(ckAttributeSize * value.Length); for (int i = 0; i < value.Length; i++) { IntPtr tempPointer = new IntPtr(attribute.value.ToInt64() + (i * ckAttributeSize)); UnmanagedMemory.Write(tempPointer, value[i]); } attribute.valueLen = NativeLongUtils.ConvertFromInt32(ckAttributeSize * value.Length); } else { attribute.value = IntPtr.Zero; attribute.valueLen = 0; } return(attribute); }
/// <summary> /// Initializes a new instance of the CkX942Dh1DeriveParams class. /// </summary> /// <param name='kdf'>Key derivation function used on the shared secret value (CKD)</param> /// <param name='otherInfo'>Some data shared between the two parties</param> /// <param name='publicData'>Other party's X9.42 Diffie-Hellman public key value</param> public CkX942Dh1DeriveParams(NativeULong kdf, byte[] otherInfo, byte[] publicData) { _lowLevelStruct.Kdf = 0; _lowLevelStruct.OtherInfoLen = 0; _lowLevelStruct.OtherInfo = IntPtr.Zero; _lowLevelStruct.PublicDataLen = 0; _lowLevelStruct.PublicData = IntPtr.Zero; _lowLevelStruct.Kdf = kdf; if (otherInfo != null) { _lowLevelStruct.OtherInfo = UnmanagedMemory.Allocate(otherInfo.Length); UnmanagedMemory.Write(_lowLevelStruct.OtherInfo, otherInfo); _lowLevelStruct.OtherInfoLen = NativeLongUtils.ConvertFromInt32(otherInfo.Length); } if (publicData != null) { _lowLevelStruct.PublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.PublicData, publicData); _lowLevelStruct.PublicDataLen = NativeLongUtils.ConvertFromInt32(publicData.Length); } }
/// <summary> /// Initializes a new instance of the CkEcdh1DeriveParams class. /// </summary> /// <param name='kdf'>Key derivation function used on the shared secret value (CKD)</param> /// <param name='sharedData'>Some data shared between the two parties</param> /// <param name='publicData'>Other party's EC public key value</param> public CkEcdh1DeriveParams(NativeULong kdf, byte[] sharedData, byte[] publicData) { _lowLevelStruct.Kdf = 0; _lowLevelStruct.SharedDataLen = 0; _lowLevelStruct.SharedData = IntPtr.Zero; _lowLevelStruct.PublicDataLen = 0; _lowLevelStruct.PublicData = IntPtr.Zero; _lowLevelStruct.Kdf = kdf; if (sharedData != null) { _lowLevelStruct.SharedData = UnmanagedMemory.Allocate(sharedData.Length); UnmanagedMemory.Write(_lowLevelStruct.SharedData, sharedData); _lowLevelStruct.SharedDataLen = ConvertUtils.UInt64FromInt32(sharedData.Length); } if (publicData != null) { _lowLevelStruct.PublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.PublicData, publicData); _lowLevelStruct.PublicDataLen = ConvertUtils.UInt64FromInt32(publicData.Length); } }
public void _01_BasicDeriveKeyTest() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (Pkcs11Library pkcs11Library = new Pkcs11Library(Settings.Pkcs11LibraryPath)) { rv = pkcs11Library.C_Initialize(Settings.InitArgs81); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present NativeULong slotId = Helpers.GetUsableSlot(pkcs11Library); // Open RW session NativeULong session = CK.CK_INVALID_HANDLE; rv = pkcs11Library.C_OpenSession(slotId, (CKF.CKF_SERIAL_SESSION | CKF.CKF_RW_SESSION), IntPtr.Zero, IntPtr.Zero, ref session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Login as normal user rv = pkcs11Library.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, ConvertUtils.UInt64FromInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Generate symetric key NativeULong baseKeyId = CK.CK_INVALID_HANDLE; rv = Helpers.GenerateKey(pkcs11Library, 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 = pkcs11Library.C_GenerateRandom(session, data, ConvertUtils.UInt64FromInt32(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 = ConvertUtils.UInt64FromInt32(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 NativeULong derivedKey = CK.CK_INVALID_HANDLE; rv = pkcs11Library.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 = pkcs11Library.C_DestroyObject(session, baseKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_DestroyObject(session, derivedKey); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11Library.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
/// <summary> /// Initializes a new instance of the CkSkipjackRelayxParams class. /// </summary> /// <param name='oldWrappedX'>Old wrapper key</param> /// <param name='oldPassword'>Old user-supplied password</param> /// <param name='oldPublicData'>Old key exchange public key value</param> /// <param name='oldRandomA'>Old Ra data</param> /// <param name='newPassword'>New user-supplied password</param> /// <param name='newPublicData'>New key exchange public key value</param> /// <param name='newRandomA'>New Ra data</param> public CkSkipjackRelayxParams(byte[] oldWrappedX, byte[] oldPassword, byte[] oldPublicData, byte[] oldRandomA, byte[] newPassword, byte[] newPublicData, byte[] newRandomA) { _lowLevelStruct.OldWrappedXLen = 0; _lowLevelStruct.OldWrappedX = IntPtr.Zero; _lowLevelStruct.OldPasswordLen = 0; _lowLevelStruct.OldPassword = IntPtr.Zero; _lowLevelStruct.OldPublicDataLen = 0; _lowLevelStruct.OldPublicData = IntPtr.Zero; _lowLevelStruct.OldRandomLen = 0; _lowLevelStruct.OldRandomA = IntPtr.Zero; _lowLevelStruct.NewPasswordLen = 0; _lowLevelStruct.NewPassword = IntPtr.Zero; _lowLevelStruct.NewPublicDataLen = 0; _lowLevelStruct.NewPublicData = IntPtr.Zero; _lowLevelStruct.NewRandomLen = 0; _lowLevelStruct.NewRandomA = IntPtr.Zero; if (oldWrappedX != null) { _lowLevelStruct.OldWrappedX = UnmanagedMemory.Allocate(oldWrappedX.Length); UnmanagedMemory.Write(_lowLevelStruct.OldWrappedX, oldWrappedX); _lowLevelStruct.OldWrappedXLen = NativeLongUtils.ConvertFromInt32(oldWrappedX.Length); } if (oldPassword != null) { _lowLevelStruct.OldPassword = UnmanagedMemory.Allocate(oldPassword.Length); UnmanagedMemory.Write(_lowLevelStruct.OldPassword, oldPassword); _lowLevelStruct.OldPasswordLen = NativeLongUtils.ConvertFromInt32(oldPassword.Length); } if (oldPublicData != null) { _lowLevelStruct.OldPublicData = UnmanagedMemory.Allocate(oldPublicData.Length); UnmanagedMemory.Write(_lowLevelStruct.OldPublicData, oldPublicData); _lowLevelStruct.OldPublicDataLen = NativeLongUtils.ConvertFromInt32(oldPublicData.Length); } if (oldRandomA != null) { _lowLevelStruct.OldRandomA = UnmanagedMemory.Allocate(oldRandomA.Length); UnmanagedMemory.Write(_lowLevelStruct.OldRandomA, oldRandomA); _lowLevelStruct.OldRandomLen = NativeLongUtils.ConvertFromInt32(oldRandomA.Length); } if (newPassword != null) { _lowLevelStruct.NewPassword = UnmanagedMemory.Allocate(newPassword.Length); UnmanagedMemory.Write(_lowLevelStruct.NewPassword, newPassword); _lowLevelStruct.NewPasswordLen = NativeLongUtils.ConvertFromInt32(newPassword.Length); } if (newPublicData != null) { _lowLevelStruct.NewPublicData = UnmanagedMemory.Allocate(newPublicData.Length); UnmanagedMemory.Write(_lowLevelStruct.NewPublicData, newPublicData); _lowLevelStruct.NewPublicDataLen = NativeLongUtils.ConvertFromInt32(newPublicData.Length); } if (newRandomA != null) { _lowLevelStruct.NewRandomA = UnmanagedMemory.Allocate(newRandomA.Length); UnmanagedMemory.Write(_lowLevelStruct.NewRandomA, newRandomA); _lowLevelStruct.NewRandomLen = NativeLongUtils.ConvertFromInt32(newRandomA.Length); } }
/// <summary> /// Initializes a new instance of the CkSkipjackPrivateWrapParams class. /// </summary> /// <param name='password'>User-supplied password</param> /// <param name='publicData'>Other party's key exchange public key value</param> /// <param name='randomA'>Ra data</param> /// <param name='primeP'>Prime, p, value</param> /// <param name='baseG'>Base, g, value</param> /// <param name='subprimeQ'>Subprime, q, value</param> public CkSkipjackPrivateWrapParams(byte[] password, byte[] publicData, byte[] randomA, byte[] primeP, byte[] baseG, byte[] subprimeQ) { _lowLevelStruct.PasswordLen = 0; _lowLevelStruct.Password = IntPtr.Zero; _lowLevelStruct.PublicDataLen = 0; _lowLevelStruct.PublicData = IntPtr.Zero; _lowLevelStruct.PAndGLen = 0; _lowLevelStruct.QLen = 0; _lowLevelStruct.RandomLen = 0; _lowLevelStruct.RandomA = IntPtr.Zero; _lowLevelStruct.PrimeP = IntPtr.Zero; _lowLevelStruct.BaseG = IntPtr.Zero; _lowLevelStruct.SubprimeQ = IntPtr.Zero; if (password != null) { _lowLevelStruct.Password = UnmanagedMemory.Allocate(password.Length); UnmanagedMemory.Write(_lowLevelStruct.Password, password); _lowLevelStruct.PasswordLen = ConvertUtils.UInt64FromInt32(password.Length); } if (publicData != null) { _lowLevelStruct.PublicData = UnmanagedMemory.Allocate(publicData.Length); UnmanagedMemory.Write(_lowLevelStruct.PublicData, publicData); _lowLevelStruct.PublicDataLen = ConvertUtils.UInt64FromInt32(publicData.Length); } if (randomA != null) { _lowLevelStruct.RandomA = UnmanagedMemory.Allocate(randomA.Length); UnmanagedMemory.Write(_lowLevelStruct.RandomA, randomA); _lowLevelStruct.RandomLen = ConvertUtils.UInt64FromInt32(randomA.Length); } if ((primeP != null) && (baseG != null)) { if (primeP.Length != baseG.Length) { throw new ArgumentException("Length of primeP has to be the same as length of baseG"); } } if (primeP != null) { _lowLevelStruct.PrimeP = UnmanagedMemory.Allocate(primeP.Length); UnmanagedMemory.Write(_lowLevelStruct.PrimeP, primeP); _lowLevelStruct.PAndGLen = ConvertUtils.UInt64FromInt32(primeP.Length); } if (baseG != null) { _lowLevelStruct.BaseG = UnmanagedMemory.Allocate(baseG.Length); UnmanagedMemory.Write(_lowLevelStruct.BaseG, baseG); _lowLevelStruct.PAndGLen = ConvertUtils.UInt64FromInt32(baseG.Length); } if (subprimeQ != null) { _lowLevelStruct.SubprimeQ = UnmanagedMemory.Allocate(subprimeQ.Length); UnmanagedMemory.Write(_lowLevelStruct.SubprimeQ, subprimeQ); _lowLevelStruct.QLen = ConvertUtils.UInt64FromInt32(subprimeQ.Length); } }
public void _LL_09_02_ExtendedInitTokenAndPinTest() { if (Platform.NativeULongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (RutokenPkcs11Library pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { // Инициализация библиотеки rv = pkcs11.C_Initialize(Settings.InitArgs40); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); // Инициализация токена var rutokenInitParam = new CK_RUTOKEN_INIT_PARAM() { SizeofThisStructure = Convert.ToUInt32(Marshal.SizeOf(typeof(CK_RUTOKEN_INIT_PARAM))), UseRepairMode = 0, NewAdminPinLen = Convert.ToUInt32(Settings.SecurityOfficerPinArray.Length), NewUserPinLen = Convert.ToUInt32(Settings.NewUserPinArray.Length), MinAdminPinLen = 6, MinUserPinLen = 6, ChangeUserPINPolicy = Convert.ToUInt32(RutokenFlag.AdminChangeUserPin | RutokenFlag.UserChangeUserPin), MaxAdminRetryCount = Settings.MAX_ADMIN_RETRY_COUNT, MaxUserRetryCount = Settings.MAX_USER_RETRY_COUNT, LabelLen = Convert.ToUInt32(Settings.TokenStdLabelArray.Length), SmMode = 0 }; // Выделение памяти для IntPtr (можно не выделять, а использовать GCPinnedArray) // После использования нужно освободить память rutokenInitParam.NewAdminPin = UnmanagedMemory.Allocate(Settings.SecurityOfficerPinArray.Length); UnmanagedMemory.Write(rutokenInitParam.NewAdminPin, Settings.SecurityOfficerPinArray); rutokenInitParam.NewUserPin = UnmanagedMemory.Allocate(Settings.NewUserPinArray.Length); UnmanagedMemory.Write(rutokenInitParam.NewUserPin, Settings.NewUserPinArray); rutokenInitParam.TokenLabel = UnmanagedMemory.Allocate(Settings.TokenStdLabelArray.Length); UnmanagedMemory.Write(rutokenInitParam.TokenLabel, Settings.TokenStdLabelArray); // Расширенная инициализация токена rv = pkcs11.C_EX_InitToken(slotId, Settings.SecurityOfficerPinArray, ref rutokenInitParam); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Освобождение выделенной памяти UnmanagedMemory.Free(ref rutokenInitParam.NewAdminPin); rutokenInitParam.NewAdminPinLen = 0; UnmanagedMemory.Free(ref rutokenInitParam.NewUserPin); rutokenInitParam.NewUserPinLen = 0; UnmanagedMemory.Free(ref rutokenInitParam.TokenLabel); rutokenInitParam.LabelLen = 0; // Открытие 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()); } // Блокировка PIN-кода пользователя путем ввода неверного пин-кода нужное число раз for (NativeULong i = 0; i < Settings.MAX_USER_RETRY_COUNT; i++) { rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.WrongUserPinArray, Convert.ToUInt32(Settings.WrongUserPinArray.Length)); if (rv != CKR.CKR_PIN_INCORRECT && rv != CKR.CKR_PIN_LOCKED) { Assert.Fail(rv.ToString()); } } // Аутентификация администратора rv = pkcs11.C_Login(session, CKU.CKU_SO, Settings.SecurityOfficerPinArray, Convert.ToUInt32(Settings.SecurityOfficerPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Разблокировка PIN-кода пользователя rv = pkcs11.C_EX_UnblockUserPIN(session); 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_Login(session, CKU.CKU_USER, Settings.NewUserPinArray, Convert.ToUInt32(Settings.NewUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Изменение метки токена на "длинную" rv = pkcs11.C_EX_SetTokenName(session, Settings.TokenLongLabelArray); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение метки токена NativeULong tokenLabelLength = 0; rv = pkcs11.C_EX_GetTokenName(session, null, ref tokenLabelLength); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(tokenLabelLength > 0); byte[] tokenLabel = new byte[tokenLabelLength]; rv = pkcs11.C_EX_GetTokenName(session, tokenLabel, ref tokenLabelLength); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Сравнение записанной и полученной метки Assert.IsTrue(Convert.ToBase64String(Settings.TokenLongLabelArray) == Convert.ToBase64String(tokenLabel)); // Установка PIN-кода пользователя по-умолчанию rv = pkcs11.C_SetPIN(session, Settings.NormalUserPinArray, Convert.ToUInt32(Settings.NormalUserPinArray.Length), Settings.NormalUserPinArray, Convert.ToUInt32(Settings.NormalUserPinArray.Length)); 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_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()); } } }