Beispiel #1
0
bool CKey::SetSecret(const CSecret& vchSecret, bool fCompressed)
{
    EC_KEY_free(pkey);
    pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
    if (pkey == NULL)
        throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
    if (vchSecret.size() != 32)
        throw key_error("CKey::SetSecret() : secret must be 32 bytes");
    BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
    if (bn == NULL)
        throw key_error("CKey::SetSecret() : BN_bin2bn failed");
    if (!EC_KEY_regenerate_key(pkey,bn))
    {
        BN_clear_free(bn);
        throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
    }
    BN_clear_free(bn);
    fSet = true;
    if (fCompressed || fCompressedPubKey)
        SetCompressedPubKey();
    return true;
}
Beispiel #2
0
/* ECDH temporary parameters */
static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
{
    int rv = 1;
    EC_KEY *ecdh;
    int nid;

    nid = EC_curve_nist2nid(value);
    if (nid == NID_undef)
        nid = OBJ_sn2nid(value);
    if (nid == 0)
        return 0;
    ecdh = EC_KEY_new_by_curve_name(nid);
    if (!ecdh)
        return 0;
    if (cctx->ctx)
        rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
    else if (cctx->ssl)
        rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
    EC_KEY_free(ecdh);

    return rv > 0;
}
static void
initialize_ecdh(void)
{
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_ECDH)
	EC_KEY	   *ecdh;
	int			nid;

	nid = OBJ_sn2nid(SSLECDHCurve);
	if (!nid)
		ereport(FATAL,
				(errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));

	ecdh = EC_KEY_new_by_curve_name(nid);
	if (!ecdh)
		ereport(FATAL,
				(errmsg("ECDH: could not create key")));

	SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_ECDH_USE);
	SSL_CTX_set_tmp_ecdh(SSL_context, ecdh);
	EC_KEY_free(ecdh);
#endif
}
Beispiel #4
0
SOTER_PRIVATE_API
soter_status_t soter_asym_ka_init(soter_asym_ka_t* asym_ka_ctx, soter_asym_ka_alg_t alg)
{
    EVP_PKEY* pkey;
    int nid = soter_alg_to_curve_nid(alg);

    if ((!asym_ka_ctx) || (0 == nid)) {
        return SOTER_INVALID_PARAMETER;
    }

    pkey = EVP_PKEY_new();
    if (!pkey) {
        return SOTER_NO_MEMORY;
    }

    if (!EVP_PKEY_set_type(pkey, EVP_PKEY_EC)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }

    asym_ka_ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (!(asym_ka_ctx->pkey_ctx)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }
    EC_KEY* ec = EC_KEY_new_by_curve_name(nid);
    if (!ec) {
        EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx);
        return SOTER_FAIL;
    }

    if (1 != EVP_PKEY_set1_EC_KEY(pkey, ec)) {
        EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx);
        EC_KEY_free(ec);
        return SOTER_FAIL;
    }
    EC_KEY_free(ec);
    return SOTER_SUCCESS;
}
Beispiel #5
0
static isc_result_t
opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
	isc_result_t ret;
	EVP_PKEY *pkey;
	EC_KEY *eckey = NULL;
	int group_nid;

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

	if (key->key_alg == DST_ALG_ECDSA256)
		group_nid = NID_X9_62_prime256v1;
	else
		group_nid = NID_secp384r1;

	eckey = EC_KEY_new_by_curve_name(group_nid);
	if (eckey == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));

	if (EC_KEY_generate_key(eckey) != 1)
		DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));

	pkey = EVP_PKEY_new();
	if (pkey == NULL)
		DST_RET (ISC_R_NOMEMORY);
	if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
		EVP_PKEY_free(pkey);
		DST_RET (ISC_R_FAILURE);
	}
	key->keydata.pkey = pkey;
	ret = ISC_R_SUCCESS;

 err:
	if (eckey != NULL)
		EC_KEY_free(eckey);
	return (ret);
}
Beispiel #6
0
void SSLCommon::load_ecdh_params(SSL_CTX *ctx, Logger &logger)
{
	SSL_CTX_set_options(ctx,
			SSL_OP_SINGLE_DH_USE |
			SSL_OP_SINGLE_ECDH_USE |
			SSL_OP_NO_SSLv2);

	/* Cheesily pick an elliptic curve to use with elliptic curve ciphersuites.
	 * We just hardcode a single curve which is reasonably decent.
	 * See http://www.mail-archive.com/[email protected]/msg30957.html */
	EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
	if (! ecdh)
	{
		logger << "Couldn't create elliptic curve" << endl;
		exitSSL("EC_KEY_new_by_curve_name(ecdh)");
	}
	if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh))
	{
		logger << "Couldn't set ecdh parameters" << endl;
		exitSSL("SSL_CTX_set_tmp_ecdh(ecdh)");
	}
}
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
{
    EC_POINT *p;
    const EC_GROUP *g;
    int ok;

    key->ecdsa_nid = nid;
    key->type_c = pki_key_ecdsa_nid_to_name(nid);

    key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
    if (key->ecdsa == NULL) {
        return -1;
    }

    g = EC_KEY_get0_group(key->ecdsa);

    p = EC_POINT_new(g);
    if (p == NULL) {
        return -1;
    }

    ok = EC_POINT_oct2point(g,
                            p,
                            ssh_string_data(e),
                            ssh_string_len(e),
                            NULL);
    if (!ok) {
        EC_POINT_free(p);
        return -1;
    }

    ok = EC_KEY_set_public_key(key->ecdsa, p);
    if (!ok) {
        EC_POINT_free(p);
    }

    return 0;
}
Beispiel #8
0
// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig)
{
    if (vchSig.size() != 65)
        return false;
    int nV = vchSig[0];
    if (nV<27 || nV>=35)
        return false;
    ECDSA_SIG *sig = ECDSA_SIG_new();
    if (!sig) return false;

    #if OPENSSL_VERSION_NUMBER > 0x1000ffffL
    // sig_r and sig_s are deallocated by ECDSA_SIG_free(sig);
    BIGNUM *sig_r = BN_bin2bn(&vchSig[1],32,BN_new());
    BIGNUM *sig_s = BN_bin2bn(&vchSig[33],32,BN_new());
    if (!sig_r || !sig_s) return false;
    // copy and transfer ownership to sig
    ECDSA_SIG_set0(sig, sig_r, sig_s);
    #else
    BN_bin2bn(&vchSig[1],32,sig->r);
    BN_bin2bn(&vchSig[33],32,sig->s);
    #endif

    EC_KEY_free(pkey);
    pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
    if (nV >= 31)
    {
        SetCompressedPubKey();
        nV -= 4;
    }
    if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), nV - 27, 0) == 1)
    {
        fSet = true;
        ECDSA_SIG_free(sig);
        return true;
    }
    ECDSA_SIG_free(sig);
    return false;
}
Beispiel #9
0
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
  const uint8_t *p = NULL;
  void *pval;
  int ptype, pklen;
  EC_KEY *eckey = NULL;
  X509_ALGOR *palg;

  if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
    return 0;
  }
  X509_ALGOR_get0(NULL, &ptype, &pval, palg);

  if (ptype != V_ASN1_OBJECT) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }
  eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid((ASN1_OBJECT *)pval));
  if (eckey == NULL) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
    return 0;
  }

  /* We have parameters now set public key */
  if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    goto err;
  }

  EVP_PKEY_assign_EC_KEY(pkey, eckey);
  return 1;

