6#ifndef WIN32_LEAN_AND_MEAN
7#define WIN32_LEAN_AND_MEAN
37 SECStatus status = NSS_Initialize(NSSConfigDir,
38 "",
"", SECMOD_DB, NSS_INIT_READONLY);
39 if (SECSuccess != status) {
40 fprintf(stderr,
"ERROR: Could not initialize NSS\n");
57 SECKEYPrivateKey **privKey,
58 CERTCertificate **cert,
59 uint32_t *signatureLength)
62 if (!certName || !
ctx || !privKey || !cert || !signatureLength) {
63 fprintf(stderr,
"ERROR: Invalid parameter passed to NSSSignBegin\n");
68 *cert = PK11_FindCertFromNickname(certName, &pwdata);
70 fprintf(stderr,
"ERROR: Could not find cert from nickname\n");
75 *privKey = PK11_FindKeyByAnyCert(*cert, &pwdata);
77 fprintf(stderr,
"ERROR: Could not find private key\n");
81 *signatureLength = PK11_SignatureLen(*privKey);
85 "ERROR: Program must be compiled with a larger block size"
86 " to support signing with signatures this large: %u.\n",
93 fprintf(stderr,
"ERROR: Key length must be >= %d bytes\n",
98 *
ctx = SGN_NewContext (SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, *privKey);
100 fprintf(stderr,
"ERROR: Could not create signature context\n");
104 if (SGN_Begin(*
ctx) != SECSuccess) {
105 fprintf(stderr,
"ERROR: Could not begin signature\n");
128 uint32_t size, SGNContext **ctxs,
137 if (fwrite(buffer,
size, 1, fpDest) != 1) {
138 fprintf(stderr,
"ERROR: Could not write %s\n",
err);
142 for (k = 0; k < ctxCount; ++k) {
143 if (SGN_Update(ctxs[k], buffer,
size) != SECSuccess) {
144 fprintf(stderr,
"ERROR: Could not update signature context for %s\n",
err);
162 char *indexBufLoc = indexBuf;
165 while (indexBufLoc != (indexBuf + indexLength)) {
167 uint32_t* offsetToContent = (uint32_t *)indexBufLoc;
168 *offsetToContent =
ntohl(*offsetToContent);
169 *offsetToContent += offsetAmount;
170 *offsetToContent =
htonl(*offsetToContent);
172 indexBufLoc += 3 *
sizeof(uint32_t);
173 indexBufLoc += strlen(indexBufLoc) + 1;
195 uint32_t size, SGNContext **ctxs,
203 if (fread(buffer,
size, 1, fpSrc) != 1) {
204 fprintf(stderr,
"ERROR: Could not read %s\n",
err);
226 uint32_t size,
const char *err)
232 if (fread(buffer,
size, 1, fpSrc) != 1) {
233 fprintf(stderr,
"ERROR: Could not read %s\n",
err);
237 if (fwrite(buffer,
size, 1, fpDest) != 1) {
238 fprintf(stderr,
"ERROR: Could not write %s\n",
err);
257 uint32_t offsetToIndex, dstOffsetToIndex, indexLength,
258 numSignatures = 0, leftOver;
259 int32_t stripAmount = 0;
260 int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR, numBytesToCopy,
263 int rv = -1, hasSignatureBlock;
265 char *indexBuf =
NULL;
268 fprintf(stderr,
"ERROR: Invalid parameter passed in.\n");
272 fpSrc = fopen(src,
"rb");
274 fprintf(stderr,
"ERROR: could not open source file: %s\n", src);
278 fpDest = fopen(dest,
"wb");
280 fprintf(stderr,
"ERROR: could not create target file: %s\n", dest);
286 fprintf(stderr,
"ERROR: could not determine if MAR is old or new.\n");
296 if (fread(&offsetToIndex,
sizeof(offsetToIndex), 1, fpSrc) != 1) {
297 fprintf(stderr,
"ERROR: Could not read offset\n");
300 offsetToIndex =
ntohl(offsetToIndex);
303 oldPos = ftello(fpSrc);
304 if (fseeko(fpSrc, 0, SEEK_END)) {
305 fprintf(stderr,
"ERROR: Could not seek to end of file.\n");
308 realSizeOfSrcMAR = ftello(fpSrc);
309 if (fseeko(fpSrc, oldPos, SEEK_SET)) {
310 fprintf(stderr,
"ERROR: Could not seek back to current location.\n");
314 if (hasSignatureBlock) {
316 if (fread(&sizeOfEntireMAR,
317 sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
318 fprintf(stderr,
"ERROR: Could read mar size\n");
322 if (sizeOfEntireMAR != realSizeOfSrcMAR) {
323 fprintf(stderr,
"ERROR: Source MAR is not of the right size\n");
328 if (fread(&numSignatures,
sizeof(numSignatures), 1, fpSrc) != 1) {
329 fprintf(stderr,
"ERROR: Could read num signatures\n");
332 numSignatures =
ntohl(numSignatures);
334 for (
i = 0;
i < numSignatures;
i++) {
335 uint32_t signatureLen;
338 if (fseeko(fpSrc,
sizeof(uint32_t), SEEK_CUR)) {
339 fprintf(stderr,
"ERROR: Could not skip past signature algorithm ID\n");
343 if (fread(&signatureLen,
sizeof(uint32_t), 1, fpSrc) != 1) {
344 fprintf(stderr,
"ERROR: Could not read signatures length.\n");
347 signatureLen =
ntohl(signatureLen);
350 if (fseeko(fpSrc, signatureLen, SEEK_CUR)) {
351 fprintf(stderr,
"ERROR: Could not skip past signature algorithm ID\n");
354 stripAmount +=
sizeof(uint32_t) +
sizeof(uint32_t) + signatureLen;
358 sizeOfEntireMAR = realSizeOfSrcMAR;
362 if (((int64_t)offsetToIndex) > sizeOfEntireMAR) {
363 fprintf(stderr,
"ERROR: Offset to index is larger than the file size.\n");
367 dstOffsetToIndex = offsetToIndex;
368 if (!hasSignatureBlock) {
369 dstOffsetToIndex +=
sizeof(sizeOfEntireMAR) +
sizeof(numSignatures);
371 dstOffsetToIndex -= stripAmount;
374 dstOffsetToIndex =
htonl(dstOffsetToIndex);
375 if (fwrite(&dstOffsetToIndex,
sizeof(dstOffsetToIndex), 1, fpDest) != 1) {
376 fprintf(stderr,
"ERROR: Could not write offset to index\n");
379 dstOffsetToIndex =
ntohl(dstOffsetToIndex);
382 if (!hasSignatureBlock) {
383 sizeOfEntireMAR +=
sizeof(sizeOfEntireMAR) +
sizeof(numSignatures);
385 sizeOfEntireMAR -= stripAmount;
389 if (fwrite(&sizeOfEntireMAR,
sizeof(sizeOfEntireMAR), 1, fpDest) != 1) {
390 fprintf(stderr,
"ERROR: Could not write size of MAR\n");
397 if (fwrite(&numSignatures,
sizeof(numSignatures), 1, fpDest) != 1) {
398 fprintf(stderr,
"ERROR: Could not write out num signatures\n");
405 if (ftello(fpSrc) > ((int64_t)offsetToIndex)) {
406 fprintf(stderr,
"ERROR: Index offset is too small.\n");
409 numBytesToCopy = ((int64_t)offsetToIndex) - ftello(fpSrc);
414 for (
i = 0;
i < numChunks; ++
i) {
422 leftOver,
"left over content block")) {
428 sizeof(indexLength),
"index length")) {
431 indexLength =
ntohl(indexLength);
434 indexBuf = malloc(indexLength);
435 if (fread(indexBuf, indexLength, 1, fpSrc) != 1) {
436 fprintf(stderr,
"ERROR: Could not read index\n");
441 if (hasSignatureBlock) {
445 sizeof(sizeOfEntireMAR) +
446 sizeof(numSignatures) -
450 if (fwrite(indexBuf, indexLength, 1, fpDest) != 1) {
451 fprintf(stderr,
"ERROR: Could not write index\n");
493 uint32_t signatureCount;
494 uint32_t signatureLen = 0;
495 uint8_t *extractedSignature =
NULL;
496 char *base64Encoded =
NULL;
499 fprintf(stderr,
"ERROR: Invalid parameter passed in.\n");
503 fpSrc = fopen(src,
"rb");
505 fprintf(stderr,
"ERROR: could not open source file: %s\n", src);
509 fpDest = fopen(dest,
"wb");
511 fprintf(stderr,
"ERROR: could not create target file: %s\n", dest);
517 fprintf(stderr,
"ERROR: could not seek to signature block\n");
522 if (fread(&signatureCount,
sizeof(signatureCount), 1, fpSrc) != 1) {
523 fprintf(stderr,
"ERROR: could not read signature count\n");
526 signatureCount =
ntohl(signatureCount);
527 if (sigIndex >= signatureCount) {
528 fprintf(stderr,
"ERROR: Signature index was out of range\n");
533 for (
i = 0;
i <= sigIndex;
i++) {
535 free(extractedSignature);
538 if (fseeko(fpSrc,
sizeof(uint32_t), SEEK_CUR)) {
539 fprintf(stderr,
"ERROR: Could not seek past sig algorithm ID.\n");
544 if (fread(&signatureLen,
sizeof(signatureLen), 1, fpSrc) != 1) {
545 fprintf(stderr,
"ERROR: could not read signature length\n");
548 signatureLen =
ntohl(signatureLen);
551 extractedSignature = malloc(signatureLen);
552 if (fread(extractedSignature, signatureLen, 1, fpSrc) != 1) {
553 fprintf(stderr,
"ERROR: could not read signature\n");
558 base64Encoded = BTOA_DataToAscii(extractedSignature, signatureLen);
559 if (!base64Encoded) {
560 fprintf(stderr,
"ERROR: could not obtain base64 encoded data\n");
564 if (fwrite(base64Encoded, strlen(base64Encoded), 1, fpDest) != 1) {
565 fprintf(stderr,
"ERROR: Could not write base64 encoded string\n");
572 PORT_Free(base64Encoded);
575 if (extractedSignature) {
576 free(extractedSignature);
606 const char *base64SigFile,
const char *dest)
613 uint32_t signatureCount, signatureLen, signatureAlgorithmID,
616 uint64_t sizeOfSrcMAR, sizeOfBase64EncodedFile;
617 char *passedInSignatureB64 =
NULL;
618 uint8_t *passedInSignatureRaw =
NULL;
619 uint8_t *extractedMARSignature =
NULL;
620 unsigned int passedInSignatureLenRaw;
623 fprintf(stderr,
"ERROR: Invalid parameter passed in.\n");
627 fpSrc = fopen(src,
"rb");
629 fprintf(stderr,
"ERROR: could not open source file: %s\n", src);
633 fpDest = fopen(dest,
"wb");
635 fprintf(stderr,
"ERROR: could not open dest file: %s\n", dest);
639 fpSigFile = fopen(base64SigFile ,
"rb");
641 fprintf(stderr,
"ERROR: could not open sig file: %s\n", base64SigFile);
646 if (fseeko(fpSrc, 0, SEEK_END)) {
647 fprintf(stderr,
"ERROR: Could not seek to end of src file.\n");
650 sizeOfSrcMAR = ftello(fpSrc);
651 if (fseeko(fpSrc, 0, SEEK_SET)) {
652 fprintf(stderr,
"ERROR: Could not seek to start of src file.\n");
657 if (fseeko(fpSigFile, 0, SEEK_END)) {
658 fprintf(stderr,
"ERROR: Could not seek to end of sig file.\n");
661 sizeOfBase64EncodedFile= ftello(fpSigFile);
662 if (fseeko(fpSigFile, 0, SEEK_SET)) {
663 fprintf(stderr,
"ERROR: Could not seek to start of sig file.\n");
668 passedInSignatureB64 = malloc(sizeOfBase64EncodedFile + 1);
669 passedInSignatureB64[sizeOfBase64EncodedFile] =
'\0';
670 if (fread(passedInSignatureB64, sizeOfBase64EncodedFile, 1, fpSigFile) != 1) {
671 fprintf(stderr,
"ERROR: Could read b64 sig file.\n");
676 passedInSignatureRaw = ATOB_AsciiToData(passedInSignatureB64, &passedInSignatureLenRaw);
677 if (!passedInSignatureRaw) {
678 fprintf(stderr,
"ERROR: could not obtain base64 decoded data\n");
690 sizeof(signatureCount),
"signature count")) {
693 signatureCount =
ntohl(signatureCount);
695 fprintf(stderr,
"ERROR: Signature count was out of range\n");
699 if (sigIndex >= signatureCount) {
700 fprintf(stderr,
"ERROR: Signature index was out of range\n");
707 for (
i = 0;
i < signatureCount;
i++) {
710 &signatureAlgorithmID,
711 sizeof(signatureAlgorithmID),
"sig algorithm ID")) {
717 &signatureLen,
sizeof(signatureLen),
"sig length")) {
720 signatureLen =
ntohl(signatureLen);
723 if (extractedMARSignature) {
724 free(extractedMARSignature);
726 extractedMARSignature = malloc(signatureLen);
729 if (passedInSignatureLenRaw != signatureLen) {
730 fprintf(stderr,
"ERROR: Signature length must be the same\n");
734 if (fread(extractedMARSignature, signatureLen, 1, fpSrc) != 1) {
735 fprintf(stderr,
"ERROR: Could not read signature\n");
739 if (fwrite(passedInSignatureRaw, passedInSignatureLenRaw,
741 fprintf(stderr,
"ERROR: Could not write signature\n");
746 extractedMARSignature, signatureLen,
"signature")) {
754 numChunks = (sizeOfSrcMAR - ftello(fpSrc)) /
BLOCKSIZE;
755 leftOver = (sizeOfSrcMAR - ftello(fpSrc)) %
BLOCKSIZE;
758 for (
i = 0;
i < numChunks; ++
i) {
764 if (
ReadAndWrite(fpSrc, fpDest, buf, leftOver,
"left over content block")) {
788 if (extractedMARSignature) {
789 free(extractedMARSignature);
792 if (passedInSignatureB64) {
793 free(passedInSignatureB64);
796 if (passedInSignatureRaw) {
797 PORT_Free(passedInSignatureRaw);
819 const char *
const *certNames,
824 uint32_t offsetToIndex, dstOffsetToIndex, indexLength,
825 numSignatures = 0, leftOver,
826 signatureAlgorithmID, signatureSectionLength = 0;
828 int64_t oldPos, sizeOfEntireMAR = 0, realSizeOfSrcMAR,
829 signaturePlaceholderOffset, numBytesToCopy,
832 int rv = -1, hasSignatureBlock;
838 char *indexBuf =
NULL;
841 memset(signatureLengths, 0,
sizeof(signatureLengths));
842 memset(ctxs, 0,
sizeof(ctxs));
843 memset(secItems, 0,
sizeof(secItems));
844 memset(privKeys, 0,
sizeof(privKeys));
845 memset(certs, 0,
sizeof(certs));
847 if (!NSSConfigDir || !certNames || certCount == 0 || !src || !dest) {
848 fprintf(stderr,
"ERROR: Invalid parameter passed in.\n");
853 fprintf(stderr,
"ERROR: Could not init config dir: %s\n", NSSConfigDir);
859 fpSrc = fopen(src,
"rb");
861 fprintf(stderr,
"ERROR: could not open source file: %s\n", src);
865 fpDest = fopen(dest,
"wb");
867 fprintf(stderr,
"ERROR: could not create target file: %s\n", dest);
873 fprintf(stderr,
"ERROR: could not determine if MAR is old or new.\n");
877 for (k = 0; k < certCount; k++) {
879 &certs[k], &signatureLengths[k])) {
880 fprintf(stderr,
"ERROR: NSSSignBegin failed\n");
888 ctxs, certCount,
"MAR ID")) {
893 if (fread(&offsetToIndex,
sizeof(offsetToIndex), 1, fpSrc) != 1) {
894 fprintf(stderr,
"ERROR: Could not read offset\n");
897 offsetToIndex =
ntohl(offsetToIndex);
900 oldPos = ftello(fpSrc);
901 if (fseeko(fpSrc, 0, SEEK_END)) {
902 fprintf(stderr,
"ERROR: Could not seek to end of file.\n");
905 realSizeOfSrcMAR = ftello(fpSrc);
906 if (fseeko(fpSrc, oldPos, SEEK_SET)) {
907 fprintf(stderr,
"ERROR: Could not seek back to current location.\n");
911 if (hasSignatureBlock) {
913 if (fread(&sizeOfEntireMAR,
914 sizeof(sizeOfEntireMAR), 1, fpSrc) != 1) {
915 fprintf(stderr,
"ERROR: Could read mar size\n");
919 if (sizeOfEntireMAR != realSizeOfSrcMAR) {
920 fprintf(stderr,
"ERROR: Source MAR is not of the right size\n");
925 if (fread(&numSignatures,
sizeof(numSignatures), 1, fpSrc) != 1) {
926 fprintf(stderr,
"ERROR: Could read num signatures\n");
929 numSignatures =
ntohl(numSignatures);
934 fprintf(stderr,
"ERROR: MAR is already signed\n");
938 sizeOfEntireMAR = realSizeOfSrcMAR;
941 if (((int64_t)offsetToIndex) > sizeOfEntireMAR) {
942 fprintf(stderr,
"ERROR: Offset to index is larger than the file size.\n");
947 for (k = 0; k < certCount; k++) {
948 signatureSectionLength +=
sizeof(signatureAlgorithmID) +
949 sizeof(signatureLengths[k]) +
952 dstOffsetToIndex = offsetToIndex;
953 if (!hasSignatureBlock) {
954 dstOffsetToIndex +=
sizeof(sizeOfEntireMAR) +
sizeof(numSignatures);
956 dstOffsetToIndex += signatureSectionLength;
959 dstOffsetToIndex =
htonl(dstOffsetToIndex);
961 sizeof(dstOffsetToIndex), ctxs, certCount,
965 dstOffsetToIndex =
ntohl(dstOffsetToIndex);
968 sizeOfEntireMAR += signatureSectionLength;
969 if (!hasSignatureBlock) {
970 sizeOfEntireMAR +=
sizeof(sizeOfEntireMAR) +
sizeof(numSignatures);
976 sizeof(sizeOfEntireMAR), ctxs, certCount,
983 numSignatures = certCount;
984 numSignatures =
htonl(numSignatures);
986 sizeof(numSignatures), ctxs, certCount,
990 numSignatures =
ntohl(numSignatures);
992 signaturePlaceholderOffset = ftello(fpDest);
994 for (k = 0; k < certCount; k++) {
996 signatureAlgorithmID =
htonl(1);
998 sizeof(signatureAlgorithmID),
999 ctxs, certCount,
"num signatures")) {
1002 signatureAlgorithmID =
ntohl(signatureAlgorithmID);
1005 signatureLengths[k] =
htonl(signatureLengths[k]);
1007 sizeof(signatureLengths[k]),
1008 ctxs, certCount,
"signature length")) {
1011 signatureLengths[k] =
ntohl(signatureLengths[k]);
1016 memset(buf, 0,
sizeof(buf));
1017 if (fwrite(buf, signatureLengths[k], 1, fpDest) != 1) {
1018 fprintf(stderr,
"ERROR: Could not write signature length\n");
1026 if (ftello(fpSrc) > ((int64_t)offsetToIndex)) {
1027 fprintf(stderr,
"ERROR: Index offset is too small.\n");
1030 numBytesToCopy = ((int64_t)offsetToIndex) - ftello(fpSrc);
1035 for (
i = 0;
i < numChunks; ++
i) {
1045 leftOver, ctxs, certCount,
1046 "left over content block")) {
1052 sizeof(indexLength), ctxs, certCount,
1056 indexLength =
ntohl(indexLength);
1059 indexBuf = malloc(indexLength);
1060 if (fread(indexBuf, indexLength, 1, fpSrc) != 1) {
1061 fprintf(stderr,
"ERROR: Could not read index\n");
1066 if (hasSignatureBlock) {
1070 sizeof(sizeOfEntireMAR) +
1071 sizeof(numSignatures) +
1072 signatureSectionLength);
1076 indexLength, ctxs, certCount,
"index")) {
1086 for (k = 0; k < certCount; k++) {
1088 if (SGN_End(ctxs[k], &secItems[k]) != SECSuccess) {
1089 fprintf(stderr,
"ERROR: Could not end signature context\n");
1092 if (signatureLengths[k] != secItems[k].len) {
1093 fprintf(stderr,
"ERROR: Signature is not the expected length\n");
1099 if (fseeko(fpDest, signaturePlaceholderOffset, SEEK_SET)) {
1100 fprintf(stderr,
"ERROR: Could not seek to signature offset\n");
1104 for (k = 0; k < certCount; k++) {
1106 if (fseeko(fpDest,
sizeof(signatureAlgorithmID) +
1107 sizeof(signatureLengths[k]), SEEK_CUR)) {
1108 fprintf(stderr,
"ERROR: Could not seek to signature offset\n");
1114 if (fwrite(secItems[k].data, secItems[k].len, 1, fpDest) != 1) {
1115 fprintf(stderr,
"ERROR: Could not write signature\n");
1139 for (k = 0; k < certCount; k++) {
1141 SGN_DestroyContext(ctxs[k], PR_TRUE);
1145 CERT_DestroyCertificate(certs[k]);
1149 SECKEY_DestroyPrivateKey(privKeys[k]);
1152 SECITEM_FreeItem(&secItems[k], PR_FALSE);
#define XP_MIN_SIGNATURE_LEN_IN_BYTES
#define NETWORK_TO_HOST64
#define MAX_SIZE_OF_MAR_FILE
#define SIGNATURE_BLOCK_OFFSET
#define HOST_TO_NETWORK64(x)
int get_mar_file_info(const char *path, int *hasSignatureBlock, uint32_t *numSignatures, int *hasAdditionalBlocks, uint32_t *offsetAdditionalBlocks, uint32_t *numAdditionalBlocks)
Determines the MAR file information.
void AdjustIndexContentOffsets(char *indexBuf, uint32_t indexLength, uint32_t offsetAmount)
Adjusts each entry's content offset in the passed in index by the specified amount.
int NSSSignBegin(const char *certName, SGNContext **ctx, SECKEYPrivateKey **privKey, CERTCertificate **cert, uint32_t *signatureLength)
Obtains a signing context.
int import_signature(const char *src, uint32_t sigIndex, const char *base64SigFile, const char *dest)
Imports a base64 encoded signature into a MAR file.
int NSSInitCryptoContext(const char *NSSConfigDir)
Initializes the NSS context.
int extract_signature(const char *src, uint32_t sigIndex, const char *dest)
Extracts a signature from a MAR file, base64 encodes it, and writes it out.
int WriteAndUpdateSignatures(FILE *fpDest, void *buffer, uint32_t size, SGNContext **ctxs, uint32_t ctxCount, const char *err)
Writes the passed buffer to the file fp and updates the signature contexts.
int ReadAndWrite(FILE *fpSrc, FILE *fpDest, void *buffer, uint32_t size, const char *err)
Reads from fpSrc, writes it to fpDest.
int ReadWriteAndUpdateSignatures(FILE *fpSrc, FILE *fpDest, void *buffer, uint32_t size, SGNContext **ctxs, uint32_t ctxCount, const char *err)
Reads from fpSrc, writes it to fpDest, and updates the signature contexts.
int mar_repackage_and_sign(const char *NSSConfigDir, const char *const *certNames, uint32_t certCount, const char *src, const char *dest)
Writes out a copy of the MAR at src but with embedded signatures.
int strip_signature_block(const char *src, const char *dest)
Writes out a copy of the MAR at src but with the signature block stripped.
OUStringBuffer & remove(OUStringBuffer &rIn, sal_Unicode c)
sal_uInt32 htonl(sal_uInt32 h)
sal_uInt32 ntohl(sal_uInt32 n)
char * SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)