$OpenBSD$ index 7578b62..78b3247 100644 --- modules/libmar/verify/mar_verify.c.orig Fri Feb 20 15:40:37 2015 +++ modules/libmar/verify/mar_verify.c Fri Feb 20 15:40:37 2015 @@ -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, - 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) { @@ -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, @@ -327,8 +276,25 @@ mar_extract_and_verify_signatures_fp(FILE *fp, } /* We don't try to verify signatures we don't know about */ - if (signatureAlgorithmIDs[i] != 1) { - fprintf(stderr, "ERROR: Unknown signature algorithm ID.\n"); +#ifdef MAR_USE_SHA512_RSA_SIG + const uint32_t kSupportedAlgID = SIGNATURE_ALGORITHM_ID_SHA512_RSA; +#else + const uint32_t kSupportedAlgID = SIGNATURE_ALGORITHM_ID_SHA1_RSA; +#endif + + if (signatureAlgorithmIDs[i] != kSupportedAlgID) { +#ifdef MAR_USE_SHA512_RSA_SIG + if (signatureAlgorithmIDs[i] == SIGNATURE_ALGORITHM_ID_SHA1_RSA) { + fprintf(stderr, + "ERROR: Unsupported signature algorithm (SHA1 with RSA).\n"); + } else { + fprintf(stderr, "ERROR: Unknown signature algorithm ID %u.\n", + signatureAlgorithmIDs[i]); + } +#else + fprintf(stderr, "ERROR: Unknown signature algorithm ID %u.\n", + signatureAlgorithmIDs[i]); +#endif for (i = 0; i < signatureCount; ++i) { free(extractedSignatures[i]); }