err:
  if (eckey) {
    EC_KEY_free(eckey);
  }
  return 0;
}
static void
attempt_parse_blob(u_char *blob, size_t len)
{
	struct sshbuf *p1;
	BIGNUM *bn;
	EC_KEY *eck;
	u_char *s;
	size_t l;
	u_int8_t u8;
	u_int16_t u16;
	u_int32_t u32;
	u_int64_t u64;

	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
	sshbuf_get_u8(p1, &u8);
	sshbuf_get_u16(p1, &u16);
	sshbuf_get_u32(p1, &u32);
	sshbuf_get_u64(p1, &u64);
	if (sshbuf_get_string(p1, &s, &l) == 0) {
		bzero(s, l);
		free(s);
	}
	bn = BN_new();
	if (sshbuf_get_bignum1(p1, bn) == 0)
		BN_clear_free(bn);
	bn = BN_new();
	if (sshbuf_get_bignum2(p1, bn) == 0)
		BN_clear_free(bn);
	eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
	ASSERT_PTR_NE(eck, NULL);
	if (sshbuf_get_eckey(p1, eck) == 0)
		EC_KEY_free(eck);
	sshbuf_free(p1);
}
Beispiel #11
0
// Get the AlphaCrypt default PEER public Key
EC_POINT * CAlphaCrypt::GetAlphaCryptPublicKey() {
	EC_KEY * lpPublicCurve = NULL;				// Curve that contains the public key
	EC_POINT * pubKey = NULL;					// Public key generated from the 2 coordinates
	const LPSTR XCoordHex = "46668077A4449322CA896BD64901DE333156B6FEAE75ABE5D4922A039B3CD013";
	const LPSTR YCoordHex = "304AB8B3F15F498094F14058A1D1EBE823BEF512D44210CC50BBD94128D2CD05";
	BIGNUM * pBnX = NULL, * pBnY = NULL;
	int iRet = 0;

	// Allocate the 2 points structures
	pBnX = BN_new(); pBnY = BN_new();

	// Get X and Y Coordinate
	BN_hex2bn(&pBnX, XCoordHex);
	BN_hex2bn(&pBnY, YCoordHex);

	// Create the curve that contains the public key 
	lpPublicCurve = EC_KEY_new_by_curve_name(NID_secp256k1);

	// Create the generator 
	pubKey = EC_POINT_new(lpPublicCurve->group);

	// Generate the Public key and verify it
	EC_POINT_set_affine_coordinates_GFp(lpPublicCurve->group, pubKey, pBnX, pBnY, NULL);
	EC_KEY_set_public_key(lpPublicCurve, pubKey);
	iRet = EC_KEY_check_key(lpPublicCurve);

	// Cleanup
	EC_KEY_free(lpPublicCurve);
	BN_free(pBnX); BN_free(pBnY);

	if (iRet)
		return pubKey;
	else 
		EC_POINT_free(pubKey);
	return NULL;
}
Beispiel #12
0
static void test_ecdsa_sign(void)
{
    EVP_PKEY *pkey;

    { /* create pkey */
        EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
        EC_KEY_generate_key(eckey);
        pkey = EVP_PKEY_new();
        EVP_PKEY_set1_EC_KEY(pkey, eckey);
        EC_KEY_free(eckey);
    }

    const char *message = "hello world";
    ptls_buffer_t sigbuf;
    uint8_t sigbuf_small[1024];

    ptls_buffer_init(&sigbuf, sigbuf_small, sizeof(sigbuf_small));
    ok(do_sign(pkey, &sigbuf, ptls_iovec_init(message, strlen(message)), EVP_sha256()) == 0);
    EVP_PKEY_up_ref(pkey);
    ok(verify_sign(pkey, ptls_iovec_init(message, strlen(message)), ptls_iovec_init(sigbuf.base, sigbuf.off)) == 0);

    ptls_buffer_dispose(&sigbuf);
    EVP_PKEY_free(pkey);
}
Beispiel #13
0
void
ssl_set_ecdh_curve(SSL_CTX *ctx, const char *curve)
{
	int	nid;
	EC_KEY *ecdh;

	if (curve == NULL)
		curve = SSL_ECDH_CURVE;
	if ((nid = OBJ_sn2nid(curve)) == 0) {
		ssl_error("ssl_set_ecdh_curve");
		fatal("ssl_set_ecdh_curve: unknown curve name "
		    SSL_ECDH_CURVE);
	}

	if ((ecdh = EC_KEY_new_by_curve_name(nid)) == NULL) {
		ssl_error("ssl_set_ecdh_curve");
		fatal("ssl_set_ecdh_curve: unable to create curve "
		    SSL_ECDH_CURVE);
	}

	SSL_CTX_set_tmp_ecdh(ctx, ecdh);
	SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
	EC_KEY_free(ecdh);
}
Beispiel #14
0
// reconstruct public key from a compact signature
// This is only slightly more CPU intensive than just verifying it.
// If this function succeeds, the recovered public key is guaranteed to be valid
// (the signature is a valid signature of the given data for that key)
bool CKey::SetCompactSignature(uint256 hash, const std::vector<unsigned char> &vchSig)
{
	if (vchSig.size() != 65)
		return false;
	int nV = vchSig[0];
	if (nV < 27 || nV >= 35)
		return false;
	ECDSA_SIG *sig = ECDSA_SIG_new();
	BN_bin2bn(&vchSig[1], 32, sig->r);
	BN_bin2bn(&vchSig[33], 32, sig->s);

	EC_KEY_free(pkey);
	pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
	if (nV >= 31) {
		SetCompressedPubKey();
		nV -= 4;
	}
	if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char *)&hash, sizeof(hash), nV - 27, 0) == 1) {
		fSet = true;
		ECDSA_SIG_free(sig);
		return true;
	}
	return false;
}
Beispiel #15
0
static int
lws_context_ssl_init_ecdh_curve(struct lws_context_creation_info *info,
				struct lws_vhost *vhost)
{
#if defined(LWS_HAVE_OPENSSL_ECDH_H) && !defined(LWS_WITH_MBEDTLS)
	EC_KEY *ecdh;
	int ecdh_nid;
	const char *ecdh_curve = "prime256v1";

