Exemple #1
0
void privkey_sign(struct peer *peer, const void *src, size_t len,
		  struct signature *sig)
{
	struct sha256_double h;

	sha256_double(&h, memcheck(src, len), len);
	sign_hash(peer->dstate->secpctx,
		  &peer->dstate->secret->privkey, &h, sig);
}
/* Only does SIGHASH_ALL */
void sign_tx_input(secp256k1_context *secpctx,
		   struct bitcoin_tx *tx,
		   unsigned int in,
		   const u8 *subscript, size_t subscript_len,
		   const struct privkey *privkey, const struct pubkey *key,
		   struct signature *sig)
{
	struct sha256_double hash;

	sha256_tx_one_input(tx, in, subscript, subscript_len, &hash);
	dump_tx("Signing", tx, in, subscript, subscript_len, key, &hash);
	sign_hash(secpctx, privkey, &hash, sig);
}
Exemple #3
0
bool ikev2_calculate_rsa_sha1(struct state *st
			      , enum phase1_role role
			      , unsigned char *idhash
			      , pb_stream *a_pbs)
{
	unsigned char  signed_octets[SHA1_DIGEST_SIZE+16];
	size_t         signed_len;
	const struct connection *c = st->st_connection;
	const struct RSA_private_key *k = get_RSA_private_key(c);
	unsigned int sz;

	if (k == NULL)
	    return 0;	/* failure: no key to use */

	sz = k->pub.k;

        /*
         * this is the prefix of the ASN/DER goop that lives inside RSA-SHA1
         * signatures.  If the signing hash changes, this needs to change
         * too, but this function is specific to RSA-SHA1.
         */
	memcpy(signed_octets, der_digestinfo, der_digestinfo_len);

	ikev2_calculate_sighash(st, role, idhash
				, st->st_firstpacket_me
				, signed_octets+der_digestinfo_len);
	signed_len = der_digestinfo_len + SHA1_DIGEST_SIZE;

	passert(RSA_MIN_OCTETS <= sz && 4 + signed_len < sz && sz <= RSA_MAX_OCTETS);

	DBG(DBG_CRYPT
	    , DBG_dump("v2rsa octets", signed_octets, signed_len));

	{
		u_char sig_val[RSA_MAX_OCTETS];

		/* now generate signature blob */
		sign_hash(k, signed_octets, signed_len
			  , sig_val, sz);
		out_raw(sig_val, sz, a_pbs, "rsa signature");
	}

	return TRUE;
}
Exemple #4
0
bool ikev2_calculate_rsa_sha1(struct state *st,
			      enum phase1_role role,
			      unsigned char *idhash,
			      pb_stream *a_pbs)
{
	unsigned char signed_octets[SHA1_DIGEST_SIZE + 16];
	size_t signed_len;
	const struct connection *c = st->st_connection;
	const struct RSA_private_key *k = get_RSA_private_key(c);
	unsigned int sz;

	if (k == NULL)
		return FALSE; /* failure: no key to use */

	sz = k->pub.k;

	memcpy(signed_octets, der_digestinfo, der_digestinfo_len);

	ikev2_calculate_sighash(st, role, idhash,
				st->st_firstpacket_me,
				signed_octets + der_digestinfo_len);
	signed_len = der_digestinfo_len + SHA1_DIGEST_SIZE;

	passert(RSA_MIN_OCTETS <= sz && 4 + signed_len < sz &&
		sz <= RSA_MAX_OCTETS);

	DBG(DBG_CRYPT,
	    DBG_dump("v2rsa octets", signed_octets, signed_len));

	{
		/* now generate signature blob */
		u_char sig_val[RSA_MAX_OCTETS];
		int shr;

		shr = sign_hash(k, signed_octets, signed_len, sig_val, sz);
		if (shr == 0)
			return FALSE;
		passert(shr == (int)sz);
		if (!out_raw(sig_val, sz, a_pbs, "rsa signature"))
			return FALSE;
	}

	return TRUE;
}
/**
 * Sign the file at the specified path using the private
 * key with the specified label on a token with the specified pin
 * and optionally with the beginning hash state saved in the
 * specified metadata_t from the previous signing.
 */
