зеркало из https://github.com/mozilla/gecko-dev.git
Bug 903135 - Updates to libmar needed to support B2G MAR signature verification. r=bbondy
This commit is contained in:
Родитель
dc4ba8bd44
Коммит
6a474042e5
|
@ -134,6 +134,26 @@ int mar_create(const char *dest,
|
|||
*/
|
||||
int mar_extract(const char *path);
|
||||
|
||||
#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary
|
||||
|
||||
/* Read the entire file (not a MAR file) into a newly-allocated buffer.
|
||||
* This function does not write to stderr. Instead, the caller should
|
||||
* write whatever error messages it sees fit. The caller must free the returned
|
||||
* buffer using free().
|
||||
*
|
||||
* @param filePath The path to the file that should be read.
|
||||
* @param maxSize The maximum valid file size.
|
||||
* @param data On success, *data will point to a newly-allocated buffer
|
||||
* with the file's contents in it.
|
||||
* @param size On success, *size will be the size of the created buffer.
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int mar_read_entire_file(const char * filePath,
|
||||
uint32_t maxSize,
|
||||
/*out*/ const uint8_t * *data,
|
||||
/*out*/ uint32_t *size);
|
||||
|
||||
/**
|
||||
* Verifies a MAR file by verifying each signature with the corresponding
|
||||
* certificate. That is, the first signature will be verified using the first
|
||||
|
@ -154,12 +174,10 @@ int mar_extract(const char *path);
|
|||
* a negative number if there was an error
|
||||
* a positive number if the signature does not verify
|
||||
*/
|
||||
#ifdef XP_WIN
|
||||
int mar_verify_signaturesW(MarFile *mar,
|
||||
int mar_verify_signatures(MarFile *mar,
|
||||
const uint8_t * const *certData,
|
||||
const uint32_t *certDataSizes,
|
||||
uint32_t certCount);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Reads the product info block from the MAR file's additional block section.
|
||||
|
|
|
@ -38,38 +38,6 @@ int get_mar_file_info(const char *path,
|
|||
uint32_t *offsetAdditionalBlocks,
|
||||
uint32_t *numAdditionalBlocks);
|
||||
|
||||
/**
|
||||
* Verifies a MAR file by verifying each signature with the corresponding
|
||||
* certificate. That is, the first signature will be verified using the first
|
||||
* certificate given, the second signature will be verified using the second
|
||||
* certificate given, etc. The signature count must exactly match the number of
|
||||
* certificates given, and all signature verifications must succeed.
|
||||
* This is only used by the signmar program when used with arguments to verify
|
||||
* a MAR. This should not be used to verify a MAR that will be extracted in the
|
||||
* same operation by updater code. This function prints the error message if
|
||||
* verification fails.
|
||||
*
|
||||
* @param pathToMAR The path of the MAR file whose signature should be
|
||||
* checked
|
||||
* @param certData Pointer to the first element in an array of certificate
|
||||
* file data.
|
||||
* @param certDataSizes Pointer to the first element in an array for size of
|
||||
* the cert data.
|
||||
* @param certNames Pointer to the first element in an array of certificate
|
||||
* names.
|
||||
* Used only if compiled with NSS support
|
||||
* @param certCount The number of elements in certData, certDataSizes,
|
||||
* and certNames
|
||||
* @return 0 on success
|
||||
* a negative number if there was an error
|
||||
* a positive number if the signature does not verify
|
||||
*/
|
||||
int mar_verify_signatures(const char *pathToMAR,
|
||||
const uint8_t * const *certData,
|
||||
const uint32_t *certDataSizes,
|
||||
const char * const *certNames,
|
||||
uint32_t certCount);
|
||||
|
||||
/**
|
||||
* Reads the product info block from the MAR file's additional block section.
|
||||
* The caller is responsible for freeing the fields in infoBlock
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#endif
|
||||
|
||||
#if !defined(NO_SIGN_VERIFY) && (!defined(XP_WIN) || defined(MAR_NSS))
|
||||
#include "cert.h"
|
||||
#include "pk11pub.h"
|
||||
int NSSInitCryptoContext(const char *NSSConfigDir);
|
||||
#endif
|
||||
|
||||
|
@ -120,15 +122,13 @@ int main(int argc, char **argv) {
|
|||
uint32_t certCount = 0;
|
||||
int32_t sigIndex = -1;
|
||||
|
||||
#if defined(XP_WIN) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY)
|
||||
HANDLE certFile;
|
||||
uint8_t *certBuffers[MAX_SIGNATURES];
|
||||
#endif
|
||||
#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \
|
||||
defined(XP_MACOSX))
|
||||
char* DERFilePaths[MAX_SIGNATURES];
|
||||
#if !defined(NO_SIGN_VERIFY)
|
||||
uint32_t fileSizes[MAX_SIGNATURES];
|
||||
uint32_t read;
|
||||
uint8_t* certBuffers[MAX_SIGNATURES];
|
||||
char* DERFilePaths[MAX_SIGNATURES];
|
||||
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
|
||||
CERTCertificate* certs[MAX_SIGNATURES];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
memset(certNames, 0, sizeof(certNames));
|
||||
|
@ -319,43 +319,68 @@ int main(int argc, char **argv) {
|
|||
return import_signature(argv[2], sigIndex, argv[3], argv[4]);
|
||||
|
||||
case 'v':
|
||||
|
||||
#if defined(XP_WIN) && !defined(MAR_NSS)
|
||||
if (certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
/* If the mar program was built using CryptoAPI, then read in the buffer
|
||||
containing the cert from disk. */
|
||||
certFile = CreateFileA(DERFilePaths[k], GENERIC_READ,
|
||||
FILE_SHARE_READ |
|
||||
FILE_SHARE_WRITE |
|
||||
FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0, NULL);
|
||||
if (INVALID_HANDLE_VALUE == certFile) {
|
||||
#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS)
|
||||
if (!NSSConfigDir || certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
fileSizes[k] = GetFileSize(certFile, NULL);
|
||||
certBuffers[k] = malloc(fileSizes[k]);
|
||||
if (!ReadFile(certFile, certBuffers[k], fileSizes[k], &read, NULL) ||
|
||||
fileSizes[k] != read) {
|
||||
CloseHandle(certFile);
|
||||
for (i = 0; i <= k; i++) {
|
||||
free(certBuffers[i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
CloseHandle(certFile);
|
||||
}
|
||||
|
||||
rv = mar_verify_signatures(argv[2], certBuffers, fileSizes,
|
||||
NULL, certCount);
|
||||
if (NSSInitCryptoContext(NSSConfigDir)) {
|
||||
fprintf(stderr, "ERROR: Could not initialize crypto library.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = 0;
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
|
||||
rv = mar_read_entire_file(DERFilePaths[k], MAR_MAX_CERT_SIZE,
|
||||
&certBuffers[k], &fileSizes[k]);
|
||||
#else
|
||||
/* It is somewhat circuitous to look up a CERTCertificate and then pass
|
||||
* in its DER encoding just so we can later re-create that
|
||||
* CERTCertificate to extract the public key out of it. However, by doing
|
||||
* things this way, we maximize the reuse of the mar_verify_signatures
|
||||
* function and also we keep the control flow as similar as possible
|
||||
* between programs and operating systems, at least for the functions
|
||||
* that are critically important to security.
|
||||
*/
|
||||
certs[k] = PK11_FindCertFromNickname(certNames[k], NULL);
|
||||
if (certs[k]) {
|
||||
certBuffers[k] = certs[k]->derCert.data;
|
||||
fileSizes[k] = certs[k]->derCert.len;
|
||||
} else {
|
||||
rv = -1;
|
||||
}
|
||||
#endif
|
||||
if (rv) {
|
||||
fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rv) {
|
||||
MarFile *mar = mar_open(argv[2]);
|
||||
if (mar) {
|
||||
rv = mar_verify_signatures(mar, certBuffers, fileSizes, certCount);
|
||||
mar_close(mar);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Could not open MAR file.\n");
|
||||
rv = -1;
|
||||
}
|
||||
}
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && !defined(MAR_NSS)
|
||||
free(certBuffers[k]);
|
||||
#else
|
||||
/* certBuffers[k] is owned by certs[k] so don't free it */
|
||||
CERT_DestroyCertificate(certs[k]);
|
||||
#endif
|
||||
}
|
||||
if (rv) {
|
||||
/* Determine if the source MAR file has the new fields for signing */
|
||||
|
@ -369,26 +394,8 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
return mar_verify_signatures(argv[2], (const uint8_t* const*)DERFilePaths,
|
||||
0, NULL, certCount);
|
||||
#else
|
||||
if (!NSSConfigDir || certCount == 0) {
|
||||
print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NSSInitCryptoContext(NSSConfigDir)) {
|
||||
fprintf(stderr, "ERROR: Could not initialize crypto library.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mar_verify_signatures(argv[2], NULL, 0, certNames, certCount);
|
||||
|
||||
#endif /* defined(XP_WIN) && !defined(MAR_NSS) */
|
||||
case 's':
|
||||
if (!NSSConfigDir || certCount == 0 || argc < 4) {
|
||||
print_usage();
|
||||
|
|
|
@ -16,29 +16,32 @@
|
|||
/**
|
||||
* Loads the public key for the specified cert name from the NSS store.
|
||||
*
|
||||
* @param certName The cert name to find.
|
||||
* @param certData The DER-encoded X509 certificate to extract the key from.
|
||||
* @param certDataSize The size of certData.
|
||||
* @param publicKey Out parameter for the public key to use.
|
||||
* @param cert Out parameter for the certificate to use.
|
||||
* @return CryptoX_Success on success, CryptoX_Error on error.
|
||||
*/
|
||||
CryptoX_Result
|
||||
NSS_LoadPublicKey(const char *certNickname,
|
||||
SECKEYPublicKey **publicKey,
|
||||
CERTCertificate **cert)
|
||||
NSS_LoadPublicKey(const unsigned char *certData, unsigned int certDataSize,
|
||||
SECKEYPublicKey **publicKey)
|
||||
{
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
if (!cert || !publicKey || !cert) {
|
||||
CERTCertificate * cert;
|
||||
SECItem certDataItem = { siBuffer, (unsigned char*) certData, certDataSize };
|
||||
|
||||
if (!certData || !publicKey) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certDataItem, NULL,
|
||||
PR_FALSE, PR_TRUE);
|
||||
/* Get the cert and embedded public key out of the database */
|
||||
*cert = PK11_FindCertFromNickname(certNickname, &pwdata);
|
||||
if (!*cert) {
|
||||
if (!cert) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
*publicKey = CERT_ExtractPublicKey(*cert);
|
||||
*publicKey = CERT_ExtractPublicKey(cert);
|
||||
CERT_DestroyCertificate(cert);
|
||||
|
||||
if (!*publicKey) {
|
||||
CERT_DestroyCertificate(*cert);
|
||||
return CryptoX_Error;
|
||||
}
|
||||
return CryptoX_Success;
|
||||
|
@ -150,12 +153,11 @@ CryptoX_Result
|
|||
CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
|
||||
BYTE *certData,
|
||||
DWORD sizeOfCertData,
|
||||
HCRYPTKEY *publicKey,
|
||||
HCERTSTORE *certStore)
|
||||
HCRYPTKEY *publicKey)
|
||||
{
|
||||
CRYPT_DATA_BLOB blob;
|
||||
CERT_CONTEXT *context;
|
||||
if (!provider || !certData || !publicKey || !certStore) {
|
||||
if (!provider || !certData || !publicKey) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
|
@ -165,7 +167,7 @@ CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
|
|||
CERT_QUERY_CONTENT_FLAG_CERT,
|
||||
CERT_QUERY_FORMAT_FLAG_BINARY,
|
||||
0, NULL, NULL, NULL,
|
||||
certStore, NULL, (const void **)&context)) {
|
||||
NULL, NULL, (const void **)&context)) {
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#if defined(MAR_NSS)
|
||||
|
||||
#include "nss_secutil.h"
|
||||
#include "cert.h"
|
||||
#include "keyhi.h"
|
||||
#include "cryptohi.h"
|
||||
|
||||
#define CryptoX_InvalidHandleValue NULL
|
||||
#define CryptoX_ProviderHandle void*
|
||||
|
@ -26,9 +28,9 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
CryptoX_Result NSS_LoadPublicKey(const char *certNickname,
|
||||
SECKEYPublicKey **publicKey,
|
||||
CERTCertificate **cert);
|
||||
CryptoX_Result NSS_LoadPublicKey(const unsigned char* certData,
|
||||
unsigned int certDataSize,
|
||||
SECKEYPublicKey** publicKey);
|
||||
CryptoX_Result NSS_VerifyBegin(VFYContext **ctx,
|
||||
SECKEYPublicKey * const *publicKey);
|
||||
CryptoX_Result NSS_VerifySignature(VFYContext * const *ctx ,
|
||||
|
@ -46,9 +48,8 @@ CryptoX_Result NSS_VerifySignature(VFYContext * const *ctx ,
|
|||
VFY_DestroyContext(*SignatureHandle, PR_TRUE)
|
||||
#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \
|
||||
VFY_Update(*SignatureHandle, (const unsigned char*)(buf), len)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, \
|
||||
publicKey, certName, cert) \
|
||||
NSS_LoadPublicKey(certName, publicKey, cert)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \
|
||||
NSS_LoadPublicKey(certData, dataSize, publicKey)
|
||||
#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \
|
||||
NSS_VerifySignature(hash, (const unsigned char *)(signedData), len)
|
||||
#define CryptoX_FreePublicKey(key) \
|
||||
|
@ -91,7 +92,7 @@ void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey);
|
|||
#define CryptoX_VerifyUpdate(aInputData, aBuf, aLen) \
|
||||
CryptoMac_VerifyUpdate(aInputData, aBuf, aLen)
|
||||
#define CryptoX_LoadPublicKey(aProviderHandle, aCertData, aDataSize, \
|
||||
aPublicKey, aCertName, aCert) \
|
||||
aPublicKey) \
|
||||
CryptoMac_LoadPublicKey(aCertData, aPublicKey)
|
||||
#define CryptoX_VerifySignature(aInputData, aPublicKey, aSignature, \
|
||||
aSignatureLen) \
|
||||
|
@ -111,8 +112,7 @@ CryptoX_Result CryptoAPI_InitCryptoContext(HCRYPTPROV *provider);
|
|||
CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV hProv,
|
||||
BYTE *certData,
|
||||
DWORD sizeOfCertData,
|
||||
HCRYPTKEY *publicKey,
|
||||
HCERTSTORE *cert);
|
||||
HCRYPTKEY *publicKey);
|
||||
CryptoX_Result CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash);
|
||||
CryptoX_Result CryptoAPI_VerifyUpdate(HCRYPTHASH* hash,
|
||||
BYTE *buf, DWORD len);
|
||||
|
@ -133,10 +133,8 @@ CryptoX_Result CyprtoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
#define CryptoX_FreeSignatureHandle(SignatureHandle)
|
||||
#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) \
|
||||
CryptoAPI_VerifyUpdate(SignatureHandle, (BYTE *)(buf), len)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, \
|
||||
publicKey, certName, cert) \
|
||||
CryptoAPI_LoadPublicKey(CryptoHandle, (BYTE*)(certData), \
|
||||
dataSize, publicKey, cert)
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \
|
||||
CryptoAPI_LoadPublicKey(CryptoHandle, (BYTE*)(certData), dataSize, publicKey)
|
||||
#define CryptoX_VerifySignature(hash, publicKey, signedData, len) \
|
||||
CyprtoAPI_VerifySignature(hash, publicKey, signedData, len)
|
||||
#define CryptoX_FreePublicKey(key) \
|
||||
|
@ -163,8 +161,7 @@ CryptoX_Result CyprtoAPI_VerifySignature(HCRYPTHASH *hash,
|
|||
CryptoX_Error
|
||||
#define CryptoX_FreeSignatureHandle(SignatureHandle)
|
||||
#define CryptoX_VerifyUpdate(SignatureHandle, buf, len) CryptoX_Error
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, \
|
||||
publicKey, certName, cert) \
|
||||
#define CryptoX_LoadPublicKey(CryptoHandle, certData, dataSize, publicKey) \
|
||||
CryptoX_Error
|
||||
#define CryptoX_VerifySignature(hash, publicKey, signedData, len) CryptoX_Error
|
||||
#define CryptoX_FreePublicKey(key) CryptoX_Error
|
||||
|
|
|
@ -17,6 +17,46 @@
|
|||
#include "mar.h"
|
||||
#include "cryptox.h"
|
||||
|
||||
int
|
||||
mar_read_entire_file(const char * filePath, uint32_t maxSize,
|
||||
/*out*/ const uint8_t * *data,
|
||||
/*out*/ uint32_t *size)
|
||||
{
|
||||
int result;
|
||||
FILE * f;
|
||||
|
||||
if (!filePath || !data || !size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
f = fopen(filePath, "rb");
|
||||
if (!f) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = -1;
|
||||
if (!fseeko(f, 0, SEEK_END)) {
|
||||
int64_t fileSize = ftello(f);
|
||||
if (fileSize > 0 && fileSize <= maxSize && !fseeko(f, 0, SEEK_SET)) {
|
||||
unsigned char * fileData;
|
||||
|
||||
*size = (unsigned int) fileSize;
|
||||
fileData = malloc(*size);
|
||||
if (fileData) {
|
||||
if (fread(fileData, *size, 1, f) == 1) {
|
||||
*data = fileData;
|
||||
result = 0;
|
||||
} else {
|
||||
free(fileData);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int mar_extract_and_verify_signatures_fp(FILE *fp,
|
||||
CryptoX_ProviderHandle provider,
|
||||
CryptoX_PublicKey *keys,
|
||||
|
@ -81,92 +121,8 @@ ReadAndUpdateVerifyContext(FILE *fp,
|
|||
* certificate given, the second signature will be verified using the second
|
||||
* certificate given, etc. The signature count must exactly match the number of
|
||||
* certificates given, and all signature verifications must succeed.
|
||||
* This is only used by the signmar program when used with arguments to verify
|
||||
* a MAR. This should not be used to verify a MAR that will be extracted in the
|
||||
* same operation by updater code. This function prints the error message if
|
||||
* verification fails.
|
||||
*
|
||||
* @param pathToMARFile The path of the MAR file to verify.
|
||||
* @param certData Pointer to the first element in an array of certificate
|
||||
* file data.
|
||||
* @param certDataSizes Pointer to the first element in an array for size of the
|
||||
* cert data.
|
||||
* @param certNames Pointer to the first element in an array of certificate names.
|
||||
* Used only if compiled as NSS, specifies the certificate names
|
||||
* @param certCount The number of elements in certData, certDataSizes, and certNames
|
||||
* @return 0 on success
|
||||
* a negative number if there was an error
|
||||
* a positive number if the signature does not verify
|
||||
*/
|
||||
int
|
||||
mar_verify_signatures(const char *pathToMARFile,
|
||||
const uint8_t * const *certData,
|
||||
const uint32_t *certDataSizes,
|
||||
const char * const *certNames,
|
||||
uint32_t certCount) {
|
||||
int rv;
|
||||
CryptoX_ProviderHandle provider = CryptoX_InvalidHandleValue;
|
||||
CryptoX_Certificate certs[MAX_SIGNATURES];
|
||||
CryptoX_PublicKey keys[MAX_SIGNATURES];
|
||||
FILE *fp;
|
||||
uint32_t k;
|
||||
|
||||
memset(certs, 0, sizeof(certs));
|
||||
memset(keys, 0, sizeof(keys));
|
||||
|
||||
if (!pathToMARFile || certCount == 0) {
|
||||
fprintf(stderr, "ERROR: Invalid parameter specified.\n");
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
fp = fopen(pathToMARFile, "rb");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "ERROR: Could not open MAR file.\n");
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
if (CryptoX_Failed(CryptoX_InitCryptoProvider(&provider))) {
|
||||
fclose(fp);
|
||||
fprintf(stderr, "ERROR: Could not init crytpo library.\n");
|
||||
return CryptoX_Error;
|
||||
}
|
||||
|
||||
/* Load the certs and keys */
|
||||
for (k = 0; k < certCount; k++) {
|
||||
if (CryptoX_Failed(CryptoX_LoadPublicKey(provider, certData[k], certDataSizes[k],
|
||||
&keys[k], certNames[k], &certs[k]))) {
|
||||
fclose(fp);
|
||||
fprintf(stderr, "ERROR: Could not load public key.\n");
|
||||
return CryptoX_Error;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mar_extract_and_verify_signatures_fp(fp, provider, keys, certCount);
|
||||
fclose(fp);
|
||||
|
||||
/* Cleanup the allocated keys and certs */
|
||||
for (k = 0; k < certCount; k++) {
|
||||
if (keys[k]) {
|
||||
CryptoX_FreePublicKey(&keys[k]);
|
||||
}
|
||||
|
||||
if (certs[k]) {
|
||||
CryptoX_FreeCertificate(&certs[k]);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
/**
|
||||
* Verifies a MAR file by verifying each signature with the corresponding
|
||||
* certificate. That is, the first signature will be verified using the first
|
||||
* certificate given, the second signature will be verified using the second
|
||||
* certificate given, etc. The signature count must exactly match the number of
|
||||
* certificates given, and all signature verifications must succeed.
|
||||
*
|
||||
* @param pathToMARFile The path of the MAR file who's signature
|
||||
* should be calculated
|
||||
* @param mar The file who's signature should be calculated
|
||||
* @param certData Pointer to the first element in an array of
|
||||
* certificate data
|
||||
* @param certDataSizes Pointer to the first element in an array for size of
|
||||
|
@ -175,17 +131,15 @@ mar_verify_signatures(const char *pathToMARFile,
|
|||
* @return 0 on success
|
||||
*/
|
||||
int
|
||||
mar_verify_signaturesW(MarFile *mar,
|
||||
mar_verify_signatures(MarFile *mar,
|
||||
const uint8_t * const *certData,
|
||||
const uint32_t *certDataSizes,
|
||||
uint32_t certCount) {
|
||||
int rv = -1;
|
||||
CryptoX_ProviderHandle provider = CryptoX_InvalidHandleValue;
|
||||
CryptoX_Certificate certs[MAX_SIGNATURES];
|
||||
CryptoX_PublicKey keys[MAX_SIGNATURES];
|
||||
uint32_t k;
|
||||
|
||||
memset(certs, 0, sizeof(certs));
|
||||
memset(keys, 0, sizeof(keys));
|
||||
|
||||
if (!mar || !certData || !certDataSizes || certCount == 0) {
|
||||
|
@ -205,7 +159,7 @@ mar_verify_signaturesW(MarFile *mar,
|
|||
|
||||
for (k = 0; k < certCount; ++k) {
|
||||
if (CryptoX_Failed(CryptoX_LoadPublicKey(provider, certData[k], certDataSizes[k],
|
||||
&keys[k], "", &certs[k]))) {
|
||||
&keys[k]))) {
|
||||
fprintf(stderr, "ERROR: Could not load public key.\n");
|
||||
goto failure;
|
||||
}
|
||||
|
@ -219,15 +173,10 @@ failure:
|
|||
if (keys[k]) {
|
||||
CryptoX_FreePublicKey(&keys[k]);
|
||||
}
|
||||
|
||||
if (certs[k]) {
|
||||
CryptoX_FreeCertificate(&certs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Extracts each signature from the specified MAR file,
|
||||
|
|
Загрузка…
Ссылка в новой задаче