	if (info->ecdh_curve)
		ecdh_curve = info->ecdh_curve;

	ecdh_nid = OBJ_sn2nid(ecdh_curve);
	if (NID_undef == ecdh_nid) {
		lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve);
		return 1;
	}

	ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
	if (NULL == ecdh) {
		lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve);
		return 1;
	}
	SSL_CTX_set_tmp_ecdh(vhost->ssl_ctx, ecdh);
	EC_KEY_free(ecdh);

	SSL_CTX_set_options(vhost->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);

	lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve);
#else
#if !defined(LWS_WITH_MBEDTLS)
	lwsl_notice(" OpenSSL doesn't support ECDH\n");
#endif
#endif
	return 0;
}
Beispiel #16
0
static EP_STAT
generate_ec_key(EP_CRYPTO_KEY *key, const char *curve)
{
	if (curve == NULL)
		curve = ep_adm_getstrparam("libep.crypto.key.ec.curve",
				"sect283r1");
	int nid = OBJ_txt2nid(curve);
	if (nid == NID_undef)
	{
		_ep_crypto_error("unknown EC curve name %s", curve);
		goto fail0;
	}
	EC_KEY *eckey = EC_KEY_new_by_curve_name(nid);
	if (eckey == NULL)
	{
		_ep_crypto_error("cannot create EC key");
		goto fail0;
	}
	if (!EC_KEY_generate_key(eckey))
	{
		_ep_crypto_error("cannot generate EC key");
		goto fail1;
	}
	if (EVP_PKEY_assign_EC_KEY(key, eckey) != 1)
	{
		_ep_crypto_error("cannot assign EC key");
		goto fail1;
	}
	return EP_STAT_OK;

fail1:
	EC_KEY_free(eckey);

fail0:
	return EP_STAT_CRYPTO_KEYCREATE;
}
Beispiel #17
0
/*
 * Set elliptic curve.
 */
