Beispiel #1
0
u2fs_rc verify_ECDSA(const unsigned char *dgst, int dgst_len,
                     const u2fs_ECDSA_t * sig, u2fs_EC_KEY_t * eckey)
{
  if (dgst == NULL || dgst_len == 0 || sig == NULL || eckey == NULL)
    return U2FS_MEMORY_ERROR;

  int rc =
      ECDSA_do_verify(dgst, dgst_len, (ECDSA_SIG *) sig, (EC_KEY *) eckey);

  if (rc != 1) {
    if (rc == -1) {
      if (debug) {
        unsigned long err = 0;
        err = ERR_get_error();
        fprintf(stderr, "Error: %s, %s, %s\n",
                ERR_lib_error_string(err),
                ERR_func_error_string(err), ERR_reason_error_string(err));
      }
      return U2FS_CRYPTO_ERROR;
    } else {
      return U2FS_SIGNATURE_ERROR;
    }
  }

  return U2FS_OK;
}
Beispiel #2
0
/* returns
 *      1: correct signature
 *      0: incorrect signature
 *     -1: error
 */
int
ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
    const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
{
	ECDSA_SIG *s;
	unsigned char *der = NULL;
	const unsigned char *p = sigbuf;
	int derlen = -1;
	int ret = -1;

	s = ECDSA_SIG_new();
	if (s == NULL)
		return (ret);
	if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
		goto err;
	/* Ensure signature uses DER and doesn't have trailing garbage */
	derlen = i2d_ECDSA_SIG(s, &der);
	if (derlen != sig_len || memcmp(sigbuf, der, derlen))
		goto err;
	ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);

