Ejemplo n.º 1
0
int ecdh_compute_key_point(void *out, size_t outlen, const EC_POINT *pub_key,
   EC_KEY *ecdh,
   void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen))
   {
   BN_CTX *ctx = NULL;
   EC_POINT *tmp=NULL;
   const BIGNUM *priv_key;
   const EC_GROUP* group;
   int ret= -1;
   size_t buflen;
   unsigned char *buf=NULL;

   check((outlen < INT_MAX), "out of memory"); /* sort of, anyway */

   if ((ctx = BN_CTX_new()) == NULL) goto err;
   BN_CTX_start(ctx);

   priv_key = EC_KEY_get0_private_key(ecdh);
   check(priv_key, "No pivate key");

   group = EC_KEY_get0_group(ecdh);
   tmp = EC_POINT_new(group);
   check(tmp, "Out of memory");

   check((EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)),
           "Arithmetic error");

    buflen = EC_POINT_point2oct(group, tmp, EC_KEY_get_conv_form(ecdh), NULL,
            0, ctx);
    check((buflen != 0), "Failed to convert point to hex");

    buf = OPENSSL_malloc(buflen);
    check(buf, "Out of memory");

    check((buflen == EC_POINT_point2oct(group, tmp, EC_KEY_get_conv_form(ecdh),
                    buf, buflen, ctx)), "Failed to convert point to hex");

    if (KDF != 0)
    {
        check((KDF(buf, buflen, out, &outlen) != NULL),
                "Key derivation function failed");
        ret = outlen;
    }
    else
    {
        /* no KDF, just copy as much as we can */
        if (outlen > buflen)
            outlen = buflen;
        memcpy(out, buf, outlen);
        ret = outlen;
    }

