$OpenBSD$ index 8abbac7..82701a9 100644 --- modules/libmar/tool/mar.c.orig Fri Feb 20 15:40:37 2015 +++ modules/libmar/tool/mar.c Fri Feb 20 15:40:37 2015 @@ -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 @@ -29,7 +31,11 @@ int mar_repackage_and_sign(const char *NSSConfigDir, const char * dest); static void print_version() { +#ifdef TOR_BROWSER_UPDATE + printf("Version: %s\n", TOR_BROWSER_VERSION); +#else printf("Version: %s\n", MOZ_APP_VERSION); +#endif printf("Default Channel ID: %s\n", MAR_CHANNEL_ID); } @@ -59,7 +65,7 @@ static void print_usage() { "signed_input_archive.mar base_64_encoded_signature_file " "changed_signed_output.mar\n"); printf("(i) is the index of the certificate to extract\n"); -#if defined(XP_MACOSX) || (defined(XP_WIN) && !defined(MAR_NSS)) +#if (defined(XP_MACOSX) || defined(XP_WIN)) && !defined(MAR_NSS) printf("Verify a MAR file:\n"); printf(" mar [-C workingDir] -D DERFilePath -v signed_archive.mar\n"); printf("At most %d signature certificate DER files are specified by " @@ -114,29 +120,31 @@ int main(int argc, char **argv) { char *NSSConfigDir = NULL; const char *certNames[MAX_SIGNATURES]; char *MARChannelID = MAR_CHANNEL_ID; +#ifdef TOR_BROWSER_UPDATE + char *productVersion = TOR_BROWSER_VERSION; +#else char *productVersion = MOZ_APP_VERSION; +#endif 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]; -#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)); #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)) +#if !defined(NO_SIGN_VERIFY) && (!defined(MAR_NSS) && (defined(XP_WIN) || \ + defined(XP_MACOSX))) memset(DERFilePaths, 0, sizeof(DERFilePaths)); memset(fileSizes, 0, sizeof(fileSizes)); #endif @@ -165,8 +173,8 @@ int main(int argc, char **argv) { argv += 2; argc -= 2; } -#if !defined(NO_SIGN_VERIFY) && ((!defined(MAR_NSS) && defined(XP_WIN)) || \ - defined(XP_MACOSX)) +#if !defined(NO_SIGN_VERIFY) && (!defined(MAR_NSS) && (defined(XP_WIN) || \ + defined(XP_MACOSX))) /* -D DERFilePath, also matches -D[index] DERFilePath We allow an index for verifying to be symmetric with the import and export command line arguments. */ @@ -319,43 +327,72 @@ 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; } +#if (!defined(XP_WIN) && !defined(XP_MACOSX)) || defined(MAR_NSS) + if (!NSSConfigDir || certCount == 0) { + print_usage(); + return -1; + } + + if (NSSInitCryptoContext(NSSConfigDir)) { + fprintf(stderr, "ERROR: Could not initialize crypto library.\n"); + return -1; + } +#endif + + rv = 0; 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; +#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]); + if (rv) { + fprintf(stderr, "ERROR: could not read file %s", DERFilePaths[k]); + break; } - 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; +#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; + } + if (rv) { + fprintf(stderr, "ERROR: no certificate named %s", certNames[k]); + break; } - CloseHandle(certFile); +#endif } - rv = mar_verify_signatures(argv[2], certBuffers, fileSizes, - NULL, certCount); + 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 +406,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();