static int set_ec_params(SSL_CTX * ctx, const char* curve_name)
{
	int curve = 0;
	if (curve_name) {
		curve = OBJ_txt2nid(curve_name);
	}
	if (curve > 0) {
		EC_KEY *ecdh = EC_KEY_new_by_curve_name (curve);
		if (! ecdh) {
			LM_ERR("unable to create EC curve\n");
			return -1;
		}
		if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) {
			LM_ERR("unable to set tmp_ecdh\n");
			return -1;
		}
		EC_KEY_free (ecdh);
	}
	else {
		LM_ERR("unable to find the EC curve\n");
		return -1;
	}
    return 0;
}
Beispiel #18
0
NOEXPORT int ecdh_init(SERVICE_OPTIONS *section) {
#ifdef WITH_WOLFSSL
    /* wolfSSL automatically detects ecdh parameters from ECC key file.
     * No need to load explicitly */
    (void)section;
    return 0;
#else
    EC_KEY *ecdh;

    s_log(LOG_DEBUG, "ECDH initialization");
    ecdh=EC_KEY_new_by_curve_name(section->curve);
    if(!ecdh) {
        sslerror("EC_KEY_new_by_curve_name");
        s_log(LOG_ERR, "Cannot create curve %s",
            OBJ_nid2ln(section->curve));
        return 1; /* FAILED */
    }
    SSL_CTX_set_tmp_ecdh(section->ctx, ecdh);
    EC_KEY_free(ecdh);
    s_log(LOG_DEBUG, "ECDH initialized with curve %s",
        OBJ_nid2ln(section->curve));
    return 0; /* OK */
#endif /* WITH_WOLFSSL */
}
Beispiel #19
0
int main (int argc, const char * argv[]) {
	
	EC_KEY *eckey;

	unsigned int curve;
	size_t digest_len;
	
	char name[1024], curve_name[200], pubkey[1024], privkey[1024];

	if (!read_params(name, 1024, curve_name, 200, pubkey, 1024, privkey, 1024))
		return ERR_STDIN_READ;
	
	///*debug*/printf("%s\n%s\n%s\n%s\n", name, curve_name, pubkey, privkey);
	
	// Get curve type and digest_len
	if (strcmp(curve_name, "secp112r1") == 0) {
		curve = NID_secp112r1;
		digest_len = 14;
	} else if (strcmp(curve_name, "secp128r1") == 0) {
		curve = NID_secp128r1;
		digest_len = 16;		
	} else if (strcmp(curve_name, "secp160r1") == 0) {
		curve = NID_secp160r1;
		digest_len = 20;		
	} else {
		return ERR_CURVE_UNKNOWN;
	}
	
	eckey = EC_KEY_new_by_curve_name(curve);
	if (eckey == NULL)
		return ERR_INIT_KEY;
	
	// set public key
	unsigned char *bin = NULL;
	size_t len = hex2bin(&bin, pubkey);
	if (len == 0)
		return ERR_PUBLIC_KEY_DECODING;
	const unsigned char *bin_copy = bin;
	eckey = o2i_ECPublicKey(&eckey, &bin_copy, len);
	OPENSSL_free(bin);
	
	// set private key
	len = hex2bin(&bin, privkey);
	if (len == 0)
		return ERR_PUBLIC_KEY_DECODING;
	bin_copy = bin;
	eckey = d2i_ECPrivateKey(&eckey, &bin_copy, len);
	OPENSSL_free(bin);
	
	// check keys
	if (!EC_KEY_check_key(eckey))
		return ERR_WRONG_KEYS;
	
	// calculate sha-1
	unsigned char digest[digest_len];
    el_compute_digest(name, digest, digest_len);

	// sign
	ECDSA_SIG *sig = ECDSA_do_sign(digest, digest_len, eckey);
	if (sig == NULL)
		return ERR_SIGNING;
	
	size_t rlen = BN_num_bytes(sig->r);
	size_t slen = BN_num_bytes(sig->s);
	size_t binlen = rlen + slen;
	bin = OPENSSL_malloc(binlen);
	bzero(bin, binlen);
	BN_bn2bin(sig->r, bin);
	BN_bn2bin(sig->s, bin + rlen); // join two values into bin
	ECDSA_SIG_free(sig);
	
	size_t b32len = el_base32_encode_buffer_size(binlen);
	char *base32 = OPENSSL_malloc(b32len);
	bzero(base32, b32len);

    el_base32_encode(bin, binlen, base32, b32len);
	printf("%s", base32);
	
	OPENSSL_free(bin);
	OPENSSL_free(base32);
	return 0;
}
Beispiel #20
0
Key *key_private_deserialize(buffer_t *blob)
{
	int success = 0;
	char *type_name = NULL;
	Key *k = NULL;
	unsigned int pklen, sklen;
	int type;

	type_name = buffer_get_string_msg(blob, NULL);
	if (type_name == NULL)
		goto error;
	type = get_keytype_from_name(type_name);

	k = key_new_private(type);

	switch (type) {
		case KEY_RSA:
			buffer_get_bignum2_msg(blob, k->rsa->n);
			buffer_get_bignum2_msg(blob, k->rsa->e);
			buffer_get_bignum2_msg(blob, k->rsa->d);
			buffer_get_bignum2_msg(blob, k->rsa->iqmp);
			buffer_get_bignum2_msg(blob, k->rsa->p);
			buffer_get_bignum2_msg(blob, k->rsa->q);

			/* Generate additional parameters */
			rsa_generate_additional_parameters(k->rsa);
			break;

		case KEY_DSA:
			buffer_get_bignum2_msg(blob, k->dsa->p);
			buffer_get_bignum2_msg(blob, k->dsa->q);
			buffer_get_bignum2_msg(blob, k->dsa->g);
			buffer_get_bignum2_msg(blob, k->dsa->pub_key);
			buffer_get_bignum2_msg(blob, k->dsa->priv_key);
			break;

		case KEY_ECDSA256:
		case KEY_ECDSA384:
		case KEY_ECDSA521:
			{
			int success = 0;
			unsigned int nid;
			char *curve = NULL;
			ssh_keytype skt;
			BIGNUM *exponent = NULL;
			EC_POINT *q = NULL;

			nid = keytype_to_cipher_nid(type);
			curve = buffer_get_string_msg(blob, NULL);
			skt = key_curve_name_to_keytype(curve);
			if (nid != keytype_to_cipher_nid(skt))
				goto ecdsa_error;

			k->ecdsa = EC_KEY_new_by_curve_name(nid);
			if (k->ecdsa == NULL)
				goto ecdsa_error;

			q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
			if (q == NULL)
				goto ecdsa_error;

			if ((exponent = BN_new()) == NULL)
				goto ecdsa_error;
			buffer_get_ecpoint_msg(blob,
				EC_KEY_get0_group(k->ecdsa), q);
			buffer_get_bignum2_msg(blob, exponent);
			if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
				goto ecdsa_error;
			if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
				goto ecdsa_error;
			if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
				EC_KEY_get0_public_key(k->ecdsa)) != 0)
				goto ecdsa_error;
			if (key_ec_validate_private(k->ecdsa) != 0)
				goto ecdsa_error;

			success = 1;

ecdsa_error:
			free(curve);
			if (exponent)
				BN_clear_free(exponent);
			if (q)
				EC_POINT_free(q);
			if (success == 0)
				goto error;
			}
			break;

		case KEY_ED25519:
			k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
			k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
			if (pklen != ED25519_PK_SZ) 
				goto error;
			if (sklen != ED25519_SK_SZ)
				goto error;
			break;

		default:
			goto error;
			break;
	}

	/* enable blinding */
	switch (k->type) {
		case KEY_RSA1:
		case KEY_RSA:
			if (RSA_blinding_on(k->rsa, NULL) != 1) 
				goto error;
			break;
	}

	success = 1;

