| author | Brian Smith <bsmith@mozilla.com> |
| Wed, 22 Oct 2014 21:00:15 -0400 | |
| changeset 237689 | 144170110448647a591bb54572dc5e2979296027 |
| parent 237688 | 4fe763cbe1961059f9051084afb6e300c6bf399f |
| child 237690 | c19d11fe299702a7ef948b29e61b51b889c10b32 |
| push id | 28546 |
| push user | netzen@gmail.com |
| push date | Mon, 06 Apr 2015 16:08:39 +0000 |
| treeherder | mozilla-central@883e17fc475f [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | bbondy |
| bugs | 903135 |
| milestone | 40.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/modules/libmar/src/mar.h +++ b/modules/libmar/src/mar.h @@ -129,16 +129,36 @@ int mar_create(const char *dest, /** * Extract a MAR file to the current working directory. * @param path The path to the MAR file to extract. This path must be * compatible with fopen. * @return A non-zero value if an error occurs. */ 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 * 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. * We do not check that the certificate was issued by any trusted authority. * We assume it to be self-signed. We do not check whether the certificate @@ -149,22 +169,20 @@ int mar_extract(const char *path); * file data. * @param certDataSizes Pointer to the first element in an array for size of * the cert data. * @param certCount The number of elements in certData and certDataSizes * @return 0 on success * 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, - const uint8_t * const *certData, - const uint32_t *certDataSizes, - uint32_t certCount); -#endif +int mar_verify_signatures(MarFile *mar, + const uint8_t * const *certData, + const uint32_t *certDataSizes, + 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 * if the return is successful. * * @param infoBlock Out parameter for where to store the result to * @return 0 on success, -1 on failure
--- a/modules/libmar/src/mar_cmdline.h +++ b/modules/libmar/src/mar_cmdline.h @@ -33,48 +33,16 @@ struct ProductInformationBlock; */ int get_mar_file_info(const char *path, int *hasSignatureBlock, uint32_t *numSignatures, int *hasAdditionalBlocks, 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 * if the return is successful. * * @param infoBlock Out parameter for where to store the result to * @return 0 on success, -1 on failure */
--- a/modules/libmar/tool/mar.c +++ b/modules/libmar/tool/mar.c @@ -14,16 +14,18 @@ #include <windows.h> #include <direct.h> #define chdir _chdir #else #include <unistd.h> #endif #if !defined(NO_SIGN_VERIFY) && (!defined(XP_WIN) || defined(MAR_NSS)) +#include "cert.h" +#include "pk11pub.h" int NSSInitCryptoContext(const char *NSSConfigDir); #endif int mar_repackage_and_sign(const char *NSSConfigDir, const char * const *certNames, uint32_t certCount, const char *src, const char * dest); @@ -115,25 +117,23 @@ int main(int argc, char **argv) { const char *certNames[MAX_SIGNATURES]; char *MARChannelID = MAR_CHANNEL_ID; char *productVersion = MOZ_APP_VERSION; uint32_t i, k; int rv = -1; 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]; +#if !defined(NO_SIGN_VERIFY) + uint32_t fileSizes[MAX_SIGNATURES]; + uint8_t* certBuffers[MAX_SIGNATURES]; + char* DERFilePaths[MAX_SIGNATURES]; +#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS) + CERTCertificate* certs[MAX_SIGNATURES]; #endif -#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \ - defined(XP_MACOSX)) - char* DERFilePaths[MAX_SIGNATURES]; - uint32_t fileSizes[MAX_SIGNATURES]; - uint32_t read; #endif memset(certNames, 0, sizeof(certNames)); #if defined(XP_WIN) && !defined(MAR_NSS) && !defined(NO_SIGN_VERIFY) memset(certBuffers, 0, sizeof(certBuffers)); #endif #if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \ defined(XP_MACOSX)) @@ -314,86 +314,93 @@ int main(int argc, char **argv) { } if (argc < 5) { print_usage(); return -1; } 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) { - 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); +#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS) + if (!NSSConfigDir || certCount == 0) { + print_usage(); + return -1; } - 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 */ int hasSignatureBlock; if (get_mar_file_info(argv[2], &hasSignatureBlock, NULL, NULL, NULL, NULL)) { fprintf(stderr, "ERROR: could not determine if MAR is old or new.\n"); } else if (!hasSignatureBlock) { fprintf(stderr, "ERROR: The MAR file is in the old format so has" " no signature to verify.\n"); } 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(); return -1; } return mar_repackage_and_sign(NSSConfigDir, certNames, certCount, argv[2], argv[3]);
--- a/modules/libmar/verify/cryptox.c +++ b/modules/libmar/verify/cryptox.c @@ -11,39 +11,42 @@ #include <stdlib.h> #include "cryptox.h" #if defined(MAR_NSS) /** * 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; } CryptoX_Result NSS_VerifyBegin(VFYContext **ctx, SECKEYPublicKey * const *publicKey) @@ -145,32 +148,31 @@ CyprtoAPI_VerifySignature(HCRYPTHASH *ha * @param sizeOfCertData The size of the certData buffer * @param certStore Pointer to the handle of the certificate store to use * @param CryptoX_Success on success */ 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; } blob.cbData = sizeOfCertData; blob.pbData = certData; if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, 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; } if (!CryptImportPublicKeyInfo(provider, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &context->pCertInfo->SubjectPublicKeyInfo, publicKey)) { CertFreeCertificateContext(context);
--- a/modules/libmar/verify/cryptox.h +++ b/modules/libmar/verify/cryptox.h @@ -10,30 +10,32 @@ #define CryptoX_Result int #define CryptoX_Success 0 #define CryptoX_Error (-1) #define CryptoX_Succeeded(X) ((X) == CryptoX_Success) #define CryptoX_Failed(X) ((X) != CryptoX_Success) #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* #define CryptoX_SignatureHandle VFYContext * #define CryptoX_PublicKey SECKEYPublicKey * #define CryptoX_Certificate CERTCertificate * #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 , const unsigned char *signature, unsigned int signatureLen); #ifdef __cplusplus } // extern "C" #endif @@ -41,19 +43,18 @@ CryptoX_Result NSS_VerifySignature(VFYCo #define CryptoX_InitCryptoProvider(CryptoHandle) \ CryptoX_Success #define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ NSS_VerifyBegin(SignatureHandle, PublicKey) #define CryptoX_FreeSignatureHandle(SignatureHandle) \ 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) \ SECKEY_DestroyPublicKey(*key) #define CryptoX_FreeCertificate(cert) \ CERT_DestroyCertificate(*cert) #elif XP_MACOSX @@ -86,17 +87,17 @@ void CryptoMac_FreePublicKey(CryptoX_Pub #define CryptoX_InitCryptoProvider(aProviderHandle) \ CryptoMac_InitCryptoProvider() #define CryptoX_VerifyBegin(aCryptoHandle, aInputData, aPublicKey) \ CryptoMac_VerifyBegin(aInputData) #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) \ CryptoMac_VerifySignature(aInputData, aPublicKey, aSignature, aSignatureLen) #define CryptoX_FreeSignatureHandle(aInputData) \ CryptoMac_FreeSignatureHandle(aInputData) #define CryptoX_FreePublicKey(aPublicKey) \ CryptoMac_FreePublicKey(aPublicKey) @@ -106,18 +107,17 @@ void CryptoMac_FreePublicKey(CryptoX_Pub #include <windows.h> #include <wincrypt.h> 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); CryptoX_Result CyprtoAPI_VerifySignature(HCRYPTHASH *hash, HCRYPTKEY *pubKey, const BYTE *signature, DWORD signatureLen); @@ -128,20 +128,18 @@ CryptoX_Result CyprtoAPI_VerifySignature #define CryptoX_Certificate HCERTSTORE #define CryptoX_InitCryptoProvider(CryptoHandle) \ CryptoAPI_InitCryptoContext(CryptoHandle) #define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ CryptoAPI_VerifyBegin(CryptoHandle, SignatureHandle) #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) \ CryptDestroyKey(*(key)) #define CryptoX_FreeCertificate(cert) \ CertCloseStore(*(cert), CERT_CLOSE_STORE_FORCE_FLAG); #else @@ -158,17 +156,16 @@ CryptoX_Result CyprtoAPI_VerifySignature #define CryptoX_PublicKey void* #define CryptoX_Certificate void* #define CryptoX_InitCryptoProvider(CryptoHandle) \ CryptoX_Error #define CryptoX_VerifyBegin(CryptoHandle, SignatureHandle, PublicKey) \ 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 #endif #endif
--- a/modules/libmar/verify/mar_verify.c +++ b/modules/libmar/verify/mar_verify.c @@ -12,16 +12,56 @@ #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include "mar_private.h" #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, uint32_t keyCount); int mar_verify_signatures_for_fp(FILE *fp, CryptoX_ProviderHandle provider, CryptoX_PublicKey *keys, const uint8_t * const *extractedSignatures, @@ -76,121 +116,35 @@ ReadAndUpdateVerifyContext(FILE *fp, } /** * 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 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 * the data stored * @param certCount The number of elements in certData and certDataSizes * @return 0 on success */ int -mar_verify_signaturesW(MarFile *mar, - const uint8_t * const *certData, - const uint32_t *certDataSizes, - uint32_t certCount) { +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) { fprintf(stderr, "ERROR: Invalid parameter specified.\n"); goto failure; } if (!mar->fp) { @@ -200,39 +154,34 @@ mar_verify_signaturesW(MarFile *mar, if (CryptoX_Failed(CryptoX_InitCryptoProvider(&provider))) { fprintf(stderr, "ERROR: Could not init crytpo library.\n"); goto failure; } 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; } } rv = mar_extract_and_verify_signatures_fp(mar->fp, provider, keys, certCount); failure: for (k = 0; k < certCount; ++k) { 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, * then calls mar_verify_signatures_for_fp to verify each signature. * * @param fp An opened MAR file handle * @param provider A library provider * @param keys The public keys to use to verify the MAR