err:
    if (tmp) EC_POINT_free(tmp);
    if (ctx) BN_CTX_end(ctx);
    if (ctx) BN_CTX_free(ctx);
    if (buf) OPENSSL_free(buf);
    return(ret);
}
Ejemplo n.º 2
0
// Extract the private and public keys from the PEM file, using the supplied
// password to decrypt the file if encrypted. priv_key and pub_key must point to
// an array o at least 65 and 131 character respectively.
int load_pem_key(char *pemstr, size_t pemstr_len, char *password,
                 char *out_priv_key, char *out_pub_key) {

  BIO *in = NULL;

  BN_CTX *ctx = NULL;
  const EC_GROUP *group;
  EC_KEY *eckey = NULL;
  const EC_POINT *pub_key_point = NULL;
  const BIGNUM *priv_key = NULL, *pub_key = NULL;

  char *priv_key_hex = NULL;
  char *pub_key_hex = NULL;

  in = BIO_new_mem_buf(pemstr, (int)pemstr_len);

  // Read key from stream, decrypting with password if not NULL
  if (password != NULL && strcmp("", password) != 0) {
    // Initialize ciphers
    ERR_load_crypto_strings ();
    OpenSSL_add_all_algorithms ();

    eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, password);
    if (eckey == NULL) {
      return -1; // Failed to decrypt or decode private key
    }
  } else {
    if ((eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL)) == NULL) {
      return -1; // Failed to decode private key
    }
  }
  BIO_free(in);

  // Deconstruct key into big numbers
  if ((ctx = BN_CTX_new()) == NULL) {
    return -2; // Failed to create new big number context
  }
  if ((group = EC_KEY_get0_group(eckey)) == NULL) {
    return -3; // Failed to load group
  }
  if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) {
    return -4; // Failed to load private key
  }
  if ((pub_key_point = EC_KEY_get0_public_key(eckey)) == NULL) {
    return -5; // Failed to load public key point
  }
  pub_key = EC_POINT_point2bn(group, pub_key_point, EC_KEY_get_conv_form(eckey), NULL, ctx);
  if (pub_key == NULL) {
    return -6; // Failed to construct public key from point
  }

  priv_key_hex = BN_bn2hex(priv_key);
  pub_key_hex = BN_bn2hex(pub_key);
  strncpy_s(out_priv_key, 64 + 1, priv_key_hex, 64 + 1);
  strncpy_s(out_pub_key, 130 + 1, pub_key_hex, 130 + 1);
  OPENSSL_free(priv_key_hex);
  OPENSSL_free(pub_key_hex);
  return 0;
}
Ejemplo n.º 3
0
BUF_MEM *
EC_POINT_point2buf(const EC_KEY * ecdh, BN_CTX * bn_ctx, const EC_POINT * ecp)
{
    size_t len;
    BUF_MEM * out;

    len = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), ecp,
            EC_KEY_get_conv_form(ecdh), NULL, 0, bn_ctx);
    if (len == 0)
        return NULL;

    out = BUF_MEM_create(len);
    if (!out)
        return NULL;

    out->length = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), ecp,
            EC_KEY_get_conv_form(ecdh), (unsigned char *) out->data, out->max,
            bn_ctx);

    return out;
}
Ejemplo n.º 4
0
static int openssl_ec_key_parse(lua_State*L)
{
  EC_KEY* ec = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key");
  int basic = luaL_opt(L,lua_toboolean, 2, 0);
  const EC_POINT* point = EC_KEY_get0_public_key(ec);
  const EC_GROUP* group = EC_KEY_get0_group(ec);
  const BIGNUM *priv = EC_KEY_get0_private_key(ec);
  lua_newtable(L);
  if (basic)
  {
    BIGNUM* x = BN_new();
    BIGNUM* y = BN_new();

    AUXILIAR_SET(L, -1, "enc_flag", EC_KEY_get_enc_flags(ec), integer);
    AUXILIAR_SET(L, -1, "conv_form", EC_KEY_get_conv_form(ec), integer);
    AUXILIAR_SET(L, -1, "curve_name", EC_GROUP_get_curve_name(group), integer);

    AUXILIAR_SETOBJECT(L, BN_dup(priv), "openssl.bn", -1, "d");

    if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, NULL) == 1)
    {
      AUXILIAR_SETOBJECT(L, x, "openssl.bn", -1, "x");
      AUXILIAR_SETOBJECT(L, y, "openssl.bn", -1, "y");
    };
  }
  else
  {
    AUXILIAR_SET(L, -1, "enc_flag", EC_KEY_get_enc_flags(ec), integer);
    AUXILIAR_SET(L, -1, "conv_form", EC_KEY_get_conv_form(ec), integer);

    point = EC_POINT_dup(point, group);
    AUXILIAR_SETOBJECT(L, point, "openssl.ec_point", -1, "pub_key");
    group = EC_GROUP_dup(group);
    AUXILIAR_SETOBJECT(L, group, "openssl.ec_group", -1, "group");

    OPENSSL_PKEY_GET_BN(priv, priv_key);
  }
  return 1;
};
Ejemplo n.º 5
0
QString pki_key::ecPubKey()
{
	QString pub;
	if (key->type == EVP_PKEY_EC) {
		EC_KEY *ec = key->pkey.ec;
		BIGNUM  *pub_key = EC_POINT_point2bn(EC_KEY_get0_group(ec),
				EC_KEY_get0_public_key(ec),
				EC_KEY_get_conv_form(ec), NULL, NULL);
		if (pub_key) {
			pub = BN2QString(pub_key);
			BN_free(pub_key);
		}
	}
	return pub;
}
Ejemplo n.º 6
0
/* For an EC key set TLS ID and required compression based on parameters. */
static int
tls1_set_ec_id(uint16_t *curve_id, uint8_t *comp_id, EC_KEY *ec)
{
	const EC_GROUP *grp;
	const EC_METHOD *meth;
	int is_prime = 0;
	int nid, id;

	if (ec == NULL)
		return (0);

	/* Determine if it is a prime field. */
	if ((grp = EC_KEY_get0_group(ec)) == NULL)
		return (0);
	if ((meth = EC_GROUP_method_of(grp)) == NULL)
		return (0);
	if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
		is_prime = 1;

	/* Determine curve ID. */
	nid = EC_GROUP_get_curve_name(grp);
	id = tls1_ec_nid2curve_id(nid);

	/* If we have an ID set it, otherwise set arbitrary explicit curve. */
	if (id != 0)
		*curve_id = id;
	else
		*curve_id = is_prime ? 0xff01 : 0xff02;

	/* Specify the compression identifier. */
	if (comp_id != NULL) {
		if (EC_KEY_get0_public_key(ec) == NULL)
			return (0);

		if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
			*comp_id = is_prime ?
			    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime :
			    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
		} else {
			*comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
		}
	}
	return (1);
}
Ejemplo n.º 7
0
int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
                               const CRYPTO_BUFFER *leaf) {
  SSL *const ssl = hs->ssl;
  assert(ssl3_protocol_version(ssl) < TLS1_3_VERSION);

  /* Check the certificate's type matches the cipher. */
  if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
    return 0;
  }

  /* Check key usages for all key types but RSA. This is needed to distinguish
   * ECDH certificates, which we do not support, from ECDSA certificates. In
   * principle, we should check RSA key usages based on cipher, but this breaks
   * buggy antivirus deployments. Other key types are always used for signing.
   *
   * TODO(davidben): Get more recent data on RSA key usages. */
  if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
    CBS leaf_cbs;
    CBS_init(&leaf_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf));
    if (!ssl_cert_check_digital_signature_key_usage(&leaf_cbs)) {
      return 0;
    }
  }

  if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
    /* Check the key's group and point format are acceptable. */
    EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
    uint16_t group_id;
    if (!ssl_nid_to_group_id(
            &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) ||
        !tls1_check_group_id(ssl, group_id) ||
        EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
      return 0;
    }
  }

  return 1;
}
Ejemplo n.º 8
0
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
	{
	unsigned char *buffer=NULL;
	const char *ecstr;
	size_t	buf_len=0, i;
	int     ret=0, reason=ERR_R_BIO_LIB;
	BIGNUM  *pub_key=NULL, *order=NULL;
	BN_CTX  *ctx=NULL;
	const EC_GROUP *group;
	const EC_POINT *public_key;
	const BIGNUM *priv_key;
 
	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
		{
		reason = ERR_R_PASSED_NULL_PARAMETER;
		goto err;
		}

	ctx = BN_CTX_new();
	if (ctx == NULL)
		{
		reason = ERR_R_MALLOC_FAILURE;
		goto err;
		}

	if (ktype > 0)
		{
		public_key = EC_KEY_get0_public_key(x);
		if (public_key != NULL)
			{
			if ((pub_key = EC_POINT_point2bn(group, public_key,
				EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
				{
				reason = ERR_R_EC_LIB;
				goto err;
				}
			buf_len = (size_t)BN_num_bytes(pub_key);
			}
		}

	if (ktype == 2)
		{
		priv_key = EC_KEY_get0_private_key(x);
		if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
			buf_len = i;
		}
	else
		priv_key = NULL;

	if (ktype > 0)
		{
		buf_len += 10;
		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
			{
			reason = ERR_R_MALLOC_FAILURE;
			goto err;
			}
		}
	if (ktype == 2)
		ecstr = "Private-Key";
	else if (ktype == 1)
		ecstr = "Public-Key";
	else
		ecstr = "ECDSA-Parameters";

	if (!BIO_indent(bp, off, 128))
		goto err;
	if ((order = BN_new()) == NULL)
		goto err;
	if (!EC_GROUP_get_order(group, order, NULL))
		goto err;
	if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
		BN_num_bits(order)) <= 0) goto err;
  
	if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, 
		buffer, off))
		goto err;
	if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
		buffer, off))
		goto err;
	if (!ECPKParameters_print(bp, group, off))
		goto err;
	ret=1;
