int main(int argc, char *argv[]) {
	if (argc < 3) {
		printf("%s file out\n", argv[0]);
		return 1;
	}
	FILE* in = fopen(argv[1], "rb");
	if (!in) {
		perror(argv[1]);
		return 1;
	}
	fseek(in, 0, SEEK_END);
	uint32_t len = ftell(in);
	fseek(in, 0, SEEK_SET);
	uint8_t* buffer = new uint8_t[len];
	fread(buffer, 1, len, in);
	fclose(in);
	const uint8_t* ptr = buffer + 16;
	len -= 16;
	try {
		SISField* field = SISField::LoadOneField(ptr, len);
		if (field->Id() == SISFieldType::SISContents) {
			SISContents* contents = (SISContents*) field;
			SISCompressed* compressed = (SISCompressed*) contents->FindElement(SISFieldType::SISCompressed);
			compressed->Uncompress();
			compressed->LoadChild();
			SISField* controllerField = compressed->Field();
			if (controllerField->Id() == SISFieldType::SISController) {
				SISController* controller = (SISController*) controllerField;
				FILE* out = fopen(argv[2], "wb");
				if (!out) {
					perror(argv[2]);
					return 1;
				}
				controller->CopyHeaderData(out);
				fclose(out);
			}
		}
		delete field;
	} catch (int i) {
		printf("caught error: %d\n", i);
	}
	delete [] buffer;

	return 0;
}
Esempio n. 2
0
int main(int argc, char *argv[]) {
	initSigning();
	const char* argv0 = argv[0];
	int ch;
	SigType type = SigAuto;
	bool remove = false;
	while ((ch = getopt(argc, argv, "?c:opsuv")) != -1) {
		switch (ch) {
		case 'c':
			if (!strcmp(optarg, "d"))
				type = SigDsa;
			else if (!strcmp(optarg, "r"))
				type = SigRsa;
			else
				fprintf(stderr, "Unknown algorithm\n");
			break;
		case 'o':
			break;
		case 'p':
			break;
		case 's':
			break;
		case 'u':
			remove = true;
			break;
		case '?':
		default:
			showHelp(argv0);
			return 0;
		}
	}

	argc -= optind;
	argv += optind;
	char* input = NULL;
	char* output = NULL;
	char* cert = NULL;
	char* key = NULL;
	char* passphrase = NULL;

	if (argc > 5)
		argc = 5;
	switch (argc) {
	case 5:
		passphrase = argv[4];
	case 4:
		key = argv[3];
	case 3:
		cert = argv[2];
	case 2:
		output = argv[1];
	case 1:
		input = argv[0];
	}

	if (input == NULL) {
		showHelp(argv0);
		return 0;
	}

	if (!output)
		output = input;


	uint8_t header[16];
	SISContents* contents = loadSISFile(input, header);
	if (!contents)
		return 1;

	SISCompressed* cController = (SISCompressed*) contents->FindElement(SISFieldType::SISCompressed);
	TCompressionAlgorithm algorithm = cController->Algorithm();
	cController->Uncompress();
	cController->LoadChild();
	SISField* field = cController->Field();
	if (field->Id() != SISFieldType::SISController) {
		fprintf(stderr, "Bad SIS field type in the top level compressed field\n");
		exit(1);
	}
	SISController* controller = (SISController*) field;

	if (remove) {
		SISField* field = controller->FindRemoveLastElement(SISFieldType::SISSignatureCertificateChain);
		delete field;
	} else {
		SISDataIndex* dataIndex = (SISDataIndex*) controller->FindRemoveElement(SISFieldType::SISDataIndex);
		const char* certData = NULL;
		const char* keyData = NULL;
		bool freeCerts = false;
		if (cert && key) {
			try {
				certData = loadTextFile(cert);
				keyData = loadTextFile(key);
			} catch (SignUtilError err) {
				return err;
			}
			freeCerts = true;
		} else {
			fprintf(stderr, "You must specify certificate and key.\n");
			exit(1);
		}

		try {
			SISSignatureCertificateChain* chain = makeChain(controller, certData, keyData, passphrase, type);
			controller->AddElement(chain);
		} catch (SignUtilError err) {
			return err;
		}
		controller->AddElement(dataIndex);

		if (freeCerts) {
			delete [] certData;
			delete [] keyData;
		}
	}


/*
	FILE* tout = fopen("testcontroller", "wb");
	controller->CopyHeaderData(tout);
	fclose(tout);
*/
	cController->LoadUncompressed();
	cController->Compress(algorithm);

	SISControllerChecksum* csum = (SISControllerChecksum*) contents->FindElement(SISFieldType::SISControllerChecksum);
	updateChecksum(csum, cController);


	FILE* out = fopen(output, "wb");
	fwrite(header, 1, 16, out);
	contents->CopyHeaderData(out);
	fclose(out);
	delete contents;

	cleanupSigning();

	return 0;
}