예제 #1
0
static off_t get_sig_offset(xar_t x) {
	off_t signedDataOffset = 0;

	xar_signature_t sig = xar_signature_first(x);
	xar_signature_copy_signed_data(sig,NULL,NULL,NULL,NULL,&signedDataOffset);
	signedDataOffset += xar_get_heap_offset(x);
	return signedDataOffset;
}
예제 #2
0
bool InstallChecker::verifyPackage( const QString &filePath, bool )
{
	QProcess proc;
	proc.start( "hdiutil", QStringList() << "verify" << filePath );
	proc.waitForFinished();
	if( proc.exitCode() )
		return false;

	QString path = mountPackage( filePath );
	if( path.isEmpty() )
		return false;

	xar_t xar = xar_open( path.toUtf8().constData(), 0 );
	if( !xar )
		return false;

	QSslCertificate cert;
	xar_signature_t sig = xar_signature_first( xar );
	int32_t count = xar_signature_get_x509certificate_count( sig );
	for( int32_t i = 0; i < count; ++i )
	{
		uint32_t size = 0;
		const uint8_t *data = 0;
		if( xar_signature_get_x509certificate_data( sig, i, &data, &size ) )
			continue;
		QSslCertificate c( QByteArray( (const char*)data, size ), QSsl::Der );
#if QT_VERSION >= 0x050000
		QString cn = c.subjectInfo( QSslCertificate::CommonName ).value(0);
#else
		QString cn = c.subjectInfo( QSslCertificate::CommonName );
#endif
		if( cn == "Estonian Informatics Centre" ||
			cn == "Developer ID Installer: Riigi Infosüsteemi Amet" )
			cert = c;
	}

	if( cert.isNull() )
	{
		xar_close( xar );
		return false;
	}

	uint8_t *data = 0, *signature = 0;
	uint32_t dataSize = 0, signatureSize = 0;
	off_t offset = 0;
	if( xar_signature_copy_signed_data( sig, &data, &dataSize, &signature, &signatureSize, &offset ) )
	{
		xar_close( xar );
		return false;
	}

	int result = RSA_verify( NID_sha1, data, dataSize, signature, signatureSize, (RSA*)cert.publicKey().handle() );
	xar_close( xar );
	free( data );
	free( signature );

	return result;
}
예제 #3
0
static void extract_data_to_sign(const char *filename) {
	xar_signature_t sig;
	off_t signatureOffset;
	FILE *file;
	xar_t x;
	int i;
	uint32_t dataToSignOffset = 0;
	uint32_t dataToSignSize = 0;
	char *buffer = NULL;
	const char *value;
	
	// find signature stub
	x = xar_open(filename, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open %s to extract data to sign!\n", filename);
		exit(1);
	}
	sig = xar_signature_first(x);
	if ( !sig ) {
		fprintf(stderr, "No signatures found to extract data from.\n");
		exit(E_NOSIG);
	}

	// locate data to sign
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/offset" ,&value) ){
		fprintf(stderr, "Could not locate checksum/offset in archive.\n");
		exit(1);
	}
	dataToSignOffset = xar_get_heap_offset(x);
	dataToSignOffset += strtoull(value, (char **)NULL, 10);
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/size" ,&value) ){
		fprintf(stderr, "Could not locate checksum/size in archive.\n");
		exit(1);
	}
	dataToSignSize = strtoull(value, (char **)NULL, 10);

	// get signature offset (inject signature here) 
	xar_signature_copy_signed_data(sig, NULL, NULL, NULL, NULL, &signatureOffset);
	signatureOffset += xar_get_heap_offset(x);
	xar_close(x);
	
	// now get data to be signed, using offset and size
	file = fopen(filename, "r");
	if (!file) {
		fprintf(stderr, "Could not open %s for reading data to sign!\n", filename);
		exit(1);
	}
	fseek(file, dataToSignOffset, SEEK_SET);
	buffer = malloc(dataToSignSize);
	i = fread(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to read data to sign from %s!\n", filename);
		exit(1);
	}
	fclose(file);
	
	// save data to sign
	file = fopen(DataToSignDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving data to sign!\n", DataToSignDumpPath);
		exit(1);
	}
	i = fwrite(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to write data to sign to %s (fwrite() returned %i)!\n", DataToSignDumpPath, i);
		exit(1);
	}
	fclose(file);

	// save signature offset
	file = fopen(SigOffsetDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving signature offset!\n", SigOffsetDumpPath);
		exit(1);
	}
	i = fprintf(file, "%lli\n", signatureOffset);
	if (i < 0) {
		fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", SigOffsetDumpPath, i);
		exit(1);
	}
	fclose(file);
	
	free(buffer);
}