error:
	free(type_name);

	if (success == 0) {
		key_free(k);
		k = NULL;
	}

	return (k);
}
Beispiel #21
0
//
// バッファからキー情報を取り出す(for SSH2)
// NOTE: 返値はアロケート領域になるので、呼び出し側で解放すること。
//
Key *key_from_blob(char *data, int blen)
{
	int keynamelen, len;
	char key[128];
	RSA *rsa = NULL;
	DSA *dsa = NULL;
	EC_KEY *ecdsa = NULL;
	EC_POINT *q = NULL;
	char *curve = NULL;
	Key *hostkey;  // hostkey
	ssh_keytype type;
	unsigned char *pk = NULL;

	hostkey = malloc(sizeof(Key));
	if (hostkey == NULL)
		goto error;

	memset(hostkey, 0, sizeof(Key));

	keynamelen = get_uint32_MSBfirst(data);
	if (keynamelen >= sizeof(key)) {
		goto error;
	}
	data += 4;
	memcpy(key, data, keynamelen);
	key[keynamelen] = 0;
	data += keynamelen;

	type = get_keytype_from_name(key);

	switch (type) {
	case KEY_RSA: // RSA key
		rsa = RSA_new();
		if (rsa == NULL) {
			goto error;
		}
		rsa->n = BN_new();
		rsa->e = BN_new();
		if (rsa->n == NULL || rsa->e == NULL) {
			goto error;
		}

		buffer_get_bignum2(&data, rsa->e);
		buffer_get_bignum2(&data, rsa->n);

		hostkey->type = type;
		hostkey->rsa = rsa;
		break;

	case KEY_DSA: // DSA key
		dsa = DSA_new();
		if (dsa == NULL) {
			goto error;
		}
		dsa->p = BN_new();
		dsa->q = BN_new();
		dsa->g = BN_new();
		dsa->pub_key = BN_new();
		if (dsa->p == NULL ||
		    dsa->q == NULL ||
		    dsa->g == NULL ||
		    dsa->pub_key == NULL) {
			goto error;
		}

		buffer_get_bignum2(&data, dsa->p);
		buffer_get_bignum2(&data, dsa->q);
		buffer_get_bignum2(&data, dsa->g);
		buffer_get_bignum2(&data, dsa->pub_key);

		hostkey->type = type;
		hostkey->dsa = dsa;
		break;

	case KEY_ECDSA256: // ECDSA
	case KEY_ECDSA384:
	case KEY_ECDSA521:
		curve = buffer_get_string(&data, NULL);
		if (type != key_curve_name_to_keytype(curve)) {
			goto error;
		}

		ecdsa = EC_KEY_new_by_curve_name(keytype_to_cipher_nid(type));
		if (ecdsa == NULL) {
			goto error;
		}

		q = EC_POINT_new(EC_KEY_get0_group(ecdsa));
		if (q == NULL) {
			goto error;
		}

		buffer_get_ecpoint(&data, EC_KEY_get0_group(ecdsa), q);
		if (key_ec_validate_public(EC_KEY_get0_group(ecdsa), q) == -1) {
			goto error;
		}

		if (EC_KEY_set_public_key(ecdsa, q) != 1) {
			goto error;
		}

		hostkey->type = type;
		hostkey->ecdsa = ecdsa;
		break;

	case KEY_ED25519:
		pk = buffer_get_string(&data, &len);
		if (pk == NULL)
			goto error;
		if (len != ED25519_PK_SZ)
			goto error;

		hostkey->type = type;
		hostkey->ed25519_pk = pk;
		pk = NULL;
		break;

	default: // unknown key
		goto error;
	}

	return (hostkey);

error:
	if (rsa != NULL)
		RSA_free(rsa);
	if (dsa != NULL)
		DSA_free(dsa);
	if (ecdsa != NULL)
		EC_KEY_free(ecdsa);

	free(hostkey);

	return NULL;
}
Beispiel #22
0
int dtls_connection_init(struct packet_stream *ps, int active, struct dtls_cert *cert) {
	struct dtls_connection *d;
	unsigned long err;

	if (!ps || !ps->sfd)
		return 0;

	__DBG("dtls_connection_init(%i)", active);

	d = &ps->sfd->dtls;

	if (d->init) {
		if ((d->active && active) || (!d->active && !active))
			goto done;
		dtls_connection_cleanup(d);
	}

	d->ssl_ctx = SSL_CTX_new(active ? DTLSv1_client_method() : DTLSv1_server_method());
	if (!d->ssl_ctx)
		goto error;

	if (SSL_CTX_use_certificate(d->ssl_ctx, cert->x509) != 1)
		goto error;
	if (SSL_CTX_use_PrivateKey(d->ssl_ctx, cert->pkey) != 1)
		goto error;

	SSL_CTX_set_verify(d->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			verify_callback);
	SSL_CTX_set_verify_depth(d->ssl_ctx, 4);
	SSL_CTX_set_cipher_list(d->ssl_ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");

	if (SSL_CTX_set_tlsext_use_srtp(d->ssl_ctx, ciphers_str))
		goto error;
	if (SSL_CTX_set_read_ahead(d->ssl_ctx, 1))
		goto error;

	d->ssl = SSL_new(d->ssl_ctx);
	if (!d->ssl)
		goto error;

	d->r_bio = BIO_new(BIO_s_mem());
	d->w_bio = BIO_new(BIO_s_mem());
	if (!d->r_bio || !d->w_bio)
		goto error;

	SSL_set_app_data(d->ssl, ps->sfd); /* XXX obj reference here? */
	SSL_set_bio(d->ssl, d->r_bio, d->w_bio);
	SSL_set_mode(d->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

	EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
	if (ecdh == NULL)
		goto error;
	SSL_set_options(d->ssl, SSL_OP_SINGLE_ECDH_USE);
	SSL_set_tmp_ecdh(d->ssl, ecdh);
	EC_KEY_free(ecdh);

	d->init = 1;
	d->active = active ? -1 : 0;

done:
	return 0;

error:
	err = ERR_peek_last_error();
	if (d->r_bio)
		BIO_free(d->r_bio);
	if (d->w_bio)
		BIO_free(d->w_bio);
	if (d->ssl)
		SSL_free(d->ssl);
	if (d->ssl_ctx)
		SSL_CTX_free(d->ssl_ctx);
	ZERO(*d);
	ilog(LOG_ERROR, "Failed to init DTLS connection: %s", ERR_reason_error_string(err));
	return -1;
}
Beispiel #23
0
static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
{
    EC_KEY *a = NULL;
    EC_KEY *b = NULL;
    BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
    char buf[12];
    unsigned char *abuf = NULL, *bbuf = NULL;
    int i, alen, blen, aout, bout, ret = 0;
    const EC_GROUP *group;

    a = EC_KEY_new_by_curve_name(nid);
    b = EC_KEY_new_by_curve_name(nid);
    if (a == NULL || b == NULL)
        goto err;

    group = EC_KEY_get0_group(a);

    if ((x_a = BN_new()) == NULL)
        goto err;
    if ((y_a = BN_new()) == NULL)
        goto err;
    if ((x_b = BN_new()) == NULL)
        goto err;
    if ((y_b = BN_new()) == NULL)
        goto err;

    BIO_puts(out, "Testing key generation with ");
    BIO_puts(out, text);
# ifdef NOISY
    BIO_puts(out, "\n");
# else
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(a))
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
        NID_X9_62_prime_field) {
        if (!EC_POINT_get_affine_coordinates_GFp
            (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(a),
                                                  x_a, y_a, ctx))
            goto err;
    }
# endif
# ifdef NOISY
    BIO_puts(out, "  pri 1=");
    BN_print(out, a->priv_key);
    BIO_puts(out, "\n  pub 1=");
    BN_print(out, x_a);
    BIO_puts(out, ",");
    BN_print(out, y_a);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, " .");
    (void)BIO_flush(out);
