I am trying to read mozilla.rsa file and parse the addon Id using C++.
My effort:
std::string rsaPath = xpiDir + "\\META-INF\\mozilla.rsa";
int rets = system(("CertUtil " + rsaPath + " | findstr " + "S=CA").c_str());
//
.....
My additional logic.............
.....
///
It's working fine on Windows 7 and later versions. But, there is no on Windows xp.
Is there any way to read addon id from mozilla.rsa file using C or C++?
Indeed, the file can be read and parsed with Windows CryptoAPI.
The file mozilla.rsa
of Mozilla extension is a PKCS#7 signature. On Linux it can be viewed with the following command:
openssl pkcs7 -print -inform der -in META-INF/mozilla.rsa
.
The signature file contains a chain of certificates. One of them has addon ID in its CN component of Subject field.
This Stack Overflow answer explains how to parse PKCS#7 data using CryptoAPI CryptQueryObject()
function.
For reference Microsoft Support has also more elaborate example of parsing: https://support.microsoft.com/en-us/help/323809/how-to-get-information-from-authenticode-signed-executables.
Using all these sources, one can compile the following code which would print the required ID:
#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);
The comparison szName[0] == L'{'
is not very reliable, it is only used for the sake of code simplicity. One might want to use better way of detecting addon ID value, e.g. regex.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With