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); }
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; }
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; }