public void _LL_12_04_Digest_Gost3411_94_Test() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (RutokenPkcs11Library pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { rv = pkcs11.C_Initialize(Settings.InitArgs80); if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED)) { Assert.Fail(rv.ToString()); } // Find first slot with token present 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()); } // Specify digesting mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_GOSTR3411); // Initialize digesting operation rv = pkcs11.C_DigestInit(session, ref mechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = TestData.Digest_Gost3411_SourceData; // Get length of digest value in first call 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); // Allocate array for digest value byte[] digest = new byte[digestLen]; // Get digest value in second call rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt64(sourceData.Length), digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] targetData = TestData.Digest_Gost3411_94_TargetData; Assert.IsTrue(Convert.ToBase64String(digest) == Convert.ToBase64String(targetData)); 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.InitArgs80); 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()); } // Генерация ключевой пары ГОСТ Р 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_30_01_SignJournalTest() { 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_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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(dataDigest.Length), signature, Convert.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(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.ToUInt32(journalDigest.Length), journalSignature, Convert.ToUInt32(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_32_01_ActivationPasswordTest() { Helpers.CheckPlatform(); 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_SO, Settings.SecurityOfficerPinArray, Convert.ToUInt32(Settings.SecurityOfficerPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // TODO: сделать вызов функций активации в правильном порядке // и с правильными данными // Загрузка ключа активации byte[] activationKey = new byte[32]; rv = pkcs11.C_EX_LoadActivationKey(session, activationKey); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение длины пароля активации NativeULong passwordLength = 0; rv = pkcs11.C_EX_GenerateActivationPassword(session, (NativeULong)ActivationPasswordNumber.GenerateNextPassword, null, ref passwordLength, (NativeULong)ActivationPasswordCharacterSet.CapsAndDigits); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(passwordLength > 0); // Генерация пароля активации byte[] password = new byte[passwordLength]; rv = pkcs11.C_EX_GenerateActivationPassword(session, (NativeULong)ActivationPasswordNumber.GenerateNextPassword, password, ref passwordLength, (NativeULong)ActivationPasswordCharacterSet.CapsAndDigits); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Установка пароля активации rv = pkcs11.C_EX_SetActivationPassword(slotId, password); 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.InitArgs80); 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()); } // Получение сохраненного тестового сертификата в формате 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_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()); } } }
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_09_01_BasicInitTokenAndPinTest() { 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); // Инициализация токена rv = pkcs11.C_InitToken(slotId, Settings.SecurityOfficerPinArray, Convert.ToUInt64(Settings.SecurityOfficerPinArray.Length), ConvertUtils.Utf8StringToBytes(Settings.TokenStdLabel, 32, 0x20)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Открытие 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_SO, Settings.SecurityOfficerPinArray, Convert.ToUInt64(Settings.SecurityOfficerPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Инициализация ПИН-кода пользователя rv = pkcs11.C_InitPIN(session, Settings.NormalUserPinArray, Convert.ToUInt64(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Завершение сессии rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _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.InitArgs81); 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.ToUInt64(Marshal.SizeOf(typeof(CK_RUTOKEN_INIT_PARAM))), UseRepairMode = 0, NewAdminPinLen = Convert.ToUInt64(Settings.SecurityOfficerPinArray.Length), NewUserPinLen = Convert.ToUInt64(Settings.NewUserPinArray.Length), MinAdminPinLen = 6, MinUserPinLen = 6, ChangeUserPINPolicy = Convert.ToUInt64(RutokenFlag.AdminChangeUserPin | RutokenFlag.UserChangeUserPin), MaxAdminRetryCount = Settings.MAX_ADMIN_RETRY_COUNT, MaxUserRetryCount = Settings.MAX_USER_RETRY_COUNT, LabelLen = Convert.ToUInt64(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.ToUInt64(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.ToUInt64(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.ToUInt64(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.ToUInt64(Settings.NormalUserPinArray.Length), Settings.NormalUserPinArray, Convert.ToUInt64(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_29_02_FlashWorkTest() { 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); // Получение расширенной информации о токене var tokenInfo = new CK_TOKEN_INFO_EXTENDED { SizeofThisStructure = Convert.ToUInt64(Marshal.SizeOf(typeof(CK_TOKEN_INFO_EXTENDED))) }; rv = pkcs11.C_EX_GetTokenInfoExtended(slotId, ref tokenInfo); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверка флага доступности Flash var isFlashMemoryAvailable = tokenInfo.Flags & (NativeULong)RutokenFlag.HasFlashDrive; Assert.IsTrue(Convert.ToBoolean(isFlashMemoryAvailable)); // Создание локальных PIN-кодов // (создание успешно только в случае их отсутствия) // Создание локального PIN-кода токена с ID = 0x03 rv = pkcs11.C_EX_SetLocalPIN(slotId, Settings.NormalUserPinArray, Settings.LocalPinArray, Settings.LocalPinId1); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Создание локального PIN-кода токена с ID = 0x1E rv = pkcs11.C_EX_SetLocalPIN(slotId, Settings.NormalUserPinArray, Settings.LocalPinArray, Settings.LocalPinId2); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Получение объема флеш-памяти NativeULong driveSize = 0; rv = pkcs11.C_EX_GetDriveSize(slotId, ref driveSize); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(driveSize > 0); // Полное удаление информации с флеш-памяти с последующим созданием // разделов в соответствии с переданными параметрами NativeULong volumeRwSize = driveSize / 2; NativeULong volumeRoSize = driveSize / 4; NativeULong volumeHiSize = driveSize / 8; NativeULong volumeCdSize = driveSize - volumeRwSize - volumeRoSize - volumeHiSize; var initParams = new CK_VOLUME_FORMAT_INFO_EXTENDED[4] { new CK_VOLUME_FORMAT_INFO_EXTENDED() { VolumeSize = volumeRwSize, AccessMode = (NativeULong)FlashAccessMode.Readwrite, VolumeOwner = (NativeULong)CKU.CKU_USER, Flags = 0 }, new CK_VOLUME_FORMAT_INFO_EXTENDED() { VolumeSize = volumeRoSize, AccessMode = (NativeULong)FlashAccessMode.Readonly, VolumeOwner = (NativeULong)CKU.CKU_SO, Flags = 0 }, new CK_VOLUME_FORMAT_INFO_EXTENDED() { VolumeSize = volumeHiSize, AccessMode = (NativeULong)FlashAccessMode.Hidden, VolumeOwner = Settings.LocalPinId1, Flags = 0 }, new CK_VOLUME_FORMAT_INFO_EXTENDED() { VolumeSize = volumeCdSize, AccessMode = (NativeULong)FlashAccessMode.Cdrom, VolumeOwner = Settings.LocalPinId2, Flags = 0 }, }; rv = pkcs11.C_EX_FormatDrive(slotId, (NativeULong)CKU.CKU_SO, Settings.SecurityOfficerPinArray, initParams); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Выделение памяти под информацию о разделах флеш-памяти NativeULong volumesInfoCount = 0; rv = pkcs11.C_EX_GetVolumesInfo(slotId, null, ref volumesInfoCount); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(volumesInfoCount > 0); var volumesInfo = new CK_VOLUME_INFO_EXTENDED[volumesInfoCount]; // Получение информации о разделах флеш-памяти rv = pkcs11.C_EX_GetVolumesInfo(slotId, volumesInfo, ref volumesInfoCount); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } foreach (var volumeInfo in volumesInfo) { Assert.IsTrue(volumeInfo.VolumeId != 0); } // Изменение атрибута доступа раздела флеш-памяти на постоянной основе // (до следующего изменения атрибутов) NativeULong volumeRo = 2; rv = pkcs11.C_EX_ChangeVolumeAttributes(slotId, (NativeULong)CKU.CKU_SO, Settings.SecurityOfficerPinArray, volumeRo, FlashAccessMode.Readwrite, permanent: true); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Временно изменить атрибут доступа к разделу флеш-памяти // (до первого извлечения устройства или следующего изменения атрибутов) NativeULong volumeRw = 1; rv = pkcs11.C_EX_ChangeVolumeAttributes(slotId, (NativeULong)CKU.CKU_USER, Settings.NormalUserPinArray, volumeRw, FlashAccessMode.Hidden, permanent: false); 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_31_01_SetAndGetLicenseTest() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (var 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); // Открытие 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_SO, Settings.SecurityOfficerPinArray, Convert.ToUInt32(Settings.NormalUserPinArray.Length)); if (rv != CKR.CKR_OK && rv != CKR.CKR_USER_ALREADY_LOGGED_IN) { Assert.Fail(rv.ToString()); } // Сохранение лицензии NativeULong licenseNum = 1; byte[] setlicense = new byte[Net.RutokenPkcs11Interop.Settings.DefaultLicenseLength]; (new Random()).NextBytes(setlicense); rv = pkcs11.C_EX_SetLicense(session, licenseNum, setlicense); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Чтение длины лицензии NativeULong licenseLen = 0; rv = pkcs11.C_EX_GetLicense(session, licenseNum, null, ref licenseLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(licenseLen > 0); Assert.AreEqual(Convert.ToUInt32(setlicense.Length), licenseLen); // Чтение лицензии byte[] getLicense = new byte[licenseLen]; rv = pkcs11.C_EX_GetLicense(session, licenseNum, getLicense, ref licenseLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Проверка на совпадение записанной и прочитанной лицензии Assert.IsTrue(Convert.ToBase64String(setlicense) == Convert.ToBase64String(getLicense)); rv = pkcs11.C_Logout(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }
public void _LL_25_26_03_KegKexp15KuznechikTwisted_Test() { Helpers.CheckPlatform(); CKR rv = CKR.CKR_OK; using (var pkcs11 = new RutokenPkcs11Library(Settings.Pkcs11LibraryPath)) { // Инициализация библиотеки rv = pkcs11.C_Initialize(Settings.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() { Helpers.CheckPlatform(); 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_12_01_Digest_SHA1_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()); } // 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()); } // Specify digesting mechanism (needs no parameter => no unamanaged memory is needed) CK_MECHANISM mechanism = CkmUtils.CreateMechanism(CKM.CKM_SHA_1); // Initialize digesting operation rv = pkcs11.C_DigestInit(session, ref mechanism); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } byte[] sourceData = ConvertUtils.Utf8StringToBytes("Hello world"); // Get length of digest value in first call NativeULong digestLen = 0; rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt32(sourceData.Length), null, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } Assert.IsTrue(digestLen > 0); // Allocate array for digest value byte[] digest = new byte[digestLen]; // Get digest value in second call rv = pkcs11.C_Digest(session, sourceData, Convert.ToUInt32(sourceData.Length), digest, ref digestLen); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } // Do something interesting with digest value rv = pkcs11.C_CloseSession(session); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } rv = pkcs11.C_Finalize(IntPtr.Zero); if (rv != CKR.CKR_OK) { Assert.Fail(rv.ToString()); } } }