err:
	freezero(der, derlen);
	ECDSA_SIG_free(s);
	return (ret);
}
int verification(
    const unsigned char m[SHORTHASH_BYTES],const unsigned long long mlen,
    const unsigned char sm[SIGNATURE_BYTES],const unsigned long long smlen,
    const unsigned char pk[PUBLICKEY_BYTES],const unsigned long long pklen
    )
{
  unsigned char h[20];
  EC_GROUP *group;
  EC_KEY *k;
  EC_POINT *kxy;
  BIGNUM *kx;
  BIGNUM *ky;
  ECDSA_SIG *rs;
  int len;

  if (smlen != SIGNATURE_BYTES) return -1;
  if (mlen > SHORTHASH_BYTES) return -1;
  SHA1(m,mlen,h);

  group = EC_GROUP_new_by_curve_name(NID);
  if (!group) return -1;

  kx = BN_new(); if (!kx) return -1;
  ky = BN_new(); if (!ky) { BN_free(kx); return -1; }
  kxy = EC_POINT_new(group); if (!kxy) { BN_free(ky); BN_free(kx); return -1; }
  k = EC_KEY_new(); if (!k) { EC_POINT_free(kxy); BN_free(ky); BN_free(kx); return -1; }
  rs = ECDSA_SIG_new(); if (!rs) { EC_KEY_free(k); EC_POINT_free(kxy); BN_free(ky); BN_free(kx); return -1; }

  if (!EC_KEY_set_group(k,group)) goto error;
  if (!BN_bin2bn(pk,PRIME_BYTES,kx)) goto error; pk += PRIME_BYTES;
  if (!BN_bin2bn(pk,PRIME_BYTES,ky)) goto error;
#ifdef PRIME_FIELD
  if (!EC_POINT_set_affine_coordinates_GFp(group,kxy,kx,ky,0)) goto error;
#else
  if (!EC_POINT_set_affine_coordinates_GF2m(group,kxy,kx,ky,0)) goto error;
#endif
  if (!EC_KEY_set_public_key(k,kxy)) goto error;

  if (!BN_bin2bn(sm,PRIME_BYTES,rs->r)) goto error; sm += PRIME_BYTES;
  if (!BN_bin2bn(sm,PRIME_BYTES,rs->s)) goto error;

  len = ECDSA_do_verify(h,20,rs,k);
  ECDSA_SIG_free(rs);
  EC_KEY_free(k);
  EC_POINT_free(kxy);
  BN_free(ky);
  BN_free(kx);

  if (len == 1) return 0;
  if (len == 0) return -100;
  return -1;
  
error:
  ECDSA_SIG_free(rs);
  EC_KEY_free(k);
  EC_POINT_free(kxy);
  BN_free(ky);
  BN_free(kx);
  return -1;
}
Beispiel #4
0
int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
                 const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) {
  ECDSA_SIG *s;
  int ret = 0;
  uint8_t *der = NULL;

  /* Decode the ECDSA signature. */
  s = ECDSA_SIG_from_bytes(sig, sig_len);
  if (s == NULL) {
    goto err;
  }

  /* Defend against potential laxness in the DER parser. */
  size_t der_len;
  if (!ECDSA_SIG_to_bytes(&der, &der_len, s) ||
      der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) {
    /* This should never happen. crypto/bytestring is strictly DER. */
    OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  ret = ECDSA_do_verify(digest, digest_len, s, eckey);

err:
  OPENSSL_free(der);
  ECDSA_SIG_free(s);
  return ret;
}
int main() {
    uint8_t pub_bytes[33] = {
        0x02,
        0x82, 0x00, 0x6e, 0x93, 0x98, 0xa6, 0x98, 0x6e,
        0xda, 0x61, 0xfe, 0x91, 0x67, 0x4c, 0x3a, 0x10,
        0x8c, 0x39, 0x94, 0x75, 0xbf, 0x1e, 0x73, 0x8f,
        0x19, 0xdf, 0xc2, 0xdb, 0x11, 0xdb, 0x1d, 0x28
    };
    uint8_t der_bytes[] = {
        0x30, 0x44, 0x02, 0x20, 0x2b, 0x2b, 0x52, 0x9b,
        0xdb, 0xdc, 0x93, 0xe7, 0x8a, 0xf7, 0xe0, 0x02,
        0x28, 0xb1, 0x79, 0x91, 0x8b, 0x03, 0x2d, 0x76,
        0x90, 0x2f, 0x74, 0xef, 0x45, 0x44, 0x26, 0xf7,
        0xd0, 0x6c, 0xd0, 0xf9, 0x02, 0x20, 0x62, 0xdd,
        0xc7, 0x64, 0x51, 0xcd, 0x04, 0xcb, 0x56, 0x7c,
        0xa5, 0xc5, 0xe0, 0x47, 0xe8, 0xac, 0x41, 0xd3,
        0xd4, 0xcf, 0x7c, 0xb9, 0x24, 0x34, 0xd5, 0x5c,
        0xb4, 0x86, 0xcc, 0xcf, 0x6a, 0xf2
    };
    const char message[] = "This is a very confidential message\n";

    EC_KEY *key;
    const uint8_t *der_bytes_copy;
    ECDSA_SIG *signature;
    uint8_t digest[32];
    int verified;

    key = bbp_ec_new_pubkey(pub_bytes, sizeof(pub_bytes));
    if (!key) {
        puts("Unable to create keypair");
        return -1;
    }

    der_bytes_copy = der_bytes;
    signature = d2i_ECDSA_SIG(NULL, &der_bytes_copy, sizeof(der_bytes));
    printf("r: %s\n", BN_bn2hex(signature->r));
    printf("s: %s\n", BN_bn2hex(signature->s));

    bbp_sha256(digest, (uint8_t *)message, strlen(message));
    bbp_print_hex("digest", digest, 32);
    verified = ECDSA_do_verify(digest, sizeof(digest), signature, key);

    switch (verified) {
        case 1:
            puts("verified");
            break;
        case 0:
            puts("not verified");
            break;
        case -1:
            puts("library error");
            break;
    }

    ECDSA_SIG_free(signature);
    EC_KEY_free(key);

    return 0;
}
Beispiel #6
0
bool BackendOpenSsl::verify_data(const ecdsa256::PublicKey& key, const ByteBuffer& data, const EcdsaSignature& sig)
{
    auto digest = calculate_digest(data);
    auto pub = internal_public_key(key);
    openssl::Signature signature(sig);

    return (ECDSA_do_verify(digest.data(), digest.size(), signature, pub) == 1);
}
Beispiel #7
0
static void
bench_openssl_ecdsa_verify (void *p)
{
  const struct openssl_ecdsa_ctx *ctx = p;
  if (ECDSA_do_verify (ctx->digest, ctx->digest_length,
			 ctx->signature, ctx->key) != 1)
    die ("Openssl ECDSA_do_verify failed.\n");      
}
int el_verify_license_key(el_context_t ctxt,
                          const char *licenseKey, const char *name)
{
    // TODO: change this back to use C99 variable length arrays once Visual C++
    //       can deal with it (2013 still can't)
    ECDSA_SIG *signature = NULL;
    uint8_t *signatureData = NULL;
    uint8_t *digest = NULL;

    if (!licenseKey || !strlen(licenseKey) || !name || !strlen(name))
        return 0;

    // TODO: blocked keys checking

    int signatureLength = el_base32_decode_buffer_size(strlen(licenseKey));

    signatureData = malloc(signatureLength);
    signatureLength = el_base32_decode(licenseKey, signatureData, signatureLength);

    // Check length of signature before verifying
    if (signatureLength != ctxt->digestLength * 2)
    {
        free(signatureData);
        return 0;
    }

    signature = ECDSA_SIG_new();
    if (!signature)
    {
        free(signatureData);
        return 0;
    }

    size_t partLen = signatureLength / 2;
    signature->r = BN_bin2bn(signatureData,           partLen, signature->r);
    signature->s = BN_bin2bn(signatureData + partLen, partLen, signature->s);
    if (!signature->r || !signature->s)
    {
        free(signatureData);
        ECDSA_SIG_free(signature);
        return 0;
    }

    digest = malloc(ctxt->digestLength);
    el_compute_digest(name, digest, ctxt->digestLength);

    int result = ECDSA_do_verify(digest, ctxt->digestLength, signature, ctxt->ecKey) == 1;

    free(signatureData);
    free(digest);
    ECDSA_SIG_free(signature);

    return result;
}
Beispiel #9
0
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
	EC_KEY * eckey = NULL;
	byte rgbDigest[EVP_MAX_MD_SIZE];
	unsigned int cbDigest = sizeof(rgbDigest);
	const EVP_MD * digest;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = &pSigner->m_allocContext;
#endif
	cn_cbor * p = NULL;
	ECDSA_SIG sig = { NULL, NULL };
	int cbR;
	cn_cbor * pSig;
	size_t cbSignature;

	eckey = ECKey_From(pKey, &cbR, perr);
	if (eckey == NULL) {
	errorReturn:
		if (sig.r != NULL) BN_free(sig.r);
		if (sig.s != NULL) BN_free(sig.s);
		if (p != NULL) CN_CBOR_FREE(p, context);
		if (eckey != NULL) EC_KEY_free(eckey);
		return false;
	}

	switch (cbitDigest) {
	case 256: digest = EVP_sha256(); break;
	case 512: digest = EVP_sha512(); break;
	case 384: digest = EVP_sha384(); break;
	default:
		FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
	}
	EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);

	pSig = _COSE_arrayget_int(pSigner, index);
	CHECK_CONDITION(pSig != NULL, CN_CBOR_ERR_INVALID_PARAMETER);
	cbSignature = pSig->length;

	CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER);
	sig.r = BN_bin2bn(pSig->v.bytes,(int) cbSignature/2, NULL);
	sig.s = BN_bin2bn(pSig->v.bytes+cbSignature/2, (int) cbSignature/2, NULL);

	CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, &sig, eckey) == 1, COSE_ERR_CRYPTO_FAIL);

	BN_free(sig.r);
	BN_free(sig.s);
	if (eckey != NULL) EC_KEY_free(eckey);

	return true;
}
Beispiel #10
0
static isc_result_t
opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
	isc_result_t ret;
	dst_key_t *key = dctx->key;
	int status;
	unsigned char *cp = sig->base;
	ECDSA_SIG *ecdsasig = NULL;
	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
	EVP_PKEY *pkey = key->keydata.pkey;
	EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
	unsigned int dgstlen, siglen;
	unsigned char digest[EVP_MAX_MD_SIZE];

	REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
		key->key_alg == DST_ALG_ECDSA384);

	if (eckey == NULL)
		return (ISC_R_FAILURE);

	if (key->key_alg == DST_ALG_ECDSA256)
		siglen = DNS_SIG_ECDSA256SIZE;
	else
		siglen = DNS_SIG_ECDSA384SIZE;

	if (sig->length != siglen)
		return (DST_R_VERIFYFAILURE);

	if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
		DST_RET (ISC_R_FAILURE);

	ecdsasig = ECDSA_SIG_new();
	if (ecdsasig == NULL)
		DST_RET (ISC_R_NOMEMORY);
	ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
	cp += siglen / 2;
	ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
	/* cp += siglen / 2; */

	status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
	if (status != 1)
		DST_RET (dst__openssl_toresult(DST_R_VERIFYFAILURE));
	ret = ISC_R_SUCCESS;

 err:
	if (ecdsasig != NULL)
		ECDSA_SIG_free(ecdsasig);
	if (eckey != NULL)
		EC_KEY_free(eckey);
	return (ret);
}
Beispiel #11
0
/* returns
 *      1: correct signature
 *      0: incorrect signature
 *     -1: error
 */