static void sign(const char* path, const char* pin, const char* label,
	metadata_t* md)
{
	int n, err, sig_size;
	sha256_context ctx;
	sha256_context ctx_cpy;
	const unsigned char *pCms = 0;
	unsigned char buf[0x10000], hash[32]; /* 32 => 256-bit sha256 */
	char sig_path[MAX_PATH] = "";
	FILE * fpi = 0, * fpo = 0;

	/* Open the data file for reading */
	fpi = fopen(path, "rb");
	if (!fpi) {
		int e = errno;
		log_err("error opening file '%s' for reading: %s", path, strerror(e));
		goto sign_error;
	}

	/* Get the saved hash context or start a new one */
	if (!md) { /* No metadata */
		/* Start a new hash context */
		sha256_starts(&ctx);
	} else { /* Metadata exists */
		/* Restore the saved hash context */
		int ok;
		/* Get the saved hashed content length (hcl) */
		offset_t hcl = sizeof(hcl) == 4 ? md->cll : (offset_t)md->clh << 32 | md->cll;
		/* Adjust the hcl back to the last block boundary */
		hcl = hcl - hcl % sizeof(ctx.buffer);
		/* Restore the "total" (hcl) field to the hash context */
		ctx.total[0] = (unsigned int)hcl;
		ctx.total[1] = (unsigned int)(hcl >> 32);
		/* Restore the state field to the hash context */
		memcpy(&ctx.state, &md->state, sizeof(ctx.state));
		/* Seek to the position of hcl minus one & verify last byte still exists */
		ok = hcl <= 0 || fseeko(fpi, hcl - 1, SEEK_SET) == 0 && getc(fpi) >= 0;
		if (!ok) {
			if (sizeof(hcl) == 4) /* 32-bit hcl */
				log_err("error seeking in '%s' to pos %d", path, (int)hcl);
			else /* 64-bit hcl */
				log_err("error seeking in '%s' to pos %lld", path, hcl);
			goto sign_error;
		}
	}

	/* Create/Continue a SHA-256 hash of the file */
	for (;;) {
		int n = fread(buf, 1, sizeof(buf), fpi);
		if (n <= 0)
			break;
		sha256_update(&ctx, buf, n);
	}

	/* Check for error during read */
	if (ferror(fpi)) {
		log_err("error reading file '%s'", path);
		goto sign_error;
	}

	/* Close the data file */
	err = fclose(fpi);
	if (err) {
		int e = errno;
		log_err("error closing file '%s': %s", path, strerror(e));
		goto sign_error;
	}
	fpi = 0;

	/* Clone the unfinalized hash context to save in the metadata */
	memcpy(&ctx_cpy, &ctx, sizeof(ctx));

	/* Finalize the hash for the current sig */
	sha256_finish(&ctx, hash);

	/* Sign the hash with the token; creates CMS document & puts ptr in pCMS
	   WARNING: sign_hash is not re-entrant (see sc-hsm-ultralite.c) */
	sig_size = sign_hash(pin, label, hash, sizeof(hash), &pCms);
	if (sig_size <= 0) {
		goto sign_error;
	}

	/* Open the new sig file for writing */
	n = snprintf(sig_path, sizeof(sig_path), "%s%s", path, sig_ext);
	if (n < 0 || n >= sizeof(sig_path)) {
		log_err("error building sig file path '%s%s'", path, sig_ext);
		goto sign_error;
	}
	fpo = fopen(sig_path, "wb");
	if (!fpo) {
		int e = errno;
		log_err("error opening sig file '%s' for writing: %s",
			sig_path, strerror(e));
		goto sign_error;
	}

	/* Write the CMS document to the sig file */
	n = fwrite(pCms, 1, sig_size, fpo);
	if (n != sig_size) {
		log_err("error writing to sig file '%s'", sig_path);
		goto sign_error;
	}

	/* Save "total" (hcl) & unfinalized hash state at end of sig file */
	err = write_metadata(fpo, &ctx_cpy);
	if (err) {
		log_err("error writing metadata to sig file '%s'", sig_path);
		goto sign_error;
	}

	/* Close the sig file */
	err = fclose(fpo);
	if (err) {
		log_err("error closing sig file '%s'", sig_path);
		goto sign_error;
	}
	fpo = 0;

	/* Success */
	log_inf("'%s' created", sig_path);
	return;

sign_error:
	/* Close input file stream, if open */
	if (fpi) {
		err = fclose(fpi);
		if (err) {
			int e = errno;
			log_err("error closing file '%s': %s",
				path, strerror(e));
		}
	}
	/* Close output file stream, if open */
	if (fpo) {
		err = fclose(fpo);
		if (err) {
			int e = errno;
			log_err("error closing sig file '%s': %s",
				sig_path, strerror(e));
		}
	}
	return;
}
int main(int argc, char **argv)
{
	int i;
	FILE* fp;
	unsigned char buf[0x10000], hash[32]; /* 32 => 256-bit sha256 */
	sha256_context ctx;
	char name[256];
	const unsigned char *pCms = 0;
	int count = argc >= 4 ? atoi(argv[3]) : 1;
	int wait  = argc >= 5 ? atoi(argv[4]) : 10000;

#if defined(_WIN32) && defined(_DEBUG)
	atexit((void(*)(void))_CrtDumpMemoryLeaks);
#endif

	/* Check args */
	if (argc < 3) {
		printf("Usage: pin label [count [wait-in-milliseconds]]\nSign this executable (%s).\n", argv[0]);
		return 1;
	}

	/* Create a SHA-256 hash of this executable */
	sha256_starts(&ctx);
	fp = fopen(argv[0], "rb");
	if (!fp) {
		int e = errno;
		printf("error opening file '%s': %s\n", argv[0], strerror(e));
		return e;
	}
	for (;;) {
		int n = fread(buf, 1, sizeof(buf), fp);
		if (n <= 0)
			break;
		sha256_update(&ctx, buf, n);
	}
	fclose(fp);
	sha256_finish(&ctx, hash);

	/* Sign the hash of this executable n times, where n = count */
	for (i = 0; i < count; i++) {
		int len;
		long start, end;
		if (i > 0 && count > 1) {
			printf("wait %d milliseconds for next signature\n", wait);
			usleep(wait * 1000);
		}
		start = GetTickCount();
		len   = sign_hash(argv[1], argv[2], hash, sizeof(hash), &pCms);
		end   = GetTickCount();
		printf("sign_hash returned: %d, time used: %ld ms\n", len, end - start);
		if (len <= 0) /* sign_hash error */
			break;
		sprintf(name, "%s.p7s", argv[0]);
		fp = fopen(name, "wb");\
		if (!fp) {
			int e = errno;
			printf("error opening file '%s': %s\n", name, strerror(e));
			break;
		}
		fwrite(pCms, 1, len, fp);
		fclose(fp);
	}
	release_template();

	return 0;
}