err:
	if (!ret)
 		ECerr(EC_F_DO_EC_KEY_PRINT, reason);
	if (pub_key) 
		BN_free(pub_key);
	if (order)
		BN_free(order);
	if (ctx)
		BN_CTX_free(ctx);
	if (buffer != NULL)
		OPENSSL_free(buffer);
	return(ret);
	}
Ejemplo n.º 9
0
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
  uint8_t *buffer = NULL;
  const char *ecstr;
  size_t buf_len = 0, i;
  int ret = 0, reason = ERR_R_BIO_LIB;
  BN_CTX *ctx = NULL;
  const EC_GROUP *group;
  const EC_POINT *public_key;
  const BIGNUM *priv_key;
  uint8_t *pub_key_bytes = NULL;
  size_t pub_key_bytes_len = 0;

  if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
    reason = ERR_R_PASSED_NULL_PARAMETER;
    goto err;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    reason = ERR_R_MALLOC_FAILURE;
    goto err;
  }

  if (ktype > 0) {
    public_key = EC_KEY_get0_public_key(x);
    if (public_key != NULL) {
      pub_key_bytes_len = EC_POINT_point2oct(
          group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
      if (pub_key_bytes_len == 0) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
      if (pub_key_bytes == NULL) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      pub_key_bytes_len =
          EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
                             pub_key_bytes, pub_key_bytes_len, ctx);
      if (pub_key_bytes_len == 0) {
        reason = ERR_R_MALLOC_FAILURE;
        goto err;
      }
      buf_len = pub_key_bytes_len;
    }
  }

  if (ktype == 2) {
    priv_key = EC_KEY_get0_private_key(x);
    if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
      buf_len = i;
    }
  } else {
    priv_key = NULL;
  }

  if (ktype > 0) {
    buf_len += 10;
    if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
      reason = ERR_R_MALLOC_FAILURE;
      goto err;
    }
  }
  if (ktype == 2) {
    ecstr = "Private-Key";
  } else if (ktype == 1) {
    ecstr = "Public-Key";
  } else {
    ecstr = "ECDSA-Parameters";
  }

  if (!BIO_indent(bp, off, 128)) {
    goto err;
  }
  const BIGNUM *order = EC_GROUP_get0_order(group);
  if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
    goto err;
  }

  if ((priv_key != NULL) &&
      !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
    goto err;
  }
  if (pub_key_bytes != NULL) {
    BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
  }
  /* TODO(fork): implement */
  /*
  if (!ECPKParameters_print(bp, group, off))
    goto err; */
  ret = 1;

