public void _LL_30_01_SignJournalTest() { 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_MECHANISM digestMechanism = CkmUtils.CreateMechanism((CKM)Extended_CKM.CKM_GOSTR3411_12_512); rv = pkcs11.C_DigestInit(session, ref digestMechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Digest_Gost3411_SourceData; // Определение размера хэш-кода NativeULong dataDigestLen = 0; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), null, ref dataDigestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(dataDigestLen > 0); // Вычисление хэш-кода данных byte[] dataDigest = new byte[dataDigestLen]; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), dataDigest, ref dataDigestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары ГОСТ Р 34.10-2012 NativeULong dataPublicKeyId = CK.CK_INVALID_HANDLE; NativeULong dataPrivateKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost512KeyPair(pkcs11, session, ref dataPublicKeyId, ref dataPrivateKeyId, Settings.Gost512KeyPairId1); // Инициализация операции подписи данных по алгоритму ГОСТ Р 34.10-2012 CK_MECHANISM signMechanism = CkmUtils.CreateMechanism((CKM)Extended_CKM.CKM_GOSTR3410_512); rv = pkcs11.C_SignInit(session, ref signMechanism, dataPrivateKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Определение размера подписи данных NativeULong signatureLen = 0; rv = pkcs11.C_Sign(session, dataDigest, Convert.ToUInt64(dataDigest.Length), null, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(signatureLen > 0); byte[] signature = new byte[signatureLen]; // Подпись данных rv = pkcs11.C_Sign(session, dataDigest, Convert.ToUInt64(dataDigest.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация проверки подписи по алгоритму ГОСТ Р 34.10-2012 rv = pkcs11.C_VerifyInit(session, ref signMechanism, dataPublicKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверить подпись для данных rv = pkcs11.C_Verify(session, dataDigest, Convert.ToUInt64(dataDigest.Length), signature, Convert.ToUInt64(signature.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение длины журнала операций NativeULong journalLen = 0; rv = pkcs11.C_EX_GetJournal(slotId, null, ref journalLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(journalLen > 0); // Получение журнала операций byte[] journal = new byte[journalLen]; rv = pkcs11.C_EX_GetJournal(slotId, journal, ref journalLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары ГОСТ Р 34.10-2012 для подписи журнала NativeULong journalPublicKeyId = CK.CK_INVALID_HANDLE; NativeULong journalPrivateKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost512JournalKeyPair( pkcs11, session, ref journalPublicKeyId, ref journalPrivateKeyId); // Инициализация хэш-функции rv = pkcs11.C_DigestInit(session, ref digestMechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Определение размера хэш-кода для журнала NativeULong journalDigestLen = 0; rv = pkcs11.C_Digest(session, journal, Convert.ToUInt64(journal.Length), null, ref journalDigestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(journalDigestLen > 0); // Вычисление хэш-кода журнала byte[] journalDigest = new byte[journalDigestLen]; rv = pkcs11.C_Digest(session, journal, Convert.ToUInt64(journal.Length), journalDigest, ref journalDigestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация операции подписи данных по алгоритму ГОСТ Р 34.10-2012 rv = pkcs11.C_SignInit(session, ref signMechanism, journalPrivateKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Определение размера подписи журнала NativeULong journalSignatureLen = 0; rv = pkcs11.C_Sign(session, journalDigest, Convert.ToUInt64(journalDigest.Length), null, ref journalSignatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(journalSignatureLen > 0); byte[] journalSignature = new byte[journalSignatureLen]; // Подпись журнала rv = pkcs11.C_Sign(session, journalDigest, Convert.ToUInt64(journalDigest.Length), journalSignature, ref journalSignatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация проверки подписи по алгоритму ГОСТ Р 34.10-2012 rv = pkcs11.C_VerifyInit(session, ref signMechanism, journalPublicKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверить подпись журнала rv = pkcs11.C_Verify(session, journalDigest, Convert.ToUInt64(journalDigest.Length), journalSignature, Convert.ToUInt64(journalSignature.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Уничтожение созданных ключей rv = pkcs11.C_DestroyObject(session, dataPrivateKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, dataPublicKeyId); 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_33_02_ImportCertificateTest() { if (Platform.NativeULongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (var 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); // Открытие 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.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Получение сохраненного тестового сертификата в формате base64 string certificateBase64 = TestData.PKI_Certificate; // Перекодирование в DER byte[] certificateDer = PKIHelpers.GetDerFromBase64(certificateBase64); // Импорт сертификата NativeULong certificateId = CK.CK_INVALID_HANDLE; Helpers.PKI_ImportCertificate(pkcs11, session, certificateDer, ref certificateId); // Получение информации о сертификате IntPtr certificateInfo; NativeULong certificateInfoLen; rv = pkcs11.C_EX_GetCertificateInfoText(session, certificateId, out certificateInfo, out certificateInfoLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(certificateInfoLen > 0); // Получение массива символов // Далее нужно воспользоваться функцией ConvertUtils.BytesToUtf8String(), // чтобы получить строку byte[] certificateInfoArray = new byte[certificateInfoLen]; Marshal.Copy(certificateInfo, certificateInfoArray, 0, (int)certificateInfoLen); // Очистка памяти токена rv = pkcs11.C_EX_FreeBuffer(certificateInfo); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Удаление созданного сертификата rv = pkcs11.C_DestroyObject(session, certificateId); 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_33_01_CreateCSR_PKCS10Test() { if (Platform.NativeULongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (var 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); // Открытие 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.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары ГОСТ Р 34.10-2001 NativeULong pubKeyId = CK.CK_INVALID_HANDLE; NativeULong privKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGostKeyPair(pkcs11, session, ref pubKeyId, ref privKeyId, Settings.GostKeyPairId1); // Создание запроса на сертификат string[] dn = { "CN", "UTF8String:Иванов", "C", "RU", "2.5.4.5", "12312312312", "1.2.840.113549.1.9.1", "*****@*****.**", "ST", "UTF8String:Москва", }; string[] exts = { "keyUsage", "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment", "extendedKeyUsage", "1.2.643.2.2.34.6,1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4", "2.5.29.14", "ASN1:FORMAT:HEX,OCTETSTRING:FE117B93CEC6B5065E1613E155D3A9CA597C0F81", "1.2.643.100.111", "ASN1:UTF8String:СКЗИ \\\"Рутокен ЭЦП 2.0\\\"" }; IntPtr[] dnPtr = StringArrayHelpers.ConvertStringArrayToIntPtrArray(dn); IntPtr[] extsPtr = StringArrayHelpers.ConvertStringArrayToIntPtrArray(exts); IntPtr csr; NativeULong csrLength; rv = pkcs11.C_EX_CreateCSR(session, pubKeyId, dnPtr, (NativeULong)dnPtr.Length, out csr, out csrLength, privKeyId, null, 0, extsPtr, (NativeULong)extsPtr.Length); StringArrayHelpers.FreeUnmanagedIntPtrArray(dnPtr); StringArrayHelpers.FreeUnmanagedIntPtrArray(extsPtr); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } var csrString = PKIHelpers.GetBase64CSR(csr, (int)csrLength); Assert.IsTrue(csrString.Length > 0); // Очистка памяти, выделенной для полученного буфера rv = pkcs11.C_EX_FreeBuffer(csr); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, pubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_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_20_04_EncryptAndDecrypt_RSA_Test() { 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.InitArgs41); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); 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.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация ключей для RSA шифрования NativeULong privateKeyId = CK.CK_INVALID_HANDLE; NativeULong publicKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateRSAKeyPair(pkcs11, session, ref publicKeyId, ref privateKeyId, Settings.RsaKeyPairId); CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS); // Инициализация операции шифрования rv = pkcs11.C_EncryptInit(session, ref mechanism, publicKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Encrypt_RSA_SourceData; // Получение длины массива с зашифрованными данными NativeULong encryptedDataLen = 0; rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), null, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(encryptedDataLen > 0); // Выделение памяти для массива с зашифрованными данными byte[] encryptedData = new byte[encryptedDataLen]; // Получение зашифрованных данных rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), encryptedData, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация операции расишфрования rv = pkcs11.C_DecryptInit(session, ref mechanism, privateKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение длины массива с расшифрованными данными NativeULong decryptedDataLen = 0; rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), null, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(decryptedDataLen > 0); // Выделение памяти для массива с расшифрованными данными byte[] decryptedData = new byte[decryptedDataLen]; // Получение расшифрованных данных rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), decryptedData, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); // Уничтожение созданных ключей rv = pkcs11.C_DestroyObject(session, privateKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, publicKeyId); 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_20_08_EncryptAndDecrypt_Magma_CTR_ACPKM_Test() { 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.InitArgs41); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); 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.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация ключа для симметричного шифрования NativeULong keyId = CK.CK_INVALID_HANDLE; Helpers.GenerateMagmaKey(pkcs11, session, ref keyId); var random = new Random(); byte[] initVector = new byte[Settings.MAGMA_BLOCK_SIZE / 2]; random.NextBytes(initVector); byte[] mechaismParams = new byte[Settings.CTR_ACPKM_PERIOD_SIZE + Settings.MAGMA_BLOCK_SIZE / 2]; mechaismParams[0] = 0x01; mechaismParams[1] = 0x00; mechaismParams[2] = 0x00; mechaismParams[3] = 0x00; Array.Copy(initVector, 0, mechaismParams, Settings.CTR_ACPKM_PERIOD_SIZE, initVector.Length); CK_MECHANISM mechanism = CkmUtils.CreateMechanism((NativeULong)Extended_CKM.CKM_MAGMA_CTR_ACPKM, mechaismParams); // Инициализация операции шифрования rv = pkcs11.C_EncryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Encrypt_Gost28147_89_ECB_SourceData; // Получение длины массива с зашифрованными данными NativeULong encryptedDataLen = 0; rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), null, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(encryptedDataLen > 0); // Выделение памяти для массива с зашифрованными данными byte[] encryptedData = new byte[encryptedDataLen]; // Получение зашифрованных данных rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), encryptedData, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация операции расишфрования rv = pkcs11.C_DecryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение длины массива с расшифрованными данными NativeULong decryptedDataLen = 0; rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), null, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(decryptedDataLen > 0); // Выделение памяти для массива с расшифрованными данными byte[] decryptedData = new byte[decryptedDataLen]; // Получение расшифрованных данных rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), decryptedData, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_20_02_EncryptAndDecrypt_Gost28147_89_Stream_Test() { 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.InitArgs41); 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(pkcs11); 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()); } // Login as normal user rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Generate symetric key NativeULong keyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost28147_89Key(pkcs11, session, ref keyId); CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_GOST28147); byte[] sourceData = TestData.Encrypt_Gost28147_89_SourceData; byte[] encryptedData = null; byte[] decryptedData = null; // Multipart encryption functions C_EncryptUpdate and C_EncryptFinal can be used i.e. for encryption of streamed data using (MemoryStream inputStream = new MemoryStream(sourceData), outputStream = new MemoryStream()) { // Initialize encryption operation rv = pkcs11.C_EncryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Prepare buffer for source data part byte[] part = new byte[8]; // Prepare buffer for encrypted data part byte[] encryptedPart = new byte[8]; NativeULong encryptedPartLen = Convert.ToUInt32(encryptedPart.Length); // Read input stream with source data int bytesRead = 0; while ((bytesRead = inputStream.Read(part, 0, part.Length)) > 0) { // Encrypt each individual source data part encryptedPartLen = Convert.ToUInt32(encryptedPart.Length); rv = pkcs11.C_EncryptUpdate(session, part, Convert.ToUInt32(bytesRead), encryptedPart, ref encryptedPartLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Append encrypted data part to the output stream outputStream.Write(encryptedPart, 0, Convert.ToInt32(encryptedPartLen)); } // Get the length of last encrypted data part in first call byte[] lastEncryptedPart = null; NativeULong lastEncryptedPartLen = 0; rv = pkcs11.C_EncryptFinal(session, null, ref lastEncryptedPartLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Allocate array for the last encrypted data part lastEncryptedPart = new byte[lastEncryptedPartLen]; // Get the last encrypted data part in second call rv = pkcs11.C_EncryptFinal(session, lastEncryptedPart, ref lastEncryptedPartLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Append the last encrypted data part to the output stream outputStream.Write(lastEncryptedPart, 0, Convert.ToInt32(lastEncryptedPartLen)); // Read whole output stream to the byte array so we can compare results more easily encryptedData = outputStream.ToArray(); } // Multipart decryption functions C_DecryptUpdate and C_DecryptFinal can be used i.e. for decryption of streamed data using (MemoryStream inputStream = new MemoryStream(encryptedData), outputStream = new MemoryStream()) { // Initialize decryption operation rv = pkcs11.C_DecryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Prepare buffer for encrypted data part byte[] encryptedPart = new byte[8]; // Prepare buffer for decrypted data part byte[] part = new byte[8]; NativeULong partLen = Convert.ToUInt32(part.Length); // Read input stream with encrypted data int bytesRead = 0; while ((bytesRead = inputStream.Read(encryptedPart, 0, encryptedPart.Length)) > 0) { // Decrypt each individual encrypted data part partLen = Convert.ToUInt32(part.Length); rv = pkcs11.C_DecryptUpdate(session, encryptedPart, Convert.ToUInt32(bytesRead), part, ref partLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Append decrypted data part to the output stream outputStream.Write(part, 0, Convert.ToInt32(partLen)); } // Get the length of last decrypted data part in first call byte[] lastPart = null; NativeULong lastPartLen = 0; rv = pkcs11.C_DecryptFinal(session, null, ref lastPartLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Allocate array for the last decrypted data part lastPart = new byte[lastPartLen]; // Get the last decrypted data part in second call rv = pkcs11.C_DecryptFinal(session, lastPart, ref lastPartLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Append the last decrypted data part to the output stream outputStream.Write(lastPart, 0, Convert.ToInt32(lastPartLen)); // Read whole output stream to the byte array so we can compare results more easily decryptedData = outputStream.ToArray(); } Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); // In LowLevelAPI we have to free unmanaged memory taken by mechanism parameter (iv in this case) UnmanagedMemory.Free(ref mechanism.Parameter); mechanism.ParameterLen = 0; rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_20_03_EncryptAndDecrypt_Gost28147_89_CBC_Test() { 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.InitArgs41); 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(pkcs11); 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()); } // Login as normal user rv = pkcs11.C_Login(session, CKU.CKU_USER, Settings.NormalUserPinArray, Convert.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация ключа для симметричного шифрования NativeULong keyId = CK.CK_INVALID_HANDLE; Helpers.GenerateGost28147_89Key(pkcs11, session, ref keyId); // Получение исходных данных byte[] sourceData = TestData.Encrypt_CBC_Gost28147_89_ECB_SourceData; // Получение синхропосылки var random = new Random(); byte[] initVector = new byte[Settings.GOST28147_89_BLOCK_SIZE]; random.NextBytes(initVector); // Шифрование данных byte[] encryptedData = Helpers.CBC_Gost28147_89_Encrypt( pkcs11, session, sourceData, initVector, keyId); // Расшифрование данных byte[] decryptedData = Helpers.CBC_Gost28147_89_Decrypt( pkcs11, session, encryptedData, initVector, keyId); // Сравнение результатов Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_25_26_03_KegKexp15KuznechikTwisted_Test() { if (Platform.NativeULongSize != 4 || Platform.StructPackingSize != 1) { Assert.Inconclusive("Test cannot be executed on this platform"); } CKR rv = CKR.CKR_OK; using (var 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); // Открытие 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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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()); } } }
public void _LL_25_26_02_DeriveAndWrap_VKO_Gost3410_12_Test() { 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); // Открытие 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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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 _LL_20_06_EncryptAndDecrypt_Magma_ECB_Test() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (RutokenPkcs11Library pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { rv = pkcs11.C_Initialize(Settings.InitArgs41); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); 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.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Генерация ключа для симметричного шифрования NativeULong keyId = CK.CK_INVALID_HANDLE; Helpers.GenerateMagmaKey(pkcs11, session, ref keyId); CK_MECHANISM mechanism = CkmUtils.CreateMechanism((NativeULong)Extended_CKM.CKM_MAGMA_ECB); // Инициализация операции шифрования rv = pkcs11.C_EncryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Encrypt_Gost28147_89_ECB_SourceData; // Получение длины массива с зашифрованными данными NativeULong encryptedDataLen = 0; rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), null, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(encryptedDataLen > 0); // Выделение памяти для массива с зашифрованными данными byte[] encryptedData = new byte[encryptedDataLen]; // Получение зашифрованных данных rv = pkcs11.C_Encrypt(session, sourceData, Convert.ToUInt32(sourceData.Length), encryptedData, ref encryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация операции расишфрования rv = pkcs11.C_DecryptInit(session, ref mechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение длины массива с расшифрованными данными NativeULong decryptedDataLen = 0; rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), null, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(decryptedDataLen > 0); // Выделение памяти для массива с расшифрованными данными byte[] decryptedData = new byte[decryptedDataLen]; // Получение расшифрованных данных rv = pkcs11.C_Decrypt(session, encryptedData, Convert.ToUInt32(encryptedData.Length), decryptedData, ref decryptedDataLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(Convert.ToBase64String(sourceData) == Convert.ToBase64String(decryptedData)); rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_21_05_SignAndVerify_MagmaMac_Test() { 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.InitArgs81); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Установление соединения с Рутокен в первом доступном слоте NativeULong slotId = Helpers.GetUsableSlot(pkcs11); 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()); } byte[] sourceData = TestData.Digest_Gost3411_SourceData; // Генерация ключа для симметричного шифрования NativeULong keyId = CK.CK_INVALID_HANDLE; Helpers.GenerateMagmaKey(pkcs11, session, ref keyId, Helpers.KeyDestenation.ForSigVer); // Инициализация операции выработки имитовставки на ключе ГОСТ 34.12-2018 CK_MECHANISM signMechanism = CkmUtils.CreateMechanism((CKM)Extended_CKM.CKM_MAGMA_MAC); rv = pkcs11.C_SignInit(session, ref signMechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Определение размера подписи данных NativeULong signatureLen = 0; rv = pkcs11.C_Sign(session, sourceData, Convert.ToUInt64(sourceData.Length), null, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(signatureLen > 0); byte[] signature = new byte[signatureLen]; // Подпись данных rv = pkcs11.C_Sign(session, sourceData, Convert.ToUInt64(sourceData.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация проверки имитовставки на ключе ГОСТ 34.12-2018 rv = pkcs11.C_VerifyInit(session, ref signMechanism, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверить подпись для данных rv = pkcs11.C_Verify(session, sourceData, Convert.ToUInt64(sourceData.Length), signature, Convert.ToUInt64(signature.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, keyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_21_03_SignAndVerify_RSA_Test() { 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.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()); } // Инициализация хэш-функции SHA-1 CK_MECHANISM digestMechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA_1); rv = pkcs11.C_DigestInit(session, ref digestMechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Digest_Gost3411_SourceData; // Определение размера хэш-кода NativeULong digestLen = 0; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), null, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(digestLen > 0); // Вычисление хэш-кода данных byte[] digest = new byte[digestLen]; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Генерация ключевой пары RSA NativeULong pubKeyId = CK.CK_INVALID_HANDLE; NativeULong privKeyId = CK.CK_INVALID_HANDLE; Helpers.GenerateRSAKeyPair(pkcs11, session, ref pubKeyId, ref privKeyId, Settings.RsaKeyPairId); // Инициализация операции подписи данных по алгоритму RSA CK_MECHANISM signMechanism = CkmUtils.CreateMechanism(CKM.CKM_RSA_PKCS); rv = pkcs11.C_SignInit(session, ref signMechanism, privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Определение размера подписи данных NativeULong signatureLen = 0; rv = pkcs11.C_Sign(session, digest, Convert.ToUInt64(digest.Length), null, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(signatureLen > 0); byte[] signature = new byte[signatureLen]; // Подпись данных rv = pkcs11.C_Sign(session, digest, Convert.ToUInt64(digest.Length), signature, ref signatureLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Инициализация проверки подписи по алгоритму RSA rv = pkcs11.C_VerifyInit(session, ref signMechanism, pubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверка подписи для данных rv = pkcs11.C_Verify(session, digest, Convert.ToUInt64(digest.Length), signature, Convert.ToUInt64(signature.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, privKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_DestroyObject(session, pubKeyId); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }