Как программно подписать код файла, когда требуется перекрестная подпись
Я столкнулся с необходимостью использовать SignerSignEx2() во время процесса отправки драйверов ядра на утверждение Microsoft.
SignerSignEx2()[^] используется для программной подписи этих драйверов. Корпорация Майкрософт требует использования Сертификат подписи кода EV (Extended Validation) [^] для драйверов ядра, ориентированных на Windows 10, и для этого требуется аппаратный маркер (Компания SafeNet eToekn[^], в большинстве случаев).
Мы получаем доступ к нашему токену с помощью разработанного нами инструмента, что делает его легким, в противном случае вам нужно каждый раз вводить пароль токена, который мы использовали SignTool.exe[^].
Однако для перекрестной подписи не существует большой документации о том, как использовать SignerSignEx2() (или более поздний SignerSignEx2 (), если уж на то пошло), чтобы объединить сертификат EV, который мы купили, с корневым сертификатом CA вместе с корневым сертификатом Microsoft.
Смотреть также эта страница о необходимости перекрестного знака.[^]
Что я уже пробовал:
В основном, следуя инструкциям в эта статья[^] и в Microsoft Docs документация. Эта статья руководит всем процессом использования SignerSignEx2().[^]
SignerSignEx2Function SignerSignEx2 = reinterpret_cast<SignerSignEx2Function>( GetProcAddress(msSignModule, "SignerSignEx2")); if (SignerSignEx2) { hr = SignerSignEx2( signerParams.dwFlags, signerParams.pSubjectInfo, signerParams.pSigningCert, signerParams.pSignatureInfo, signerParams.pProviderInfo, signerParams.dwTimestampFlags, signerParams.pszAlgorithmOid, signerParams.pwszTimestampURL, signerParams.pCryptAttrs, signerParams.pSipData, signerParams.pSignerContext, signerParams.pCryptoPolicy, signerParams.pReserved);
Есть объяснение о штамповке времени, но ничего о перекрестной подписи. Несколько попыток, которые мы предприняли, привели к тому, что корневой сертификат заменил наш собственный сертификат вместо того, чтобы быть добавленным к нему в цепочке.
Моя функция предполагает, что сертификат EV уже считан в память (что позволяет мне либо прочитать его из файла .pfx, либо из eToken как PCCERT_CONTEXT ). Как вы можете видеть, я попытался прочитать перекрестный сертификат (CROSSCERTPATH) и каким-то образом совмещение его и этой части не работает. Я тоже предопределения SIGNER_TIMESTAMP_AUTHENTICODE это URL-адрес с отметкой времени, и эта часть действительно работает.
HRESULT SignAppxPackage( _In_ PCCERT_CONTEXT signingCertContext, _In_ LPCWSTR packageFilePath) { // First read the root certificate PCCERT_CONTEXT Root = OpenCert(CROSSCERTPATH); HRESULT hr = S_OK; // Initialize the parameters for SignerSignEx2 DWORD signerIndex = 0; SIGNER_FILE_INFO fileInfo = {}; fileInfo.cbSize = sizeof(SIGNER_FILE_INFO); fileInfo.pwszFileName = packageFilePath; SIGNER_SUBJECT_INFO subjectInfo = {}; subjectInfo.cbSize = sizeof(SIGNER_SUBJECT_INFO); subjectInfo.pdwIndex = &signerIndex; subjectInfo.dwSubjectChoice = SIGNER_SUBJECT_FILE; subjectInfo.pSignerFileInfo = &fileInfo; SIGNER_CERT_STORE_INFO certStoreInfo = {}; certStoreInfo.cbSize = sizeof(SIGNER_CERT_STORE_INFO); certStoreInfo.dwCertPolicy = SIGNER_CERT_POLICY_STORE; certStoreInfo.pSigningCert = Root; // ??? not sure // certStoreInfo.hCertStore = Root; SIGNER_CERT cert = {}; cert.cbSize = sizeof(SIGNER_CERT); cert.dwCertChoice = SIGNER_CERT_POLICY_CHAIN; cert.pCertStoreInfo = &certStoreInfo; // The algidHash of the signature to be created must match the // hash algorithm used to create the app package SIGNER_SIGNATURE_INFO signatureInfo = {}; signatureInfo.cbSize = sizeof(SIGNER_SIGNATURE_INFO); signatureInfo.algidHash = CALG_SHA_256; signatureInfo.dwAttrChoice = SIGNER_NO_ATTR; SIGNER_SIGN_EX2_PARAMS signerParams = {}; signerParams.pSubjectInfo = &subjectInfo; signerParams.pSigningCert = &cert; signerParams.pSignatureInfo = &signatureInfo; signerParams.dwTimestampFlags = SIGNER_TIMESTAMP_AUTHENTICODE; signerParams.pszAlgorithmOid = NULL; signerParams.pwszTimestampURL = TIMESTAMPURL; APPX_SIP_CLIENT_DATA sipClientData = {}; sipClientData.pSignerParams = &signerParams; signerParams.pSipData = &sipClientData; // Type definition for invoking SignerSignEx2 via GetProcAddress typedef HRESULT(WINAPI *SignerSignEx2Function)( DWORD, PSIGNER_SUBJECT_INFO, PSIGNER_CERT, PSIGNER_SIGNATURE_INFO, PSIGNER_PROVIDER_INFO, DWORD, PCSTR, PCWSTR, PCRYPT_ATTRIBUTES, PVOID, PSIGNER_CONTEXT *, PVOID, PVOID); // Load the SignerSignEx2 function from MSSign32.dll HMODULE msSignModule = LoadLibraryEx( L"MSSign32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (msSignModule) { SignerSignEx2Function SignerSignEx2 = reinterpret_cast<SignerSignEx2Function>( GetProcAddress(msSignModule, "SignerSignEx2")); if (SignerSignEx2) { hr = SignerSignEx2( signerParams.dwFlags, signerParams.pSubjectInfo, signerParams.pSigningCert, signerParams.pSignatureInfo, signerParams.pProviderInfo, signerParams.dwTimestampFlags, signerParams.pszAlgorithmOid, signerParams.pwszTimestampURL, signerParams.pCryptAttrs, signerParams.pSipData, signerParams.pSignerContext, signerParams.pCryptoPolicy, signerParams.pReserved); } else { DWORD lastError = GetLastError(); hr = HRESULT_FROM_WIN32(lastError); } FreeLibrary(msSignModule); } else { DWORD lastError = GetLastError(); hr = HRESULT_FROM_WIN32(lastError); } // Free any state used during app package signing if (sipClientData.pAppxSipState) { sipClientData.pAppxSipState->Release(); } return hr; }
Nelek
Затем используйте инструменты, которые у вас есть, и сообщите об этом как о "не являющемся вопросом". И понизьте его, чтобы компенсировать несправедливое повышение.
Жалуясь на вещи, но ничего не делая против этого, вы мало что добавляете к ценностям, которые защищаете
Nelek
И на всякий случай... Я сказал "вроде бы общий и немного широкий ответ", вот почему я пошел на неполный. Я думаю, что он мог бы иметь больше информации, чтобы прояснить ситуацию, чтобы дать "быстрый" ответ
Michael Haephrati
Спасибо за ваши добрые комментарии, ребята. Конечно, я уточню. Сейчас 5:00 утра! Позже будет сделано.
Patrice T
вы должны спросить Мисс
Michael Haephrati
Ваш комментарий хорош практически для любого вопроса о продукте Microsoft, так что же вы хотите сказать? если я найду ответ, то выложу его здесь.