err:
  if (!ret) {
    OPENSSL_PUT_ERROR(EVP, reason);
  }
  OPENSSL_free(pub_key_bytes);
  BN_CTX_free(ctx);
  OPENSSL_free(buffer);
  return ret;
}
Ejemplo n.º 10
0
static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
{
    const char *ecstr;
    unsigned char *priv = NULL, *pub = NULL;
    size_t privlen = 0, publen = 0;
    int ret = 0;
    const EC_GROUP *group;

    if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
        if (publen == 0)
            goto err;
    }

    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
        privlen = EC_KEY_priv2buf(x, &priv);
        if (privlen == 0)
            goto err;
    }

    if (ktype == EC_KEY_PRINT_PRIVATE)
        ecstr = "Private-Key";
    else if (ktype == EC_KEY_PRINT_PUBLIC)
        ecstr = "Public-Key";
    else
        ecstr = "ECDSA-Parameters";

    if (!BIO_indent(bp, off, 128))
        goto err;
    if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
                   EC_GROUP_order_bits(group)) <= 0)
        goto err;

    if (privlen != 0) {
        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
            goto err;
        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
            goto err;
    }

    if (publen != 0) {
        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
            goto err;
        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
            goto err;
    }

    if (!ECPKParameters_print(bp, group, off))
        goto err;
    ret = 1;
 err:
    if (!ret)
        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
    OPENSSL_clear_free(priv, privlen);
    OPENSSL_free(pub);
    return ret;
}