# endif

    if (!EC_KEY_generate_key(b))
        goto err;

    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
        NID_X9_62_prime_field) {
        if (!EC_POINT_get_affine_coordinates_GFp
            (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx))
            goto err;
    }
# ifndef OPENSSL_NO_EC2M
    else {
        if (!EC_POINT_get_affine_coordinates_GF2m(group,
                                                  EC_KEY_get0_public_key(b),
                                                  x_b, y_b, ctx))
            goto err;
    }
# endif

# ifdef NOISY
    BIO_puts(out, "  pri 2=");
    BN_print(out, b->priv_key);
    BIO_puts(out, "\n  pub 2=");
    BN_print(out, x_b);
    BIO_puts(out, ",");
    BN_print(out, y_b);
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    alen = KDF1_SHA1_len;
    abuf = (unsigned char *)OPENSSL_malloc(alen);
    aout =
        ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key1 =");
    for (i = 0; i < aout; i++) {
        sprintf(buf, "%02X", abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    blen = KDF1_SHA1_len;
    bbuf = (unsigned char *)OPENSSL_malloc(blen);
    bout =
        ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1);

# ifdef NOISY
    BIO_puts(out, "  key2 =");
    for (i = 0; i < bout; i++) {
        sprintf(buf, "%02X", bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
# else
    BIO_printf(out, ".");
    (void)BIO_flush(out);
# endif

    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
# ifndef NOISY
        BIO_printf(out, " failed\n\n");
        BIO_printf(out, "key a:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(a));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_a);
        BIO_printf(out, ",");
        BN_print(out, y_a);
        BIO_printf(out, "\nkey b:\n");
        BIO_printf(out, "private key: ");
        BN_print(out, EC_KEY_get0_private_key(b));
        BIO_printf(out, "\n");
        BIO_printf(out, "public key (x,y): ");
        BN_print(out, x_b);
        BIO_printf(out, ",");
        BN_print(out, y_b);
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key a: ");
        for (i = 0; i < bout; i++) {
            sprintf(buf, "%02X", bbuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
        BIO_printf(out, "generated key b: ");
        for (i = 0; i < aout; i++) {
            sprintf(buf, "%02X", abuf[i]);
            BIO_puts(out, buf);
        }
        BIO_printf(out, "\n");
# endif
        fprintf(stderr, "Error in ECDH routines\n");
        ret = 0;
    } else {
# ifndef NOISY
        BIO_printf(out, " ok\n");
# endif
        ret = 1;
    }
 err:
    ERR_print_errors_fp(stderr);

    if (abuf != NULL)
        OPENSSL_free(abuf);
    if (bbuf != NULL)
        OPENSSL_free(bbuf);
    if (x_a)
        BN_free(x_a);
    if (y_a)
        BN_free(y_a);
    if (x_b)
        BN_free(x_b);
    if (y_b)
        BN_free(y_b);
    if (b)
        EC_KEY_free(b);
    if (a)
        EC_KEY_free(a);
    return (ret);
}
Beispiel #24
0
CECKey::CECKey() {
    pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
    assert(pkey != NULL);
}
Beispiel #25
0
static int
input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
{
	struct kex *kex = ssh->kex;
	EC_POINT *client_public;
	EC_KEY *server_key = NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	BIGNUM *shared_secret = NULL;
	struct sshkey *server_host_private, *server_host_public;
	u_char *server_host_key_blob = NULL, *signature = NULL;
	u_char *kbuf = NULL;
	u_char hash[SSH_DIGEST_MAX_LENGTH];
	size_t slen, sbloblen;
	size_t klen = 0, hashlen;
	int r;

	if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (EC_KEY_generate_key(server_key) != 1) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}
	group = EC_KEY_get0_group(server_key);

#ifdef DEBUG_KEXECDH
	fputs("server private key:\n", stderr);
	sshkey_dump_ec_key(server_key);
#endif

	if (kex->load_host_public_key == NULL ||
	    kex->load_host_private_key == NULL) {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	server_host_public = kex->load_host_public_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	server_host_private = kex->load_host_private_key(kex->hostkey_type,
	    kex->hostkey_nid, ssh);
	if (server_host_public == NULL) {
		r = SSH_ERR_NO_HOSTKEY_LOADED;
		goto out;
	}
	if ((client_public = EC_POINT_new(group)) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 ||
	    (r = sshpkt_get_end(ssh)) != 0)
		goto out;

#ifdef DEBUG_KEXECDH
	fputs("client public key:\n", stderr);
	sshkey_dump_ec_point(group, client_public);
#endif
	if (sshkey_ec_validate_public(group, client_public) != 0) {
		sshpkt_disconnect(ssh, "invalid client public key");
		r = SSH_ERR_MESSAGE_INCOMPLETE;
		goto out;
	}

	/* Calculate shared_secret */
	klen = (EC_GROUP_get_degree(group) + 7) / 8;
	if ((kbuf = malloc(klen)) == NULL ||
	    (shared_secret = BN_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if (ECDH_compute_key(kbuf, klen, client_public,
	    server_key, NULL) != (int)klen ||
	    BN_bin2bn(kbuf, klen, shared_secret) == NULL) {
		r = SSH_ERR_LIBCRYPTO_ERROR;
		goto out;
	}

#ifdef DEBUG_KEXECDH
	dump_digest("shared secret", kbuf, klen);
#endif
	/* calc H */
	if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob,
	    &sbloblen)) != 0)
		goto out;
	hashlen = sizeof(hash);
	if ((r = kex_ecdh_hash(
	    kex->hash_alg,
	    group,
	    kex->client_version_string,
	    kex->server_version_string,
	    sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
	    sshbuf_ptr(kex->my), sshbuf_len(kex->my),
	    server_host_key_blob, sbloblen,
	    client_public,
	    EC_KEY_get0_public_key(server_key),
	    shared_secret,
	    hash, &hashlen)) != 0)
		goto out;

	/* save session id := H */
	if (kex->session_id == NULL) {
		kex->session_id_len = hashlen;
		kex->session_id = malloc(kex->session_id_len);
		if (kex->session_id == NULL) {
			r = SSH_ERR_ALLOC_FAIL;
			goto out;
		}
		memcpy(kex->session_id, hash, kex->session_id_len);
	}

	/* sign H */
	if ((r = kex->sign(server_host_private, server_host_public, &signature,
	     &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0)
		goto out;

	/* destroy_sensitive_data(); */

	public_key = EC_KEY_get0_public_key(server_key);
	/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
	if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
	    (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
	    (r = sshpkt_put_ec(ssh, public_key, group)) != 0 ||
	    (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
	    (r = sshpkt_send(ssh)) != 0)
		goto out;

	if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
		r = kex_send_newkeys(ssh);
 out:
	explicit_bzero(hash, sizeof(hash));
	if (kex->ec_client_key) {
		EC_KEY_free(kex->ec_client_key);
		kex->ec_client_key = NULL;
	}
	if (server_key)
		EC_KEY_free(server_key);
	if (kbuf) {
		explicit_bzero(kbuf, klen);
		free(kbuf);
	}
	if (shared_secret)
		BN_clear_free(shared_secret);
	free(server_host_key_blob);
	free(signature);
	return r;
}
Beispiel #26
0
static void setup_ecc_key(SSL_CTX *ssl_ctx)
{
    EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    SSL_CTX_set_tmp_ecdh(ssl_ctx, key);
    EC_KEY_free(key);
}
/* 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 #28
0
eventer_ssl_ctx_t *
eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
                    const char *layer,
                    const char *certificate, const char *key,
                    const char *ca, const char *ciphers) {
  char ssl_ctx_key[SSL_CTX_KEYLEN];
  eventer_ssl_ctx_t *ctx;
  const char *layer_str;
  char *ctx_layer, *opts;
  char *opts_fallback = DEFAULT_OPTS_STRING;
  time_t now;
  ctx = calloc(1, sizeof(*ctx));
  if(!ctx) return NULL;

  layer_str = layer ? layer : DEFAULT_LAYER_STRING;
  ctx_layer = alloca(strlen(layer_str)+1);
  memcpy(ctx_layer, layer_str, strlen(layer_str)+1);
  opts = strchr(ctx_layer,':');
  if(opts) *opts++ = '\0';
  else {
    opts = alloca(strlen(opts_fallback)+1);
    memcpy(opts, opts_fallback, strlen(opts_fallback)+1);
  }

  now = time(NULL);
  ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key),
                    type, layer, certificate, key, ca, ciphers);
  ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key);
  if(ctx->ssl_ctx_cn) {
    if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry ||
       (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry &&
           (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) ||
            validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) ||
            validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || 
            (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */
      ssl_ctx_cache_remove(ssl_ctx_key);
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = NULL;
    }
  }

  if(!ctx->ssl_ctx_cn) {
    char *part = NULL, *brkt = NULL;
    long ctx_options = 0;
    ssl_ctx_cache_node *existing_ctx_cn;
    ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn));
    ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key);
    ctx->ssl_ctx_cn->refcnt = 1;
    ctx->ssl_ctx_cn->creation_time = now;
    ctx->ssl_ctx_cn->last_stat_time = now;
    populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate);
    populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key);
    populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca);
    ctx->ssl_ctx = NULL;
    if(0)
      ;
