Разобрать идентификатор аддона из файла mozilla.rsa - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь прочитать файл mozilla.rsa и проанализировать идентификатор дополнения с помощью C ++.

Мои усилия:

std::string rsaPath = xpiDir + "\\META-INF\\mozilla.rsa";

int rets = system(("CertUtil " + rsaPath + " | findstr " + "S=CA").c_str());

//
.....
My additional logic.............
.....
///

Отлично работает на Windows 7 и более поздних версиях. Но на Windows XP нет.

CertUtil

Есть ли способ прочитать идентификатор аддона из файла mozilla.rsa , используя C или C ++?

1 Ответ

0 голосов
/ 11 февраля 2019

Действительно, файл можно прочитать и проанализировать с помощью Windows CryptoAPI.

Файл mozilla.rsa с расширением Mozilla подпись PKCS # 7 . В Linux это можно просмотреть с помощью следующей команды:

openssl pkcs7 -print -inform der -in META-INF/mozilla.rsa.

Файл подписи содержит цепочку сертификатов. Один из них имеет идентификатор дополнения в своем компоненте CN поля Subject.

Этот ответ о переполнении стека объясняет, как анализировать данные PKCS # 7 с помощью функции CryptoAPI CryptQueryObject().

Для справки Служба поддержки Microsoft также имеет более сложный пример синтаксического анализа: https://support.microsoft.com/en-us/help/323809/how-to-get-information-from-authenticode-signed-executables.

Используя все эти источники, можно скомпилировать следующий код, который напечатал бы требуемый идентификатор:

#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")

...

std::string rsaPath = xpiDir + "\\META-INF\\mozilla.rsa";
std::wstring wRsaPath(rsaPath.begin(), rsaPath.end());

HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
BOOL res = CryptQueryObject(
    CERT_QUERY_OBJECT_FILE,
    wRsaPath.c_str(),
    CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
    CERT_QUERY_FORMAT_FLAG_BINARY,
    0,
    NULL,
    NULL,
    NULL,
    &hStore,
    &hMsg,
    NULL
);
if (!res) {
    std::cout << "Error decoding PKCS#7 file: " << GetLastError() << std::endl;
    return -1;
}

PCCERT_CONTEXT next_cert = NULL;
while ((next_cert = CertEnumCertificatesInStore(hStore, next_cert)) != NULL)
{
    WCHAR szName[1024];
    // Get subject name
    if (!CertGetNameString(
        next_cert,
        CERT_NAME_SIMPLE_DISPLAY_TYPE,
        0,
        NULL,
        szName,
        1024
    )) {
        std::cout << "CertGetNameString failed.\n";
        return -1;
    }

    // only process names looking like IDs, e.g. "CN={212b458b-a608-452b-be1f-a09658163cbf}"
    if (szName[0] == L'{') {
        std::wcout << szName << std::endl;
    }
}

CryptMsgClose(hMsg);
CertCloseStore(hStore, 0);

Сравнение szName[0] == L'{' не очень надежно, оно используется только для простоты кода. Кто-то может захотеть использовать лучший способ определения значения идентификатора аддона, например, регулярное выражение.

...