int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
		const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
 	{
	ECDSA_SIG *s;
	int ret=-1;

	s = ECDSA_SIG_new();
	if (s == NULL) return(ret);
	if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;
	ret=ECDSA_do_verify(dgst, dgst_len, s, eckey);
err:
	ECDSA_SIG_free(s);
	return(ret);
	}
Beispiel #12
0
Datei: jws.c Projekt: cisco/cjose
static bool _cjose_jws_verify_sig_ec(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;

    // ensure jwk is EC
    if (jwk->kty != CJOSE_JWK_KTY_EC)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    ec_keydata *keydata = (ec_keydata *)jwk->keydata;
    EC_KEY *ec = keydata->key;

    ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
    int key_len = jws->sig_len / 2;

#if defined(CJOSE_OPENSSL_11X)
    BIGNUM *pr = BN_new(), *ps = BN_new();
    BN_bin2bn(jws->sig, key_len, pr);
    BN_bin2bn(jws->sig + key_len, key_len, ps);
    ECDSA_SIG_set0(ecdsa_sig, pr, ps);
#else
    BN_bin2bn(jws->sig, key_len, ecdsa_sig->r);
    BN_bin2bn(jws->sig + key_len, key_len, ecdsa_sig->s);
#endif

    if (ECDSA_do_verify(jws->dig, jws->dig_len, ecdsa_sig, ec) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ec_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_ec_cleanup:
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);

    return retval;
}
Beispiel #13
0
int main(int argc, char **argv)
{
	int ok;
	EC_KEY *ec_key;
	ECDSA_SIG *sig;
	unsigned char dgst[32];

	ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
	OPENSSL_assert(ec_key);

	ok = EC_KEY_generate_key(ec_key);
	OPENSSL_assert(ok);

	sig = ECDSA_do_sign(dgst, 32, ec_key);
	ok = ECDSA_do_verify(dgst, 32, sig, ec_key);

	printf("ok = %d\n", ok);

	return 0;
}
Beispiel #14
0
static int openssl_ecdsa_verify(lua_State*L)
{
  size_t l;
  int ret;
  EC_KEY* ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key");
  const char* dgst = luaL_checklstring(L, 2, &l);
  BIGNUM *r = CHECK_OBJECT(3, BIGNUM, "openssl.bn");
  BIGNUM *s = CHECK_OBJECT(4, BIGNUM, "openssl.bn");

  ECDSA_SIG* sig = ECDSA_SIG_new();
  BN_copy(sig->r, r);
  BN_copy(sig->s, s);

  ret = ECDSA_do_verify((const unsigned char*)dgst, l, sig, ec);
  if (ret == -1)
    lua_pushnil(L);
  else
    lua_pushboolean(L, ret);
  ECDSA_SIG_free(sig);
  return 1;
}
Beispiel #15
0
/*-
 * This function hijacks the RNG to feed it the chosen ECDSA key and nonce.
 * The ECDSA KATs are from:
 * - the X9.62 draft (4)
 * - NIST CAVP (720)
 *
 * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG.
 * NB: This is not how applications should use ECDSA; this is only for testing.
 *
 * Tests the library can successfully:
 * - generate public keys that matches those KATs
 * - create ECDSA signatures that match those KATs
 * - accept those signatures as valid
 */