#if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv3_server_method() : SSLv3_client_method());
#endif
#if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv2_server_method() : SSLv2_client_method());
#endif
#if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_server_method() : TLSv1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_1_server_method() : TLSv1_1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_2_server_method() : TLSv1_2_client_method());
#endif
    if(ctx->ssl_ctx == NULL)
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv23_server_method() : SSLv23_client_method());
    if(!ctx->ssl_ctx) goto bail;

    for(part = strtok_r(opts, ",", &brkt);
        part;
        part = strtok_r(NULL, ",", &brkt)) {
      char *optname = part;
      int neg = 0;
      if(*optname == '!') neg = 1, optname++;

#define SETBITOPT(name, neg, opt) \
  if(!strcasecmp(optname, name)) { \
    if(neg) ctx_options &= ~(opt); \
    else    ctx_options |= (opt); \
  }

      SETBITOPT("all", neg, SSL_OP_ALL)
#ifdef SSL_TXT_SSLV2
      else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2)
#endif
#ifdef SSL_TXT_SSLV3
      else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3)
#endif
#ifdef SSL_TXT_TLSV1
      else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1)
#endif
#ifdef SSL_TXT_TLSV1_1
      else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1)
#endif
#ifdef SSL_TXT_TLSV1_2
      else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2)
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
      else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE)
#endif
      else {
        mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname);
      }
    }

    if (type == SSL_SERVER)
      SSL_CTX_set_session_id_context(ctx->ssl_ctx,
              (unsigned char *)EVENTER_SSL_DATANAME,
              sizeof(EVENTER_SSL_DATANAME)-1);
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
#endif
#ifdef SSL_OP_NO_COMPRESSION
    ctx_options |= SSL_OP_NO_COMPRESSION;
#endif
#ifdef SSL_OP_NO_TICKET
    ctx_options |= SSL_OP_NO_TICKET;
#endif
#ifdef SSL_OP_SINGLE_DH_USE
    ctx_options |= SSL_OP_SINGLE_DH_USE;
#endif
#ifdef SSL_OP_SINGLE_ECDH_USE
    ctx_options |= SSL_OP_SINGLE_ECDH_USE;
#endif
    SSL_CTX_set_options(ctx->ssl_ctx, ctx_options);
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
    if(certificate &&
       SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
      goto bail;
    if(key &&
       SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
                                      SSL_FILETYPE_PEM) != 1)
      goto bail;
    if(ca) {
      STACK_OF(X509_NAME) *cert_stack;
      if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
         (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
        goto bail;
      SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
    }
    SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
    SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb);
#ifndef OPENSSL_NO_EC
#if defined(SSL_CTX_set_ecdh_auto)
    SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1);
#elif defined(NID_X9_62_prime256v1)
    EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key);
    EC_KEY_free(ec_key);
#endif
#endif
    existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn);
    if(existing_ctx_cn != ctx->ssl_ctx_cn) {
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = existing_ctx_cn;
    }
  }
Beispiel #29
0
rb_ssl_ctx *
rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, const char *dhfile,
		    const char *ssl_cipher_list, const char *named_curve, rb_tls_ver_t tls_min_ver)
{
        const char *libratbox_data = "libratbox tls session";
	const char *ciphers = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
	unsigned long err;
	rb_ssl_ctx *sctx; 
	long tls_opts;
	sctx = rb_malloc(sizeof(rb_ssl_ctx));
	sctx->refcount = 1;
	sctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
	if(sctx->ssl_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		rb_free(sctx);
		return NULL;
	}

	tls_opts = SSL_CTX_get_options(sctx->ssl_ctx);
	/* Disable SSLv2, make the client use our settings */
	tls_opts |= SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE;
	switch(tls_min_ver)
	{
		case RB_TLS_VER_SSL3: /* we default to SSLv3..sadly */
			break;
			
		case RB_TLS_VER_TLS1:
#ifdef SSL_OP_NO_SSLv3
			tls_opts |= SSL_OP_NO_SSLv3;
#endif
			break;
		case RB_TLS_VER_TLS1_1:
#ifdef SSL_OP_NO_TLSv1
			tls_opts |= SSL_OP_NO_TLSv1;
#endif
			break;

		case RB_TLS_VER_TLS1_2:
#ifdef SSL_OP_NO_TLSv1
			tls_opts |= SSL_OP_NO_TLSv1;
#endif
#ifdef SSL_OP_NO_TLSv1_1
			tls_opts |= SSL_OP_NO_TLSv1_1;
#endif
			break;
		case RB_TLS_VER_LAST:
			break;
	}

#ifdef SSL_OP_SINGLE_DH_USE
	tls_opts |= SSL_OP_SINGLE_DH_USE;
#endif

#ifdef SSL_OP_SINGLE_ECDH_USE
	tls_opts |= SSL_OP_SINGLE_ECDH_USE;
#endif

#ifdef SSL_OP_NO_TICKET
	tls_opts |= SSL_OP_NO_TICKET;
#endif

	SSL_CTX_set_options(sctx->ssl_ctx, tls_opts);


	if(ssl_cipher_list != NULL)
		ciphers = ssl_cipher_list;

	if(!SSL_CTX_set_cipher_list(sctx->ssl_ctx, ciphers))
	{
		rb_lib_log("rb_setup_ssl_server: Error setting ssl_cipher_list=\"%s\": %s",
			   ciphers, ERR_error_string(ERR_get_error(), NULL));
		goto cleanup;;
	}


	if(cert == NULL)
	{
		rb_lib_log("rb_setup_ssl_server: No certificate file");
		goto cleanup;
	}
	if(!SSL_CTX_use_certificate_chain_file(sctx->ssl_ctx, cert))
	{
		err = ERR_get_error();
		rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert,
			   ERR_error_string(err, NULL));
		goto cleanup;
	}
	
	if(cacert != NULL)
	{
		if (!SSL_CTX_load_verify_locations(sctx->ssl_ctx, cacert, NULL)) 
		{
			err = ERR_get_error();
			rb_lib_log("rb_setup_ssl_server: Error loading CA file [%s]: %s", cacert, ERR_error_string(err, NULL));
			goto cleanup;
		}
	}

	if(keyfile == NULL)
	{
		rb_lib_log("rb_setup_ssl_server: No key file");
		goto cleanup;
	}


	if(!SSL_CTX_use_PrivateKey_file(sctx->ssl_ctx, keyfile, SSL_FILETYPE_PEM))
	{
		err = ERR_get_error();
		rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
			   ERR_error_string(err, NULL));
		goto cleanup;;
	}


	if(dhfile != NULL)
	{
		/* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
		BIO *bio = BIO_new_file(dhfile, "r");
		if(bio != NULL)
		{
			DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
			if(dh == NULL)
			{
				err = ERR_get_error();
				rb_lib_log
					("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
					 dhfile, ERR_error_string(err, NULL));
				BIO_free(bio);
				goto cleanup;
			}
			BIO_free(bio);
			SSL_CTX_set_tmp_dh(sctx->ssl_ctx, dh);
			DH_free(dh);
		}
		else
		{
			err = ERR_get_error();
			rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
				   dhfile, ERR_error_string(err, NULL));
			goto cleanup;	  
		}
	}

#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
	
	if(named_curve != NULL)
	{
		int nid;
		EC_KEY *ecdh;
		
		nid = OBJ_sn2nid(named_curve);
		if(nid == 0)
		{
			err = ERR_get_error();
			rb_lib_log("rb_setup_ssl_server: Unknown curve named [%s]: %s", named_curve, ERR_error_string(err, NULL));
			goto cleanup;
		}
		
		ecdh = EC_KEY_new_by_curve_name(nid);
		if(ecdh == NULL)
		{
			err = ERR_get_error();
			rb_lib_log("rb_setup_ssl_server: Curve creation failed for [%s]: %s", named_curve, ERR_error_string(err, NULL));
			goto cleanup;
		}
		SSL_CTX_set_options(sctx->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
		SSL_CTX_set_tmp_ecdh(sctx->ssl_ctx, ecdh);
		EC_KEY_free(ecdh);
	}
#endif
#endif
	SSL_CTX_set_verify(sctx->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
	SSL_CTX_set_session_id_context(sctx->ssl_ctx, (const unsigned char *)libratbox_data, strlen(libratbox_data));
	return sctx;

cleanup:
	SSL_CTX_free(sctx->ssl_ctx);
	rb_free(sctx);
	return NULL;
		
	
}
Beispiel #30
0
EC_KEY *
vg_exec_context_new_key(void)
{
	return EC_KEY_new_by_curve_name(NID_secp256k1);
}