static int x9_62_tests(int n)
{
    int nid, md_nid, ret = 0;
    const char *r_in = NULL, *s_in = NULL, *tbs = NULL;
    unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int dgst_len = 0;
    long q_len, msg_len = 0;
    size_t p_len;
    EVP_MD_CTX *mctx = NULL;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    const BIGNUM *sig_r = NULL, *sig_s = NULL;

    nid = ecdsa_cavs_kats[n].nid;
    md_nid = ecdsa_cavs_kats[n].md_nid;
    r_in = ecdsa_cavs_kats[n].r;
    s_in = ecdsa_cavs_kats[n].s;
    tbs = ecdsa_cavs_kats[n].msg;
    numbers[0] = ecdsa_cavs_kats[n].d;
    numbers[1] = ecdsa_cavs_kats[n].k;

    TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid));

    if (!TEST_ptr(mctx = EVP_MD_CTX_new())
        /* get the message digest */
        || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len))
        || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL))
        || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len))
        || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len))
        /* create the key */
        || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid))
        /* load KAT variables */
        || !TEST_ptr(r = BN_new())
        || !TEST_ptr(s = BN_new())
        || !TEST_true(BN_hex2bn(&r, r_in))
        || !TEST_true(BN_hex2bn(&s, s_in))
        /* swap the RNG source */
        || !TEST_true(change_rand()))
        goto err;

    /* public key must match KAT */
    use_fake = 1;
    if (!TEST_true(EC_KEY_generate_key(key))
        || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED,
                                             &pbuf, NULL))
        || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len))
        || !TEST_int_eq(q_len, p_len)
        || !TEST_mem_eq(qbuf, q_len, pbuf, p_len))
        goto err;

    /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */
    use_fake = 1;
    if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))
        || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len,
                                                  kinv, rp, key))
        /* verify the signature */
        || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1))
        goto err;

    /* compare the created signature with the expected signature */
    ECDSA_SIG_get0(signature, &sig_r, &sig_s);
    if (!TEST_BN_eq(sig_r, r)
        || !TEST_BN_eq(sig_s, s))
        goto err;

    ret = 1;

 err:
    /* restore the RNG source */
    if (!TEST_true(restore_rand()))
        ret = 0;

    OPENSSL_free(message);
    OPENSSL_free(pbuf);
    OPENSSL_free(qbuf);
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(mctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}
Beispiel #16
0
// Verification functions
bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const std::string mechanism)
{
	std::string lowerMechanism;
	lowerMechanism.resize(mechanism.size());
	std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower);

	if (lowerMechanism.compare("ecdsa"))
	{
		ERROR_MSG("Invalid mechanism supplied (%s)", mechanism.c_str());
		return false;
	}

	// Check if the private key is the right type
	if (!publicKey->isOfType(OSSLECPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	OSSLECPublicKey* pk = (OSSLECPublicKey*) publicKey;
	EC_KEY* eckey = pk->getOSSLKey();

	if (eckey == NULL)
	{
		ERROR_MSG("Could not get the OpenSSL public key");

		return false;
	}

	// Perform the verify operation
	size_t len = pk->getOrderLength();
	if (len == 0)
		return false;
	if (signature.size() != 2 * len)
		return false;
	ECDSA_SIG* sig = ECDSA_SIG_new();
	if (sig == NULL)
		return false;
	if (sig->r != NULL)
		BN_clear_free(sig->r);
	const unsigned char *s = signature.const_byte_str();
	sig->r = BN_bin2bn(s, len, NULL);
	if (sig->s != NULL)
		BN_clear_free(sig->s);
	sig->s = BN_bin2bn(s + len, len, NULL);
	if (sig->r == NULL || sig->s == NULL)
	{
		ECDSA_SIG_free(sig);
		return false;
	}
	int ret = ECDSA_do_verify(originalData.const_byte_str(), originalData.size(), sig, eckey);
	if (ret != 1)
	{
		if (ret < 0)
			ERROR_MSG("ECDSA verify failed (0x%08X)", ERR_get_error());

		ECDSA_SIG_free(sig);
		return false;
	}

	ECDSA_SIG_free(sig);
	return true;
}
/* Verify the signature on this transaction using the public key
 * prev_tx->dest_pubkey. The return value is:
 *  1 for successful verification;
 *  0 for failed verification;
 * -1 for any runtime error. */
int transaction_verify(struct transaction *tx, const struct transaction *prev_tx)
{
	unsigned char uint32_buf[4];
	SHA256_CTX sha;
	hash_output h;
	EC_KEY *pubkey;
	ECDSA_SIG *sig;
	BIGNUM *x, *y;
	int v, rc;

	pubkey = NULL;
	sig = NULL;
	x = NULL;
	y = NULL;

	SHA256_Init(&sha);
	serialize_uint32(uint32_buf, tx->height);
	SHA256_Update(&sha, uint32_buf, sizeof(uint32_buf));
	SHA256_Update(&sha, tx->prev_transaction_hash, sizeof(tx->prev_transaction_hash));
	SHA256_Update(&sha, tx->dest_pubkey.x, sizeof(tx->dest_pubkey.x));
	SHA256_Update(&sha, tx->dest_pubkey.y, sizeof(tx->dest_pubkey.y));
	SHA256_Final(h, &sha);

	x = BN_bin2bn(prev_tx->dest_pubkey.x, sizeof(prev_tx->dest_pubkey.x), NULL);
	if (x == NULL)
		goto err;
	y = BN_bin2bn(prev_tx->dest_pubkey.y, sizeof(prev_tx->dest_pubkey.y), NULL);
	if (y == NULL)
		goto err;

	pubkey = EC_KEY_new_by_curve_name(EC_GROUP_NID);
	if (pubkey == NULL)
		goto err;
	rc = EC_KEY_set_public_key_affine_coordinates(pubkey, x, y);
	if (rc != 1) {
		EC_KEY_free(pubkey);
		BN_free(x);
		BN_free(y);
		return 0;
	}

	BN_free(x);
	x = NULL;
	BN_free(y);
	y = NULL;

	sig = ECDSA_SIG_new();
	if (sig == NULL)
		goto err;

	sig->r = BN_bin2bn(tx->src_signature.r, sizeof(tx->src_signature.r), sig->r);
	if (sig->r == NULL)
		goto err;
	sig->s = BN_bin2bn(tx->src_signature.s, sizeof(tx->src_signature.s), sig->s);
	if (sig->s == NULL)
		goto err;

	v = ECDSA_do_verify(h, sizeof(h), sig, pubkey);

	EC_KEY_free(pubkey);
	ECDSA_SIG_free(sig);

	return v;

err:
	if (pubkey != NULL)
		EC_KEY_free(pubkey);
	if (sig != NULL)
		ECDSA_SIG_free(sig);
	if (x != NULL)
		BN_free(x);
	if (y != NULL)
		BN_free(y);

	return -1;
}
Beispiel #18
0
/* some tests from the X9.62 draft */
static int x9_62_test_internal(int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX *md_ctx;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    const BIGNUM *sig_r, *sig_s;

    if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()))
        goto x962_int_err;

    /* get the message digest */
    if (!TEST_true(EVP_DigestInit(md_ctx, EVP_sha1()))
        || !TEST_true(EVP_DigestUpdate(md_ctx, (const void *)message, 3))
        || !TEST_true(EVP_DigestFinal(md_ctx, digest, &dgst_len)))
        goto x962_int_err;

    TEST_info("testing %s", OBJ_nid2sn(nid));

    /* create the key */
    if (!TEST_ptr(key = EC_KEY_new_by_curve_name(nid)))
        goto x962_int_err;
    use_fake = 1;
    if (!TEST_true(EC_KEY_generate_key(key)))
        goto x962_int_err;

    /* create the signature */
    use_fake = 1;
    /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
    if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)))
        goto x962_int_err;
    if (!TEST_ptr(signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key)))
        goto x962_int_err;

    /* compare the created signature with the expected signature */
    if (!TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()))
        goto x962_int_err;
    if (!TEST_true(BN_dec2bn(&r, r_in)) || !TEST_true(BN_dec2bn(&s, s_in)))
        goto x962_int_err;
    ECDSA_SIG_get0(signature, &sig_r, &sig_s);
    if (!TEST_BN_eq(sig_r, r)
            || !TEST_BN_eq(sig_s, s))
        goto x962_int_err;

    /* verify the signature */
    if (!TEST_int_eq(ECDSA_do_verify(digest, 20, signature, key), 1))
        goto x962_int_err;

    ret = 1;

 x962_int_err:
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(md_ctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}
/* some tests from the X9.62 draft */
int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX md_ctx;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;

    EVP_MD_CTX_init(&md_ctx);
    /* get the message digest */
    EVP_DigestInit(&md_ctx, EVP_ecdsa());
    EVP_DigestUpdate(&md_ctx, (const void *)message, 3);
    EVP_DigestFinal(&md_ctx, digest, &dgst_len);

    BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
    /* create the key */
    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        goto x962_int_err;
    if (!EC_KEY_generate_key(key))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create the signature */
    signature = ECDSA_do_sign(digest, 20, key);
    if (signature == NULL)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* compare the created signature with the expected signature */
    if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        goto x962_int_err;
    if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
        goto x962_int_err;
    if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify the signature */
    if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    ret = 1;
x962_int_err:
    if (!ret)
        BIO_printf(out, " failed\n");
    if (key)
        EC_KEY_free(key);
    if (signature)
        ECDSA_SIG_free(signature);
    if (r)
        BN_free(r);
    if (s)
        BN_free(s);
    EVP_MD_CTX_cleanup(&md_ctx);
    return ret;
}
Beispiel #20
0
int main(int argc, char **argv)
{
    char *prog = basename(argv[0]);
    EC_GROUP *ec_group = NULL;
    EC_KEY *ec_key = NULL;
    BN_CTX *ctx = BN_CTX_new();
    const char *id = "*****@*****.**";
    unsigned char za[32];
    BIGNUM *k = NULL;
    BIGNUM *x = NULL;
    ECDSA_SIG *sig = NULL;
    unsigned char dgst[20] = "abc";
    int ret;

    if (!(ec_group = EC_GROUP_new_by_curve_name(NID_sm2t257v1))) {
        fprintf(stderr, "%s: no such curve\n", prog);
        return -1;
    }
    if (!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) {
        fprintf(stderr, "%s: %s %d\n", prog, __FUNCTION__, __LINE__);
        return -1;
    }
    if (!EC_KEY_generate_key(ec_key)) {
        ERR_print_errors_fp(stderr);
        return -1;
    }


    if ((ret = EC_KEY_compute_za(za, EVP_sha256(), id, strlen(id), ec_key)) < 0) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    printf("Za length = %d\n", ret);

    if (!(sig = ECDSA_do_sign(dgst, sizeof(dgst), ec_key))) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    printf("result = %d\n", ret);

    if (!ECDSA_sign_setup(ec_key, ctx, &k, &x)) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    if (!(sig = ECDSA_do_sign_ex(dgst, sizeof(dgst), k, x, ec_key))) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) {
        ERR_print_errors_fp(stderr);
        return -1;
    }
    printf("result = %d\n", ret);


    return 0;
}
// Verification functions
bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData,
		       const ByteString& signature, const AsymMech::Type mechanism,
		       const void* /* param = NULL */, const size_t /* paramLen = 0 */)
{
	if (mechanism != AsymMech::ECDSA)
	{
		ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
		return false;
	}

	// Check if the private key is the right type
	if (!publicKey->isOfType(OSSLECPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	OSSLECPublicKey* pk = (OSSLECPublicKey*) publicKey;
	EC_KEY* eckey = pk->getOSSLKey();

	if (eckey == NULL)
	{
		ERROR_MSG("Could not get the OpenSSL public key");

		return false;
	}

	// Use the OpenSSL implementation and not any engine
	ECDSA_set_method(eckey, ECDSA_OpenSSL());

	// Perform the verify operation
	size_t len = pk->getOrderLength();
	if (len == 0)
	{
		ERROR_MSG("Could not get the order length");
		return false;
	}
	if (signature.size() != 2 * len)
	{
		ERROR_MSG("Invalid buffer length");
		return false;
	}
	ECDSA_SIG* sig = ECDSA_SIG_new();
	if (sig == NULL)
	{
		ERROR_MSG("Could not create an ECDSA_SIG object");
		return false;
	}
	if (sig->r != NULL)
		BN_clear_free(sig->r);
	const unsigned char *s = signature.const_byte_str();
	sig->r = BN_bin2bn(s, len, NULL);
	if (sig->s != NULL)
		BN_clear_free(sig->s);
	sig->s = BN_bin2bn(s + len, len, NULL);
	if (sig->r == NULL || sig->s == NULL)
	{
		ERROR_MSG("Could not add data to the ECDSA_SIG object");
		ECDSA_SIG_free(sig);
		return false;
	}
	int ret = ECDSA_do_verify(originalData.const_byte_str(), originalData.size(), sig, eckey);
	if (ret != 1)
	{
		if (ret < 0)
			ERROR_MSG("ECDSA verify failed (0x%08X)", ERR_get_error());

		ECDSA_SIG_free(sig);
		return false;
	}

	ECDSA_SIG_free(sig);
	return true;
}
Beispiel #22
0
/* ARGSUSED */
int
ssh_ecdsa_verify(const struct sshkey *key,
    const u_char *signature, size_t signaturelen,
    const u_char *data, size_t datalen, u_int compat)
{
	ECDSA_SIG *sig = NULL;
	int hash_alg;
	u_char digest[SSH_DIGEST_MAX_LENGTH];
	size_t dlen;
	int ret = SSH_ERR_INTERNAL_ERROR;
	struct sshbuf *b = NULL, *sigbuf = NULL;
	char *ktype = NULL;

	if (key == NULL || key->ecdsa == NULL ||
	    sshkey_type_plain(key->type) != KEY_ECDSA)
		return SSH_ERR_INVALID_ARGUMENT;

	if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 ||
	    (dlen = ssh_digest_bytes(hash_alg)) == 0)
		return SSH_ERR_INTERNAL_ERROR;

	/* fetch signature */
	if ((b = sshbuf_from(signature, signaturelen)) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if (sshbuf_get_cstring(b, &ktype, NULL) != 0 ||
	    sshbuf_froms(b, &sigbuf) != 0) {
		ret = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if (strcmp(sshkey_ssh_name_plain(key), ktype) != 0) {
		ret = SSH_ERR_KEY_TYPE_MISMATCH;
		goto out;
	}
	if (sshbuf_len(b) != 0) {
		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
		goto out;
	}

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL) {
		ret = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
	    sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
		ret = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if (sshbuf_len(sigbuf) != 0) {
		ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
		goto out;
	}
	if ((ret = ssh_digest_memory(hash_alg, data, datalen,
	    digest, sizeof(digest))) != 0)
		goto out;

	switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) {
	case 1:
		ret = 0;
		break;
	case 0:
		ret = SSH_ERR_SIGNATURE_INVALID;
		goto out;
	default:
		ret = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

 out:
	explicit_bzero(digest, sizeof(digest));
	if (sigbuf != NULL)
		sshbuf_free(sigbuf);
	if (b != NULL)
		sshbuf_free(b);
	if (sig != NULL)
		ECDSA_SIG_free(sig);
	free(ktype);
	return ret;
}
Beispiel #23
0
int
ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	int hash_alg;
	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b, bb;
	char *ktype;

	if (key == NULL || key_type_plain(key->type) != KEY_ECDSA ||
	    key->ecdsa == NULL) {
		error("%s: no ECDSA key", __func__);
		return -1;
	}

	/* fetch signature */
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_string(&b, NULL);
	if (strcmp(key_ssh_name_plain(key), ktype) != 0) {
		error("%s: cannot handle type %s", __func__, ktype);
		buffer_free(&b);
		free(ktype);
		return -1;
	}
	free(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("%s: remaining bytes in signature %d", __func__, rlen);
		free(sigblob);
		return -1;
	}

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		fatal("%s: ECDSA_SIG_new failed", __func__);

	buffer_init(&bb);
	buffer_append(&bb, sigblob, len);
	buffer_get_bignum2(&bb, sig->r);
	buffer_get_bignum2(&bb, sig->s);
	if (buffer_len(&bb) != 0)
		fatal("%s: remaining bytes in inner sigblob", __func__);
	buffer_free(&bb);

	/* clean up */
	explicit_bzero(sigblob, len);
	free(sigblob);

	/* hash the data */
	hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
		error("%s: bad hash algorithm %d", __func__, hash_alg);
		return -1;
	}
	if (ssh_digest_memory(hash_alg, data, datalen,
	    digest, sizeof(digest)) != 0) {
		error("%s: digest_memory failed", __func__);
		return -1;
	}

	ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
	explicit_bzero(digest, sizeof(digest));

	ECDSA_SIG_free(sig);

	debug("%s: signature %s", __func__,
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}
Beispiel #24
0
void
ecdsa_sigverify(val_context_t * ctx,
                const u_char *data,
                size_t data_len,
                const val_dnskey_rdata_t * dnskey,
                const val_rrsig_rdata_t * rrsig,
                val_astatus_t * key_status, val_astatus_t * sig_status)
{
    char            buf[1028];
    size_t          buflen = 1024;
    u_char   sha_hash[MAX_DIGEST_LENGTH];
    EC_KEY   *eckey = NULL;
    BIGNUM *bn_x = NULL;
    BIGNUM *bn_y = NULL;
    ECDSA_SIG *ecdsa_sig;
    size_t   hashlen = 0;

    ecdsa_sig = ECDSA_SIG_new();
    memset(sha_hash, 0, sizeof(sha_hash));

    val_log(ctx, LOG_DEBUG,
            "ecdsa_sigverify(): parsing the public key...");

    if (rrsig->algorithm == ALG_ECDSAP256SHA256) {
        hashlen = SHA256_DIGEST_LENGTH; 
        SHA256(data, data_len, sha_hash);
        eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); /* P-256 */
    } else if (rrsig->algorithm == ALG_ECDSAP384SHA384) {
        hashlen = SHA384_DIGEST_LENGTH; 
        SHA384(data, data_len, sha_hash);
        eckey = EC_KEY_new_by_curve_name(NID_secp384r1); /* P-384 */
    } 

    if (eckey == NULL) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): could not create key for ECDSA group.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    };

    /* 
     * contruct an EC_POINT from the "Q" field in the 
     * dnskey->public_key, dnskey->public_key_len
     */
    if (dnskey->public_key_len != 2*hashlen) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): dnskey length does not match expected size.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    }
    bn_x = BN_bin2bn(dnskey->public_key, hashlen, NULL);
    bn_y = BN_bin2bn(&dnskey->public_key[hashlen], hashlen, NULL);
    if (1 != EC_KEY_set_public_key_affine_coordinates(eckey, bn_x, bn_y)) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): Error associating ECSA structure with key.");
        *key_status = VAL_AC_INVALID_KEY;
        goto err;
    }


    val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): SHA hash = %s",
            get_hex_string(sha_hash, hashlen, buf, buflen));
    val_log(ctx, LOG_DEBUG,
            "ecdsa_sigverify(): verifying ECDSA signature...");

    /* 
     * contruct ECDSA signature from the "r" and "s" fileds in 
     * rrsig->signature, rrsig->signature_len
     */
    if (rrsig->signature_len != 2*hashlen) {
        val_log(ctx, LOG_INFO,
                "ecdsa_sigverify(): Signature length does not match expected size.");
        *sig_status = VAL_AC_RRSIG_VERIFY_FAILED;
        goto err;
    }

    ECDSA_SIG_set0(ecdsa_sig, BN_bin2bn(rrsig->signature, hashlen, NULL),
                   BN_bin2bn(&rrsig->signature[hashlen], hashlen, NULL));

    if (ECDSA_do_verify(sha_hash, hashlen, ecdsa_sig, eckey) == 1) {
        val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned SUCCESS");
        *sig_status = VAL_AC_RRSIG_VERIFIED;
    } else {
        val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned FAILURE");
        *sig_status = VAL_AC_RRSIG_VERIFY_FAILED;
    }

    /* Free all structures allocated */
err:
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    if (bn_x)
        BN_free(bn_x);
    if (bn_y)
        BN_free(bn_y);
    if (eckey)
        EC_KEY_free(eckey);

    return;

}
Beispiel #25
0
int signMessageWithPem(char *message, char *pem, char **signature) {

    unsigned int meslen = strlen(message);
    unsigned char *messagebytes = calloc(meslen, sizeof(unsigned char));
    int derSigLen = 0;
    int i = 0;
    memcpy(messagebytes, message, meslen);

    EC_KEY *key = NULL;
    BIO *in = NULL;
    unsigned char *buffer = NULL;

    char *sha256ofMsg = calloc(SHA256_HEX_STRING, sizeof(char));
    unsigned char *outBytesOfsha256ofMsg = calloc(SHA256_STRING, sizeof(unsigned char));

    digestOfBytes(messagebytes, &sha256ofMsg, "sha256", meslen);
    sha256ofMsg[64] = '\0';
    createDataWithHexString(sha256ofMsg, &outBytesOfsha256ofMsg);
    
    in = BIO_new(BIO_s_mem());
    BIO_puts(in, pem);
    key = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
    
    if(key == NULL) {
       return ERROR;
    } 
    while(derSigLen < 70 && i < 10) {
        i++;
        ECDSA_SIG *sig = ECDSA_do_sign((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, key);
        
        int verify = ECDSA_do_verify((const unsigned char*)outBytesOfsha256ofMsg, SHA256_DIGEST_LENGTH, sig, key);
        
        if(verify != 1) {
            return ERROR;
        }

        int buflen = ECDSA_size(key);
        buffer = OPENSSL_malloc(buflen);

        derSigLen = i2d_ECDSA_SIG(sig, &buffer);
    }
    if(i == 10)
        return ERROR;
    char *hexData = calloc(derSigLen, sizeof(char));
    memcpy(hexData, buffer-derSigLen, derSigLen);

    char *hexString = calloc(derSigLen*2+1, sizeof(char));

    toHexString(hexData, derSigLen, &hexString);
    hexString[derSigLen * 2] = '\0';
    
    memcpy(*signature, hexString, (derSigLen*2)+ 1);

    EC_KEY_free(key);
    BIO_free_all(in);
    
    free(messagebytes);
    free(sha256ofMsg);
    free(outBytesOfsha256ofMsg);
    free(hexData);
    free(hexString);

    return NOERROR;
}
Beispiel #26
0
int ssh_ecdsa_verify(EC_KEY *key, ssh_keytype keytype,
                     u_char *signature, u_int signaturelen,
                     u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	unsigned char digest[EVP_MAX_MD_SIZE], *sigblob;
	unsigned int len, dlen;
	int ret, nid = NID_undef;
	char *ptr;

	OpenSSL_add_all_digests();

	if (key == NULL) {
		return -2;
	}

	ptr = signature;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
		return -3;
	}
	ptr += len;

	len = get_uint32_MSBfirst(ptr);
	ptr += 4;
	sigblob = ptr;
	ptr += len;

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		return -4;
	if ((sig->r = BN_new()) == NULL)
		return -5;
	if ((sig->s = BN_new()) == NULL)
		return -6;

	buffer_get_bignum2(&sigblob, sig->r);
	buffer_get_bignum2(&sigblob, sig->s);
	if (sigblob != ptr) {
		return -7;
	}

	/* hash the data */
	nid = keytype_to_hash_nid(keytype);
	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
		return -8;
	}
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = ECDSA_do_verify(digest, dlen, sig, key);
	memset(digest, 'd', sizeof(digest));

	ECDSA_SIG_free(sig);

	return ret;
}
Beispiel #27
0
/* some tests from the X9.62 draft */
int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
{
    int ret = 0;
    const char message[] = "abc";
    unsigned char digest[20];
    unsigned int dgst_len = 0;
    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    BIGNUM *sig_r, *sig_s;

    if (md_ctx == NULL)
        goto x962_int_err;

    /* get the message digest */
    if (!EVP_DigestInit(md_ctx, EVP_sha1())
        || !EVP_DigestUpdate(md_ctx, (const void *)message, 3)
        || !EVP_DigestFinal(md_ctx, digest, &dgst_len))
        goto x962_int_err;

    BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
    /* create the key */
    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
        goto x962_int_err;
    use_fake = 1;
    if (!EC_KEY_generate_key(key))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* create the signature */
    use_fake = 1;
    /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
    if (!ECDSA_sign_setup(key, NULL, &kinv, &rp))
        goto x962_int_err;
    signature = ECDSA_do_sign_ex(digest, 20, kinv, rp, key);
    if (signature == NULL)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* compare the created signature with the expected signature */
    if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
        goto x962_int_err;
    if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
        goto x962_int_err;
    ECDSA_SIG_get0(&sig_r, &sig_s, signature);
    if (BN_cmp(sig_r, r) || BN_cmp(sig_s, s))
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);
    /* verify the signature */
    if (ECDSA_do_verify(digest, 20, signature, key) != 1)
        goto x962_int_err;
    BIO_printf(out, ".");
    (void)BIO_flush(out);

    BIO_printf(out, " ok\n");
    ret = 1;
 x962_int_err:
    if (!ret)
        BIO_printf(out, " failed\n");
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(md_ctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}
Beispiel #28
0
TACK_RETVAL tackOpenSSLVerifyFunc(uint8_t publicKey[TACK_PUBKEY_LENGTH], 
						uint8_t signature[TACK_SIG_LENGTH],
						uint8_t* data, uint32_t dataLen)
{
    uint8_t pubKeyBuf[TACK_PUBKEY_LENGTH + 1];
    uint8_t hashBuf[TACK_HASH_LENGTH];
    EC_KEY* ec_key = 0;
    EC_GROUP* ec_group = 0;
    EC_POINT* ec_point = 0;
    ECDSA_SIG* ecdsa_sig = 0;
    SHA256_CTX sha256_ctx;	
    TACK_RETVAL retval = TACK_ERR_CRYPTO_FUNC;
    int ret = 0;
    
    /* Prepare the public key to be passed into OpenSSL */
    pubKeyBuf[0] = 0x04;
    memcpy(pubKeyBuf+1, publicKey, TACK_PUBKEY_LENGTH);
    
    /* Create EC_KEY from raw bytes */
    if ((ec_key = EC_KEY_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0)
        goto end;
    if ((ec_group = EC_GROUP_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0)
        goto end;
    if ((ec_point = EC_POINT_new(ec_group)) == 0)
        goto end;		
    if (EC_POINT_oct2point(ec_group, ec_point, pubKeyBuf, 65, 0) == 0) {
        retval = TACK_ERR_BAD_PUBKEY;
        goto end;
    }
    if (EC_KEY_set_public_key(ec_key, ec_point) == 0)
        goto end;
    
    /* Create ECDSA_SIG from raw bytes */
    if ((ecdsa_sig = ECDSA_SIG_new()) == 0)
        goto end;		
    if (BN_bin2bn(signature, TACK_SIG_LENGTH/2, ecdsa_sig->r) == 0)
        goto end;
    if (BN_bin2bn(signature + TACK_SIG_LENGTH/2, TACK_SIG_LENGTH/2, ecdsa_sig->s) == 0)
        goto end;
    
    /* Hash the input data */
    SHA256_Init(&sha256_ctx);  
    SHA256_Update(&sha256_ctx, data, dataLen);   
    SHA256_Final(hashBuf, &sha256_ctx);	
    
    /* Verify the signature */
    ret = ECDSA_do_verify(hashBuf, TACK_HASH_LENGTH, ecdsa_sig, ec_key);
    if (ret == 1)
        retval = TACK_OK;
    else if (ret == 0)
        retval = TACK_ERR_BAD_SIGNATURE;
    else if (ret == -1)
        retval = TACK_ERR_CRYPTO_FUNC;
    
end:
    if (ec_key)
        EC_KEY_free(ec_key);
    if (ec_group)
        EC_GROUP_free(ec_group);
    if (ec_point)
        EC_POINT_free(ec_point);
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    
    return(retval);
}
Beispiel #29
0
int
ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b, bb;
	char *ktype;

	if (key == NULL || key->ecdsa == NULL ||
	    (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) {
		error("%s: no ECDSA key", __func__);
		return -1;
	}
	evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);

	/* fetch signature */
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_string(&b, NULL);
	if (strcmp(key_ssh_name_plain(key), ktype) != 0) {
		error("%s: cannot handle type %s", __func__, ktype);
		buffer_free(&b);
		free(ktype);
		return -1;
	}
	free(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("%s: remaining bytes in signature %d", __func__, rlen);
		free(sigblob);
		return -1;
	}

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		fatal("%s: ECDSA_SIG_new failed", __func__);
	if ((sig->r = BN_new()) == NULL ||
	    (sig->s = BN_new()) == NULL)
		fatal("%s: BN_new failed", __func__);

	buffer_init(&bb);
	buffer_append(&bb, sigblob, len);
	buffer_get_bignum2(&bb, sig->r);
	buffer_get_bignum2(&bb, sig->s);
	if (buffer_len(&bb) != 0)
		fatal("%s: remaining bytes in inner sigblob", __func__);
	buffer_free(&bb);

	/* clean up */
	memset(sigblob, 0, len);
	free(sigblob);

	/* hash the data */
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
	memset(digest, 'd', sizeof(digest));

	ECDSA_SIG_free(sig);

	debug("%s: signature %s", __func__,
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}