Пример #1
0
static int openssl_ec_group_asn1_flag(lua_State*L)
{
  EC_GROUP* group = CHECK_OBJECT(1, EC_GROUP, "openssl.ec_group");
  int asn1_flag = 0;
  if (lua_isnone(L, 2))
  {
    asn1_flag = EC_GROUP_get_asn1_flag(group);
    if (asn1_flag == 0)
      lua_pushstring(L, "explicit");
    else if (asn1_flag == OPENSSL_EC_NAMED_CURVE)
      lua_pushstring(L, "named_curve");
    else
      lua_pushnil(L);
    lua_pushinteger(L, asn1_flag);
    return 2;
  } else if (lua_isstring(L, 2))
  {           /* OPENSSL_EC_NAMED_CURVE,   0 */
    const char* const options[] = {"named_curve", "explicit", NULL};
    asn1_flag = luaL_checkoption(L, 2, NULL, options);
    EC_GROUP_set_asn1_flag(group, asn1_flag);
  } else if (lua_isnumber(L, 2))
  {
    asn1_flag = luaL_checkint(L, 2);
    EC_GROUP_set_asn1_flag(group, asn1_flag);
  } else
    luaL_argerror(L, 2, "not accept type of asn1 flag");

  return 0;
}
Пример #2
0
static int
ecdsa_private_key_import(hx509_context context,
                         const AlgorithmIdentifier *keyai,
                         const void *data,
                         size_t len,
                         hx509_key_format_t format,
                         hx509_private_key private_key)
{
    const unsigned char *p = data;
    EC_KEY **pkey = NULL;
    EC_KEY *key;

    if (keyai->parameters) {
        EC_GROUP *group;
        int groupnid;
        int ret;

        ret = parse_ECParameters(context, keyai->parameters, &groupnid);
        if (ret)
            return ret;

        key = EC_KEY_new();
        if (key == NULL)
            return ENOMEM;

        group = EC_GROUP_new_by_curve_name(groupnid);
        if (group == NULL) {
            EC_KEY_free(key);
            return ENOMEM;
        }
        EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
        if (EC_KEY_set_group(key, group) == 0) {
            EC_KEY_free(key);
            EC_GROUP_free(group);
            return ENOMEM;
        }
        EC_GROUP_free(group);
        pkey = &key;
    }

    switch (format) {
    case HX509_KEY_FORMAT_DER:

        private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
        if (private_key->private_key.ecdsa == NULL) {
            hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
                                   "Failed to parse EC private key");
            return HX509_PARSING_KEY_FAILED;
        }
        private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
        break;

    default:
        return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
    }

    return 0;
}
static int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params) {
    Unique_EC_GROUP group;
    switch (ec_params->field_size) {
    case 224:
        group.reset(EC_GROUP_new_by_curve_name(NID_secp224r1));
        break;
    case 256:
        group.reset(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
        break;
    case 384:
        group.reset(EC_GROUP_new_by_curve_name(NID_secp384r1));
        break;
    case 521:
        group.reset(EC_GROUP_new_by_curve_name(NID_secp521r1));
        break;
    default:
        break;
    }

    if (group.get() == NULL) {
        logOpenSSLError("generate_ec_keypair");
        return -1;
    }

#if !defined(OPENSSL_IS_BORINGSSL)
    EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
    EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
#endif

    /* initialize EC key */
    Unique_EC_KEY eckey(EC_KEY_new());
    if (eckey.get() == NULL) {
        logOpenSSLError("generate_ec_keypair");
        return -1;
    }

    if (EC_KEY_set_group(eckey.get(), group.get()) != 1) {
        logOpenSSLError("generate_ec_keypair");
        return -1;
    }

    if (EC_KEY_generate_key(eckey.get()) != 1 || EC_KEY_check_key(eckey.get()) < 0) {
        logOpenSSLError("generate_ec_keypair");
        return -1;
    }

    if (EVP_PKEY_assign_EC_KEY(pkey, eckey.get()) == 0) {
        logOpenSSLError("generate_ec_keypair");
        return -1;
    }
    release_because_ownership_transferred(eckey);

    return 0;
}
Пример #4
0
static int
param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
{
	ASN1_OBJECT *obj = NULL;
	int nid;
	GOST_KEY *ec;
	EC_GROUP *group;
	int ret;

	/* New format */
	if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder)
		return decode_gost01_algor_params(pkey, pder, derlen);

	/* Compatibility */
	if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	nid = OBJ_obj2nid(obj);
	ASN1_OBJECT_free(obj);

	ec = GOST_KEY_new();
	if (ec == NULL) {
		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
		return 0;
	}
	group = EC_GROUP_new_by_curve_name(nid);
	if (group == NULL) {
		GOSTerr(GOST_F_PARAM_DECODE_GOST01,
		    EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
		GOST_KEY_free(ec);
		return 0;
	}

	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
	if (GOST_KEY_set_group(ec, group) == 0) {
		GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_EC_LIB);
		EC_GROUP_free(group);
		GOST_KEY_free(ec);
		return 0;
	}
	EC_GROUP_free(group);
	if (GOST_KEY_set_digest(ec,
	    NID_id_GostR3411_94_CryptoProParamSet) == 0) {
		GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE);
		GOST_KEY_free(ec);
		return 0;
	}
	ret = EVP_PKEY_assign_GOST(pkey, ec);
	if (ret == 0)
		GOST_KEY_free(ec);
	return ret;
}
/**
 *  eccx08_eckey_convert()
 *
 * \brief Converts raw 64 bytes of public key (ATECC508 format) to the
 *  openssl EC_KEY structure. It allocates EC_KEY structure and
 *  does not free it (must be a caller to free)
 *
 * \param[out] p_eckey Pointer to EC_KEY with Public Key on success
 * \param[in] raw_pubkey Raw public key, 64 bytes length 32-byte X following with 32-byte Y
 * \param[in] serial_number 9 bytes of ATECCX08 serial number
 * \param[in] serial_len Size of the ATECCX08 serial number buffer
 * \return 1 on success, 0 on error
 */
int eccx08_eckey_convert(EC_KEY **p_eckey, uint8_t *raw_pubkey, uint8_t *serial_number, int serial_len)
{
    int rc = 0;
    int ret = 0;
    EC_GROUP *ecgroup = NULL, *ecgroup_old = NULL;
    EC_KEY *eckey = *p_eckey;
    EC_POINT *ecpoint = NULL;
    BN_CTX *bnctx = NULL;
    int asn1_flag = OPENSSL_EC_NAMED_CURVE;
    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
    char tmp_buf[MEM_BLOCK_SIZE * 2 + 1];


    /* Openssl raw key has a leading byte with conversion form id */
    tmp_buf[0] = POINT_CONVERSION_UNCOMPRESSED;
    memcpy(&tmp_buf[1], raw_pubkey, MEM_BLOCK_SIZE * 2);

    if (!eckey) {
        eckey = EC_KEY_new();
        if (!eckey) goto done;
    }
    ecgroup = eckey->group;
    if (!ecgroup) {
        ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
        if (!ecgroup) goto done;
        EC_GROUP_set_point_conversion_form(ecgroup, form);
        EC_GROUP_set_asn1_flag(ecgroup, asn1_flag);
    }

    if (!eckey->group) {
        ret = EC_KEY_set_group(eckey, ecgroup);
        if (!ret) goto done;
    }

    ret = eccx08_generate_key(eckey, serial_number, serial_len);
    if (!ret) goto done;

    ecgroup = eckey->group;
    ecpoint = eckey->pub_key;

    if (!ecpoint) {
        ecpoint = EC_POINT_new(ecgroup);
        if (!ecpoint) goto done;
    }

    ret = EC_POINT_oct2point(ecgroup, ecpoint, tmp_buf, MEM_BLOCK_SIZE * 2 + 1, NULL);
    if (!ret) goto done;

    *p_eckey = eckey;
    rc = 1;
done:
    return (rc);
}
Пример #6
0
static EC_KEY *eckey_type2param(int ptype, void *pval)
	{
	EC_KEY *eckey = NULL;
	if (ptype == V_ASN1_SEQUENCE)
		{
		ASN1_STRING *pstr = pval;
		const unsigned char *pm = NULL;
		int pmlen;
		pm = pstr->data;
		pmlen = pstr->length;
		if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen)))
			{
			ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
			goto ecerr;
			}
		}
	else if (ptype == V_ASN1_OBJECT)
		{
		ASN1_OBJECT *poid = pval;
		EC_GROUP *group;

		/* type == V_ASN1_OBJECT => the parameters are given
		 * by an asn1 OID
		 */
		if ((eckey = EC_KEY_new()) == NULL)
			{
			ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
			goto ecerr;
			}
		group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
		if (group == NULL)
			goto ecerr;
		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
		if (EC_KEY_set_group(eckey, group) == 0)
			goto ecerr;
		EC_GROUP_free(group);
		}
	else
		{
		ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
		goto ecerr;
		}

	return eckey;

	ecerr:
	if (eckey)
		EC_KEY_free(eckey);
	return NULL;
	}
Пример #7
0
void pki_evp::generate(int bits, int type, QProgressBar *progress, int curve_nid)
{
	RSA *rsakey;
	DSA *dsakey;
	EC_KEY *eckey;

	progress->setMinimum(0);
	progress->setMaximum(100);
	progress->setValue(50);

	switch (type) {
	case EVP_PKEY_RSA:
		rsakey = RSA_generate_key(bits, 0x10001, inc_progress_bar,
			progress);
		if (rsakey)
			EVP_PKEY_assign_RSA(key, rsakey);
		break;
	case EVP_PKEY_DSA:
		progress->setMaximum(500);
		dsakey = DSA_generate_parameters(bits, NULL, 0, NULL, NULL,
				inc_progress_bar, progress);
		DSA_generate_key(dsakey);
		if (dsakey)
			EVP_PKEY_assign_DSA(key, dsakey);
		break;
	case EVP_PKEY_EC:
		EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_nid);
		if (!group)
			break;
		eckey = EC_KEY_new();
		if (eckey == NULL) {
			EC_GROUP_free(group);
			break;
		}
		EC_GROUP_set_asn1_flag(group, 1);
		if (EC_KEY_set_group(eckey, group)) {
			if (EC_KEY_generate_key(eckey)) {
				EVP_PKEY_assign_EC_KEY(key, eckey);
				EC_GROUP_free(group);
				break;
			}
		}
		EC_KEY_free(eckey);
		EC_GROUP_free(group);
		break;
	}
	pki_openssl_error();
	encryptKey();
}
Пример #8
0
static int createNewKey(EC_GROUP *group, EC_KEY *eckey) {

    int asn1Flag = OPENSSL_EC_NAMED_CURVE;
    int form = POINT_CONVERSION_UNCOMPRESSED;

    EC_GROUP_set_asn1_flag(group, asn1Flag);
    EC_GROUP_set_point_conversion_form(group, form);
    int setGroupError = EC_KEY_set_group(eckey, group);

    int resultFromKeyGen = EC_KEY_generate_key(eckey);

    if (resultFromKeyGen != 1 || setGroupError != 1){
        return ERROR;
    }

    return NOERROR;
}
Пример #9
0
static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor)
{
	EC_KEY *ec_key = NULL;
	int ptype;
	void *pval;
	const unsigned char *p;
	
	X509_ALGOR_get0(NULL, &ptype, &pval, algor);
	
	if (ptype == V_ASN1_SEQUENCE) {
		ASN1_OCTET_STRING *pstr = (ASN1_OCTET_STRING *)pval;
		p = pstr->data;
		if (!(ec_key = d2i_ECParameters(NULL, &p, pstr->length))) {
			CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB);
			return NULL;
		}
	
	} else if (ptype == V_ASN1_OBJECT) {
		ASN1_OBJECT *poid = (ASN1_OBJECT *)pval;
		EC_GROUP *group;
		if (!(ec_key = EC_KEY_new())) {	
			CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_MALLOC_FAILURE);
			return NULL;
		}	
		if (!(group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)))) {
			EC_KEY_free(ec_key);
			CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB);
			return NULL;
		}
		EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
		if (!EC_KEY_set_group(ec_key, group)) {
			EC_GROUP_free(group);
			EC_KEY_free(ec_key);
			CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB);
			return NULL;
		}
		EC_GROUP_free(group);
	
	} else {
		CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, CPK_R_BAD_DATA);
		return NULL;
	}
	return ec_key;	
}
Пример #10
0
/*
 * Parses GOST algorithm parameters from X509_ALGOR and
 * modifies pkey setting NID and parameters
 */
static int
decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len)
{
	int param_nid = NID_undef, digest_nid = NID_undef;
	GOST_KEY_PARAMS *gkp = NULL;
	EC_GROUP *group;
	GOST_KEY *ec;

	gkp = d2i_GOST_KEY_PARAMS(NULL, p, len);
	if (gkp == NULL) {
		GOSTerr(GOST_F_DECODE_GOST01_ALGOR_PARAMS,
			GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
		return 0;
	}
	param_nid = OBJ_obj2nid(gkp->key_params);
	digest_nid = OBJ_obj2nid(gkp->hash_params);
	GOST_KEY_PARAMS_free(gkp);

	ec = pkey->pkey.gost;
	if (ec == NULL) {
		ec = GOST_KEY_new();
		if (ec == NULL)
			return 0;
		if (EVP_PKEY_assign_GOST(pkey, ec) == 0)
			return 0;
	}

	group = EC_GROUP_new_by_curve_name(param_nid);
	if (group == NULL)
		return 0;
	EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
	if (GOST_KEY_set_group(ec, group) == 0) {
		EC_GROUP_free(group);
		return 0;
	}
	EC_GROUP_free(group);
	if (GOST_KEY_set_digest(ec, digest_nid) == 0)
		return 0;
	return 1;
}
Пример #11
0
static void search_ec_oid(EC_KEY *ec)
{
	const EC_GROUP *ec_group = EC_KEY_get0_group(ec);
	EC_GROUP *builtin;

	if (!ec_group)
		return;
	if (EC_GROUP_get_curve_name(ec_group))
		return;
	/* There is an EC_GROUP with a missing OID
	 * because of explicit parameters */
	for (size_t i=0; i<pki_evp::num_curves; i++) {
		int nid = pki_evp::curves[i].nid;
		builtin = EC_GROUP_new_by_curve_name(nid);
		if (EC_GROUP_cmp(builtin, ec_group, NULL) == 0) {
			EC_GROUP_set_curve_name((EC_GROUP *)ec_group, nid);
			EC_GROUP_set_asn1_flag((EC_GROUP *)ec_group, 1);
			EC_GROUP_free(builtin);
			break;
		} else {
			EC_GROUP_free(builtin);
		}
	}
}
Пример #12
0
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
{
  EVP_PKEY *pkey = NULL;
#ifndef OPENSSL_NO_RSA
  RSA *rsa = NULL;
#endif
#ifndef OPENSSL_NO_DSA
  DSA *dsa = NULL;
  ASN1_TYPE *t1, *t2;
  ASN1_INTEGER *privkey;
  STACK_OF(ASN1_TYPE) *ndsa = NULL;
#endif
#ifndef OPENSSL_NO_EC
  EC_KEY *eckey = NULL;
  const unsigned char *p_tmp;
#endif
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
  ASN1_TYPE    *param = NULL;  
  BN_CTX *ctx = NULL;
  int plen;
#endif
  X509_ALGOR *a;
  const unsigned char *p;
  const unsigned char *cp;
  int pkeylen;
  int  nid;
  char obj_tmp[80];

  if(p8->pkey->type == V_ASN1_OCTET_STRING) {
    p8->broken = PKCS8_OK;
    p = p8->pkey->value.octet_string->data;
    pkeylen = p8->pkey->value.octet_string->length;
  } else {
    p8->broken = PKCS8_NO_OCTET;
    p = p8->pkey->value.sequence->data;
    pkeylen = p8->pkey->value.sequence->length;
  }
  if (!(pkey = EVP_PKEY_new())) {
    EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  a = p8->pkeyalg;
  nid = OBJ_obj2nid(a->algorithm);
  switch(nid)
  {
#ifndef OPENSSL_NO_RSA
    case NID_rsaEncryption:
    cp = p;
    if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      return NULL;
    }
    EVP_PKEY_assign_RSA (pkey, rsa);
    break;
#endif
#ifndef OPENSSL_NO_DSA
    case NID_dsa:
    /* PKCS#8 DSA is weird: you just get a private key integer
           * and parameters in the AlgorithmIdentifier the pubkey must
     * be recalculated.
     */
  
    /* Check for broken DSA PKCS#8, UGH! */
    if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
        if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, 
                d2i_ASN1_TYPE,
                ASN1_TYPE_free))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        if(sk_ASN1_TYPE_num(ndsa) != 2 ) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        /* Handle Two broken types:
         * SEQUENCE {parameters, priv_key}
         * SEQUENCE {pub_key, priv_key}
         */

        t1 = sk_ASN1_TYPE_value(ndsa, 0);
        t2 = sk_ASN1_TYPE_value(ndsa, 1);
        if(t1->type == V_ASN1_SEQUENCE) {
      p8->broken = PKCS8_EMBEDDED_PARAM;
      param = t1;
        } else if(a->parameter->type == V_ASN1_SEQUENCE) {
      p8->broken = PKCS8_NS_DB;
      param = a->parameter;
        } else {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }

        if(t2->type != V_ASN1_INTEGER) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
        }
        privkey = t2->value.integer;
    } else {
      if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
        goto dsaerr;
      }
      param = p8->pkeyalg->parameter;
    }
    if (!param || (param->type != V_ASN1_SEQUENCE)) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
    }
    cp = p = param->value.sequence->data;
    plen = param->value.sequence->length;
    if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto dsaerr;
    }
    /* We have parameters now set private key */
    if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
      goto dsaerr;
    }
    /* Calculate public key (ouch!) */
    if (!(dsa->pub_key = BN_new())) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
      goto dsaerr;
    }
    if (!(ctx = BN_CTX_new())) {
      EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
      goto dsaerr;
    }
      
    if (!BN_mod_exp(dsa->pub_key, dsa->g,
             dsa->priv_key, dsa->p, ctx)) {
      
      EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
      goto dsaerr;
    }

    EVP_PKEY_assign_DSA(pkey, dsa);
    BN_CTX_free (ctx);
    if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    else ASN1_INTEGER_free(privkey);
    break;
    dsaerr:
    BN_CTX_free (ctx);
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    DSA_free(dsa);
    EVP_PKEY_free(pkey);
    return NULL;
    break;
#endif
#ifndef OPENSSL_NO_EC
    case NID_X9_62_id_ecPublicKey:
    p_tmp = p;
    /* extract the ec parameters */
    param = p8->pkeyalg->parameter;

    if (!param || ((param->type != V_ASN1_SEQUENCE) &&
        (param->type != V_ASN1_OBJECT)))
    {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto ecerr;
    }

    if (param->type == V_ASN1_SEQUENCE)
    {
      cp = p = param->value.sequence->data;
      plen = param->value.sequence->length;

      if (!(eckey = d2i_ECParameters(NULL, &cp, plen)))
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY,
          EVP_R_DECODE_ERROR);
        goto ecerr;
      }
    }
    else
    {
      EC_GROUP *group;
      cp = p = param->value.object->data;
      plen = param->value.object->length;

      /* type == V_ASN1_OBJECT => the parameters are given
       * by an asn1 OID
       */
      if ((eckey = EC_KEY_new()) == NULL)
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY,
          ERR_R_MALLOC_FAILURE);
        goto ecerr;
      }
      group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
      if (group == NULL)
        goto ecerr;
      EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
      if (EC_KEY_set_group(eckey, group) == 0)
        goto ecerr;
      EC_GROUP_free(group);
    }

    /* We have parameters now set private key */
    if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen))
    {
      EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
      goto ecerr;
    }

    /* calculate public key (if necessary) */
    if (EC_KEY_get0_public_key(eckey) == NULL)
    {
      const BIGNUM *priv_key;
      const EC_GROUP *group;
      EC_POINT *pub_key;
      /* the public key was not included in the SEC1 private
       * key => calculate the public key */
      group   = EC_KEY_get0_group(eckey);
      pub_key = EC_POINT_new(group);
      if (pub_key == NULL)
      {
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      priv_key = EC_KEY_get0_private_key(eckey);
      if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      if (EC_KEY_set_public_key(eckey, pub_key) == 0)
      {
        EC_POINT_free(pub_key);
        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
        goto ecerr;
      }
      EC_POINT_free(pub_key);
    }

    EVP_PKEY_assign_EC_KEY(pkey, eckey);
    if (ctx)
      BN_CTX_free(ctx);
    break;
ecerr:
    if (ctx)
      BN_CTX_free(ctx);
    if (eckey)
      EC_KEY_free(eckey);
    if (pkey)
      EVP_PKEY_free(pkey);
    return NULL;
#endif
    default:
    EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
    if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp);
    else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
    ERR_add_error_data(2, "TYPE=", obj_tmp);
    EVP_PKEY_free (pkey);
    return NULL;
  }
  return pkey;
}
Пример #13
0
int 
ecparam_main(int argc, char **argv)
{
	EC_GROUP *group = NULL;
	point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
	int new_form = 0;
	int asn1_flag = OPENSSL_EC_NAMED_CURVE;
	int new_asn1_flag = 0;
	char *curve_name = NULL, *inrand = NULL;
	int list_curves = 0, no_seed = 0, check = 0, badops = 0, text = 0,
	 i, genkey = 0;
	char *infile = NULL, *outfile = NULL, *prog;
	BIO *in = NULL, *out = NULL;
	int informat, outformat, noout = 0, C = 0, ret = 1;
	char *engine = NULL;

	BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL,
	*ec_order = NULL, *ec_cofactor = NULL;
	unsigned char *buffer = NULL;

	if (!load_config(bio_err, NULL))
		goto end;

	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;

	prog = argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-text") == 0)
			text = 1;
		else if (strcmp(*argv, "-C") == 0)
			C = 1;
		else if (strcmp(*argv, "-check") == 0)
			check = 1;
		else if (strcmp(*argv, "-name") == 0) {
			if (--argc < 1)
				goto bad;
			curve_name = *(++argv);
		} else if (strcmp(*argv, "-list_curves") == 0)
			list_curves = 1;
		else if (strcmp(*argv, "-conv_form") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_form = 1;
			if (strcmp(*argv, "compressed") == 0)
				form = POINT_CONVERSION_COMPRESSED;
			else if (strcmp(*argv, "uncompressed") == 0)
				form = POINT_CONVERSION_UNCOMPRESSED;
			else if (strcmp(*argv, "hybrid") == 0)
				form = POINT_CONVERSION_HYBRID;
			else
				goto bad;
		} else if (strcmp(*argv, "-param_enc") == 0) {
			if (--argc < 1)
				goto bad;
			++argv;
			new_asn1_flag = 1;
			if (strcmp(*argv, "named_curve") == 0)
				asn1_flag = OPENSSL_EC_NAMED_CURVE;
			else if (strcmp(*argv, "explicit") == 0)
				asn1_flag = 0;
			else
				goto bad;
		} else if (strcmp(*argv, "-no_seed") == 0)
			no_seed = 1;
		else if (strcmp(*argv, "-noout") == 0)
			noout = 1;
		else if (strcmp(*argv, "-genkey") == 0) {
			genkey = 1;
		} else if (strcmp(*argv, "-rand") == 0) {
			if (--argc < 1)
				goto bad;
			inrand = *(++argv);
		} else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
		BIO_printf(bio_err, "where options are\n");
		BIO_printf(bio_err, " -inform arg       input format - "
		    "default PEM (DER or PEM)\n");
		BIO_printf(bio_err, " -outform arg      output format - "
		    "default PEM\n");
		BIO_printf(bio_err, " -in  arg          input file  - "
		    "default stdin\n");
		BIO_printf(bio_err, " -out arg          output file - "
		    "default stdout\n");
		BIO_printf(bio_err, " -noout            do not print the "
		    "ec parameter\n");
		BIO_printf(bio_err, " -text             print the ec "
		    "parameters in text form\n");
		BIO_printf(bio_err, " -check            validate the ec "
		    "parameters\n");
		BIO_printf(bio_err, " -C                print a 'C' "
		    "function creating the parameters\n");
		BIO_printf(bio_err, " -name arg         use the "
		    "ec parameters with 'short name' name\n");
		BIO_printf(bio_err, " -list_curves      prints a list of "
		    "all currently available curve 'short names'\n");
		BIO_printf(bio_err, " -conv_form arg    specifies the "
		    "point conversion form \n");
		BIO_printf(bio_err, "                   possible values:"
		    " compressed\n");
		BIO_printf(bio_err, "                                   "
		    " uncompressed (default)\n");
		BIO_printf(bio_err, "                                   "
		    " hybrid\n");
		BIO_printf(bio_err, " -param_enc arg    specifies the way"
		    " the ec parameters are encoded\n");
		BIO_printf(bio_err, "                   in the asn1 der "
		    "encoding\n");
		BIO_printf(bio_err, "                   possible values:"
		    " named_curve (default)\n");
		BIO_printf(bio_err, "                                   "
		    " explicit\n");
		BIO_printf(bio_err, " -no_seed          if 'explicit'"
		    " parameters are chosen do not"
		    " use the seed\n");
		BIO_printf(bio_err, " -genkey           generate ec"
		    " key\n");
		BIO_printf(bio_err, " -rand file        files to use for"
		    " random number input\n");
		BIO_printf(bio_err, " -engine e         use engine e, "
		    "possibly a hardware device\n");
		goto end;
	}
	ERR_load_crypto_strings();

	in = BIO_new(BIO_s_file());
	out = BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (infile == NULL)
		BIO_set_fp(in, stdin, BIO_NOCLOSE);
	else {
		if (BIO_read_filename(in, infile) <= 0) {
			perror(infile);
			goto end;
		}
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	if (list_curves) {
		EC_builtin_curve *curves = NULL;
		size_t crv_len = 0;
		size_t n = 0;

		crv_len = EC_get_builtin_curves(NULL, 0);

		curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));

		if (curves == NULL)
			goto end;

		if (!EC_get_builtin_curves(curves, crv_len)) {
			free(curves);
			goto end;
		}
		for (n = 0; n < crv_len; n++) {
			const char *comment;
			const char *sname;
			comment = curves[n].comment;
			sname = OBJ_nid2sn(curves[n].nid);
			if (comment == NULL)
				comment = "CURVE DESCRIPTION NOT AVAILABLE";
			if (sname == NULL)
				sname = "";

			BIO_printf(out, "  %-10s: ", sname);
			BIO_printf(out, "%s\n", comment);
		}

		free(curves);
		ret = 0;
		goto end;
	}
	if (curve_name != NULL) {
		int nid;

		/*
		 * workaround for the SECG curve names secp192r1 and
		 * secp256r1 (which are the same as the curves prime192v1 and
		 * prime256v1 defined in X9.62)
		 */
		if (!strcmp(curve_name, "secp192r1")) {
			BIO_printf(bio_err, "using curve name prime192v1 "
			    "instead of secp192r1\n");
			nid = NID_X9_62_prime192v1;
		} else if (!strcmp(curve_name, "secp256r1")) {
			BIO_printf(bio_err, "using curve name prime256v1 "
			    "instead of secp256r1\n");
			nid = NID_X9_62_prime256v1;
		} else
			nid = OBJ_sn2nid(curve_name);

		if (nid == 0) {
			BIO_printf(bio_err, "unknown curve name (%s)\n",
			    curve_name);
			goto end;
		}
		group = EC_GROUP_new_by_curve_name(nid);
		if (group == NULL) {
			BIO_printf(bio_err, "unable to create curve (%s)\n",
			    curve_name);
			goto end;
		}
		EC_GROUP_set_asn1_flag(group, asn1_flag);
		EC_GROUP_set_point_conversion_form(group, form);
	} else if (informat == FORMAT_ASN1) {
		group = d2i_ECPKParameters_bio(in, NULL);
	} else if (informat == FORMAT_PEM) {
		group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
	} else {
		BIO_printf(bio_err, "bad input format specified\n");
		goto end;
	}

	if (group == NULL) {
		BIO_printf(bio_err,
		    "unable to load elliptic curve parameters\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	if (new_form)
		EC_GROUP_set_point_conversion_form(group, form);

	if (new_asn1_flag)
		EC_GROUP_set_asn1_flag(group, asn1_flag);

	if (no_seed) {
		EC_GROUP_set_seed(group, NULL, 0);
	}
	if (text) {
		if (!ECPKParameters_print(out, group, 0))
			goto end;
	}
	if (check) {
		if (group == NULL)
			BIO_printf(bio_err, "no elliptic curve parameters\n");
		BIO_printf(bio_err, "checking elliptic curve parameters: ");
		if (!EC_GROUP_check(group, NULL)) {
			BIO_printf(bio_err, "failed\n");
			ERR_print_errors(bio_err);
		} else
			BIO_printf(bio_err, "ok\n");

	}
	if (C) {
		size_t buf_len = 0, tmp_len = 0;
		const EC_POINT *point;
		int is_prime, len = 0;
		const EC_METHOD *meth = EC_GROUP_method_of(group);

		if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
		    (ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
		    (ec_order = BN_new()) == NULL ||
		    (ec_cofactor = BN_new()) == NULL) {
			perror("malloc");
			goto end;
		}
		is_prime = (EC_METHOD_get_field_type(meth) ==
		    NID_X9_62_prime_field);

		if (is_prime) {
			if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
				ec_b, NULL))
				goto end;
		} else {
			/* TODO */
			goto end;
		}

		if ((point = EC_GROUP_get0_generator(group)) == NULL)
			goto end;
		if (!EC_POINT_point2bn(group, point,
			EC_GROUP_get_point_conversion_form(group), ec_gen,
			NULL))
			goto end;
		if (!EC_GROUP_get_order(group, ec_order, NULL))
			goto end;
		if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
			goto end;

		if (!ec_p || !ec_a || !ec_b || !ec_gen ||
		    !ec_order || !ec_cofactor)
			goto end;

		len = BN_num_bits(ec_order);

		if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
			buf_len = tmp_len;
		if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
			buf_len = tmp_len;

		buffer = (unsigned char *) malloc(buf_len);

		if (buffer == NULL) {
			perror("malloc");
			goto end;
		}
		ecparam_print_var(out, ec_p, "ec_p", len, buffer);
		ecparam_print_var(out, ec_a, "ec_a", len, buffer);
		ecparam_print_var(out, ec_b, "ec_b", len, buffer);
		ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
		ecparam_print_var(out, ec_order, "ec_order", len, buffer);
		ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
		    buffer);

		BIO_printf(out, "\n\n");

		BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
		BIO_printf(out, "\tint ok=0;\n");
		BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
		BIO_printf(out, "\tEC_POINT *point = NULL;\n");
		BIO_printf(out, "\tBIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, "
		    "*tmp_3 = NULL;\n\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
		    "sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
		    "sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
		    "sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
		    "goto err;\n", len, len);
		if (is_prime) {
			BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
			    "GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
			    "\n\t\tgoto err;\n\n");
		} else {
			/* TODO */
			goto end;
		}
		BIO_printf(out, "\t/* build generator */\n");
		BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
		    "sizeof(ec_gen_%d), tmp_1)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
		    "NULL, NULL);\n");
		BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
		BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
		    "sizeof(ec_order_%d), tmp_2)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
		    "sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
		    "\n\t\tgoto err;\n", len, len);
		BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
		    " tmp_2, tmp_3))\n\t\tgoto err;\n");
		BIO_printf(out, "\n\tok=1;\n");
		BIO_printf(out, "err:\n");
		BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
		BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
		BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
		BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
		BIO_printf(out, "\tif (!ok)\n");
		BIO_printf(out, "\t\t{\n");
		BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
		BIO_printf(out, "\t\tgroup = NULL;\n");
		BIO_printf(out, "\t\t}\n");
		BIO_printf(out, "\treturn(group);\n\t}\n");
	}
	if (!noout) {
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPKParameters_bio(out, group);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPKParameters(out, group);
		else {
			BIO_printf(bio_err, "bad output format specified for"
			    " outfile\n");
			goto end;
		}
		if (!i) {
			BIO_printf(bio_err, "unable to write elliptic "
			    "curve parameters\n");
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (genkey) {
		EC_KEY *eckey = EC_KEY_new();

		if (eckey == NULL)
			goto end;

		if (EC_KEY_set_group(eckey, group) == 0)
			goto end;

		if (!EC_KEY_generate_key(eckey)) {
			EC_KEY_free(eckey);
			goto end;
		}
		if (outformat == FORMAT_ASN1)
			i = i2d_ECPrivateKey_bio(out, eckey);
		else if (outformat == FORMAT_PEM)
			i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
			    NULL, 0, NULL, NULL);
		else {
			BIO_printf(bio_err, "bad output format specified "
			    "for outfile\n");
			EC_KEY_free(eckey);
			goto end;
		}
		EC_KEY_free(eckey);
	}
	ret = 0;
end:
	if (ec_p)
		BN_free(ec_p);
	if (ec_a)
		BN_free(ec_a);
	if (ec_b)
		BN_free(ec_b);
	if (ec_gen)
		BN_free(ec_gen);
	if (ec_order)
		BN_free(ec_order);
	if (ec_cofactor)
		BN_free(ec_cofactor);
	free(buffer);
	if (in != NULL)
		BIO_free(in);
	if (out != NULL)
		BIO_free_all(out);
	if (group != NULL)
		EC_GROUP_free(group);
	
	return (ret);
}
Пример #14
0
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
    EC_PKEY_CTX *dctx = ctx->data;
    EC_GROUP *group;
    switch (type) {
    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
        group = EC_GROUP_new_by_curve_name(p1);
        if (group == NULL) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
            return 0;
        }
        EC_GROUP_free(dctx->gen_group);
        dctx->gen_group = group;
        return 1;

    case EVP_PKEY_CTRL_EC_PARAM_ENC:
        if (!dctx->gen_group) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
            return 0;
        }
        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
        return 1;

#ifndef OPENSSL_NO_EC
    case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
        if (p1 == -2) {
            if (dctx->cofactor_mode != -1)
                return dctx->cofactor_mode;
            else {
                EC_KEY *ec_key = ctx->pkey->pkey.ec;
                return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
                    0;
            }
        } else if (p1 < -1 || p1 > 1)
            return -2;
        dctx->cofactor_mode = p1;
        if (p1 != -1) {
            EC_KEY *ec_key = ctx->pkey->pkey.ec;
            if (!ec_key->group)
                return -2;
            /* If cofactor is 1 cofactor mode does nothing */
            if (BN_is_one(ec_key->group->cofactor))
                return 1;
            if (!dctx->co_key) {
                dctx->co_key = EC_KEY_dup(ec_key);
                if (!dctx->co_key)
                    return 0;
            }
            if (p1)
                EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
            else
                EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
        } else {
            EC_KEY_free(dctx->co_key);
            dctx->co_key = NULL;
        }
        return 1;
#endif

    case EVP_PKEY_CTRL_EC_KDF_TYPE:
        if (p1 == -2)
            return dctx->kdf_type;
        if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
            return -2;
        dctx->kdf_type = p1;
        return 1;

    case EVP_PKEY_CTRL_EC_KDF_MD:
        dctx->kdf_md = p2;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_MD:
        *(const EVP_MD **)p2 = dctx->kdf_md;
        return 1;

    case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
        if (p1 <= 0)
            return -2;
        dctx->kdf_outlen = (size_t)p1;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
        *(int *)p2 = dctx->kdf_outlen;
        return 1;

    case EVP_PKEY_CTRL_EC_KDF_UKM:
        OPENSSL_free(dctx->kdf_ukm);
        dctx->kdf_ukm = p2;
        if (p2)
            dctx->kdf_ukmlen = p1;
        else
            dctx->kdf_ukmlen = 0;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
        *(unsigned char **)p2 = dctx->kdf_ukm;
        return dctx->kdf_ukmlen;

    case EVP_PKEY_CTRL_MD:
        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
            return 0;
        }
        dctx->md = p2;
        return 1;

    case EVP_PKEY_CTRL_GET_MD:
        *(const EVP_MD **)p2 = dctx->md;
        return 1;

    case EVP_PKEY_CTRL_PEER_KEY:
        /* Default behaviour is OK */
    case EVP_PKEY_CTRL_DIGESTINIT:
    case EVP_PKEY_CTRL_PKCS7_SIGN:
    case EVP_PKEY_CTRL_CMS_SIGN:
        return 1;

    default:
        return -2;

    }
}
Пример #15
0
std::string
CertificateManager::generateECDSACertificate ()
{
  EC_KEY *ec_key;
  std::shared_ptr <EC_GROUP> group;
  std::shared_ptr <EVP_PKEY> private_key;
  std::string pem;
  std::string ecdsaParameters, ecdsaKey;
  std::string certificateECDSA;

  ec_key = EC_KEY_new ();

  if (ec_key == nullptr) {
    GST_ERROR ("EC key not created");
    return certificateECDSA;
  }

  group = std::shared_ptr <EC_GROUP> (EC_GROUP_new_by_curve_name (
                                        NID_X9_62_prime256v1),
  [] (EC_GROUP * obj) {
    EC_GROUP_free (obj);
  });
  EC_GROUP_set_asn1_flag (group.get(), OPENSSL_EC_NAMED_CURVE);

  if (group == nullptr) {
    EC_KEY_free (ec_key);
    GST_ERROR ("EC group not created");
    return certificateECDSA;
  }

  if (EC_KEY_set_group (ec_key, group.get() ) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Group not set to key");
    return certificateECDSA;
  }

  if (EC_KEY_generate_key (ec_key) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("EC key not generated");
    return certificateECDSA;
  }

  private_key = std::shared_ptr<EVP_PKEY> (EVP_PKEY_new (),
  [] (EVP_PKEY * obj) {
    EVP_PKEY_free (obj);
  });

  if (private_key == nullptr) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Private key not created");
    return certificateECDSA;
  }

  if (EVP_PKEY_assign_EC_KEY (private_key.get(), ec_key) == 0) {
    EC_KEY_free (ec_key);
    GST_ERROR ("Private key not assigned");
    return certificateECDSA;
  }

  pem = generateCertificate (private_key.get() );

  if (pem.empty () ) {
    GST_WARNING ("Certificate not generated");
    return certificateECDSA;
  }

  ecdsaKey = ECDSAKeyToPEMString (ec_key);
  ec_key = nullptr;
  ecdsaParameters = parametersToPEMString (group.get() );

  certificateECDSA = ecdsaParameters + ecdsaKey + pem;

  return certificateECDSA;
}
Пример #16
0
EC_GROUP* openssl_get_ec_group(lua_State* L, int ec_name_idx, int param_enc_idx,
  int conv_form_idx)
{
  int nid = NID_undef;
  EC_GROUP* g = NULL;
  if (lua_isnumber(L, ec_name_idx))
    nid = lua_tointeger(L, ec_name_idx);
  else if (lua_isstring(L, ec_name_idx))
  {
    const char* name = luaL_checkstring(L, ec_name_idx);
    nid = OBJ_sn2nid(name);
  } else if (lua_isuserdata(L, ec_name_idx))
  {
    if (auxiliar_isclass(L, "openssl.evp_pkey", ec_name_idx))
    {
      EVP_PKEY* pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey");
      EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(pkey);
      if (ec_key)
      {
        g = (EC_GROUP*)EC_KEY_get0_group(ec_key);
        EC_KEY_free(ec_key);
      }
    } else if (auxiliar_isclass(L, "openssl.ec_key", ec_name_idx))
    {
      EC_KEY* ec_key = CHECK_OBJECT(1, EC_KEY, "openssl.ec_key");
      g = (EC_GROUP*)EC_KEY_get0_group(ec_key);
    }
    if (g)
      g = EC_GROUP_dup(g);
  }

  if (g == NULL && nid != NID_undef)
    g = EC_GROUP_new_by_curve_name(nid);

  if (g)
  {
    if (param_enc_idx)
    {
      int form = 0;
      if (lua_isstring(L, param_enc_idx))
      {
        const char* options[] = {"compressed", "uncompressed", "hybrid", NULL};
        int f = luaL_checkoption(L, param_enc_idx, NULL, options);
        if (f == 0)
          form = POINT_CONVERSION_COMPRESSED;
        else if (f == 1)
          form = POINT_CONVERSION_UNCOMPRESSED;
        else if (f == 2)
          form = POINT_CONVERSION_HYBRID;
        else
          luaL_argerror(L, param_enc_idx, "not accept value point_conversion_form");
        EC_GROUP_set_point_conversion_form(g, form);
      } else if (lua_isnumber(L, param_enc_idx))
      {
        form = luaL_checkint(L, param_enc_idx);
        EC_GROUP_set_point_conversion_form(g, form);
      } else if (lua_isnoneornil(L, param_enc_idx))
      {
        EC_GROUP_set_point_conversion_form(g, POINT_CONVERSION_UNCOMPRESSED);
      }
      else
        luaL_argerror(L, param_enc_idx, "not accept type of point_conversion_form");
    }else
      EC_GROUP_set_point_conversion_form(g, POINT_CONVERSION_UNCOMPRESSED);

    if (conv_form_idx)
    {
      int asn1_flag = 0;
      if (lua_isstring(L, conv_form_idx))
      {           /* OPENSSL_EC_NAMED_CURVE,   0 */
        const char* const options[] = {"named_curve", "explicit", NULL};
        asn1_flag = luaL_checkoption(L, conv_form_idx, NULL, options);
        EC_GROUP_set_asn1_flag(g, asn1_flag);
      } else if (lua_isnumber(L, conv_form_idx))
      {
        asn1_flag = luaL_checkint(L, conv_form_idx);
        EC_GROUP_set_asn1_flag(g, asn1_flag);
      } else if (lua_isnoneornil(L, conv_form_idx))
      {
        EC_GROUP_set_asn1_flag(g, OPENSSL_EC_NAMED_CURVE);
      }
      else
        luaL_argerror(L, conv_form_idx, "not accept type of asn1 flag");
    }else
      EC_GROUP_set_asn1_flag(g, OPENSSL_EC_NAMED_CURVE);
  }

  return g;
}
Пример #17
0
void test_ssl() {
    interface ifs[16];
    active_interfaces(ifs, 16);

    char *passwd = "password";
    char *dir = chdir_temp_dir();

    kdfp kdfp = { .N = 2, .r = 1, .p = 1};
    uint8_t kek[KEY_LEN]  = { 0 };
    struct server_cfg cfg = {
        .passwd = passwd,
        .cert   = "server.pem",
        .ifa    = &ifs[0],
    };
    pthread_t tid;

    EC_GROUP *group = EC_GROUP_new_by_curve_name(OBJ_txt2nid(EC_CURVE_NAME));
    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
    init_certs(group, passwd, "server.pem", "client.pem");
    init_certs(group, passwd, "zerver.pem", "zlient.pem");
    init_index("index", kek, &kdfp);
    EC_GROUP_free(group);

    assert(pthread_create(&tid, NULL, &run_server, &cfg) == 0);

    struct timeval timeout = { .tv_usec = 500 };
    uint32_t usecs = 10000;
    sockaddr6 addr;
    X509 *cert = NULL, *sert = NULL;
    EVP_PKEY *pk = NULL, *sk = NULL;
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
    uint8_t data[KDFP_LEN];

    // client/server cert & pk mismatch
    read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert);
    read_pem("server.pem", NULL, passwd, &sk, 0);

    assert(client_ctx(sert, cert, sk) == NULL);
    assert(server_sock(&ctx, sert, pk, cfg.ifa, &addr) == -1);
    assert(ctx == NULL);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    // incorrect signature on pong
    read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert);
    assert(find_server(sk, &addr, usecs, 30) == false);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    // incorrect server certificate
    read_pem("server.pem", NULL, passwd, &sk, 1, &sert);
    assert(find_server(sk, &addr, usecs, 30) == true);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert);
    X509_free(sert);
    read_pem("zerver.pem", NULL, passwd, &sk, 1, &sert);
    ctx = client_ctx(sert, cert, pk);
    assert(client_socket(ctx, &addr, &timeout) == NULL);
    assert(ERR_GET_REASON(ERR_get_error()) == SSL_R_CERTIFICATE_VERIFY_FAILED);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    // incorrect client certificate
    read_pem("zlient.pem", NULL, passwd, &pk, 1, &cert);
    read_pem("server.pem", NULL, passwd, &sk, 1, &sert);
    ctx = client_ctx(sert, cert, pk);
    assert(client_socket(ctx, &addr, &timeout) == NULL);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    // valid certificates
    read_pem("client.pem", NULL, passwd, &pk, 2, &sert, &cert);
    read_pem("server.pem", NULL, passwd, &sk, 0);
    ctx = client_ctx(sert, cert, pk);
    assert((ssl = client_socket(ctx, &addr, &timeout)));
    assert(SSL_read(ssl, &data, KDFP_LEN) == KDFP_LEN);
    cleanup(&ctx, &ssl, &sert, &cert, &sk, &pk);

    pthread_kill(tid, SIGINT);
    pthread_join(tid, NULL);

    unlink("server.pem");
    unlink("client.pem");
    unlink("zerver.pem");
    unlink("zlient.pem");
    unlink("index");

    rmdir_temp_dir(dir);
}
Пример #18
0
int ecparam_main(int argc, char **argv)
{
    BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
    BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
    BIO *in = NULL, *out = NULL;
    EC_GROUP *group = NULL;
    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
    char *curve_name = NULL, *inrand = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    unsigned char *buffer = NULL;
    OPTION_CHOICE o;
    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret =
        1;
    int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
    int text = 0, i, need_rand = 0, genkey = 0;

    prog = opt_init(argc, argv, ecparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(ecparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_LIST_CURVES:
            list_curves = 1;
            break;
        case OPT_NO_SEED:
            no_seed = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_NAME:
            curve_name = opt_arg();
            break;
        case OPT_CONV_FORM:
            if (!opt_pair(opt_arg(), forms, &new_form))
                goto opthelp;
            form = new_form;
            new_form = 1;
            break;
        case OPT_PARAM_ENC:
            if (!opt_pair(opt_arg(), encodings, &asn1_flag))
                goto opthelp;
            new_asn1_flag = 1;
            break;
        case OPT_GENKEY:
            genkey = need_rand = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            need_rand = 1;
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    in = bio_open_default(infile, RB(informat));
    if (in == NULL)
        goto end;
    out = bio_open_default(outfile, WB(outformat));
    if (out == NULL)
        goto end;

    if (list_curves) {
        EC_builtin_curve *curves = NULL;
        size_t crv_len = EC_get_builtin_curves(NULL, 0);
        size_t n;

        curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
        if (!EC_get_builtin_curves(curves, crv_len)) {
            OPENSSL_free(curves);
            goto end;
        }

        for (n = 0; n < crv_len; n++) {
            const char *comment;
            const char *sname;
            comment = curves[n].comment;
            sname = OBJ_nid2sn(curves[n].nid);
            if (comment == NULL)
                comment = "CURVE DESCRIPTION NOT AVAILABLE";
            if (sname == NULL)
                sname = "";

            BIO_printf(out, "  %-10s: ", sname);
            BIO_printf(out, "%s\n", comment);
        }

        OPENSSL_free(curves);
        ret = 0;
        goto end;
    }

    if (curve_name != NULL) {
        int nid;

        /*
         * workaround for the SECG curve names secp192r1 and secp256r1 (which
         * are the same as the curves prime192v1 and prime256v1 defined in
         * X9.62)
         */
        if (strcmp(curve_name, "secp192r1") == 0) {
            BIO_printf(bio_err, "using curve name prime192v1 "
                       "instead of secp192r1\n");
            nid = NID_X9_62_prime192v1;
        } else if (strcmp(curve_name, "secp256r1") == 0) {
            BIO_printf(bio_err, "using curve name prime256v1 "
                       "instead of secp256r1\n");
            nid = NID_X9_62_prime256v1;
        } else
            nid = OBJ_sn2nid(curve_name);

        if (nid == 0)
            nid = EC_curve_nist2nid(curve_name);

        if (nid == 0) {
            BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name);
            goto end;
        }

        group = EC_GROUP_new_by_curve_name(nid);
        if (group == NULL) {
            BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name);
            goto end;
        }
        EC_GROUP_set_asn1_flag(group, asn1_flag);
        EC_GROUP_set_point_conversion_form(group, form);
    } else if (informat == FORMAT_ASN1)
        group = d2i_ECPKParameters_bio(in, NULL);
    else
        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
    if (group == NULL) {
        BIO_printf(bio_err, "unable to load elliptic curve parameters\n");
        ERR_print_errors(bio_err);
        goto end;
    }

    if (new_form)
        EC_GROUP_set_point_conversion_form(group, form);

    if (new_asn1_flag)
        EC_GROUP_set_asn1_flag(group, asn1_flag);

    if (no_seed) {
        EC_GROUP_set_seed(group, NULL, 0);
    }

    if (text) {
        if (!ECPKParameters_print(out, group, 0))
            goto end;
    }

    if (check) {
        if (group == NULL)
            BIO_printf(bio_err, "no elliptic curve parameters\n");
        BIO_printf(bio_err, "checking elliptic curve parameters: ");
        if (!EC_GROUP_check(group, NULL)) {
            BIO_printf(bio_err, "failed\n");
            ERR_print_errors(bio_err);
        } else
            BIO_printf(bio_err, "ok\n");

    }

    if (C) {
        size_t buf_len = 0, tmp_len = 0;
        const EC_POINT *point;
        int is_prime, len = 0;
        const EC_METHOD *meth = EC_GROUP_method_of(group);

        if ((ec_p = BN_new()) == NULL
                || (ec_a = BN_new()) == NULL
                || (ec_b = BN_new()) == NULL
                || (ec_gen = BN_new()) == NULL
                || (ec_order = BN_new()) == NULL
                || (ec_cofactor = BN_new()) == NULL) {
            perror("Can't allocate BN");
            goto end;
        }

        is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
        if (!is_prime) {
            BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
            goto end;
        }

        if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL))
            goto end;

        if ((point = EC_GROUP_get0_generator(group)) == NULL)
            goto end;
        if (!EC_POINT_point2bn(group, point,
                               EC_GROUP_get_point_conversion_form(group),
                               ec_gen, NULL))
            goto end;
        if (!EC_GROUP_get_order(group, ec_order, NULL))
            goto end;
        if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
            goto end;

        if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor)
            goto end;

        len = BN_num_bits(ec_order);

        if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
            buf_len = tmp_len;
        if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
            buf_len = tmp_len;

        buffer = app_malloc(buf_len, "BN buffer");

        BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len);
        print_bignum_var(out, ec_p, "ec_p", len, buffer);
        print_bignum_var(out, ec_a, "ec_a", len, buffer);
        print_bignum_var(out, ec_b, "ec_b", len, buffer);
        print_bignum_var(out, ec_gen, "ec_gen", len, buffer);
        print_bignum_var(out, ec_order, "ec_order", len, buffer);
        print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer);
        BIO_printf(out, "    int ok = 0;\n"
                        "    EC_GROUP *group = NULL;\n"
                        "    EC_POINT *point = NULL;\n"
                        "    BIGNUM *tmp_1 = NULL;\n"
                        "    BIGNUM *tmp_2 = NULL;\n"
                        "    BIGNUM *tmp_3 = NULL;\n"
                        "\n");

        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n"
                        "        goto err;\n"
                        "\n");
        BIO_printf(out, "    /* build generator */\n");
        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n");
        BIO_printf(out, "    if (point == NULL)\n"
                        "        goto err;\n");
        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n"
                        "        goto err;\n", len, len);
        BIO_printf(out, "    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n"
                        "        goto err;\n"
                        "ok = 1;"
                        "\n");
        BIO_printf(out, "err:\n"
                        "    BN_free(tmp_1);\n"
                        "    BN_free(tmp_2);\n"
                        "    BN_free(tmp_3);\n"
                        "    EC_POINT_free(point);\n"
                        "    if (!ok) {\n"
                        "        EC_GROUP_free(group);\n"
                        "        return NULL;\n"
                        "    }\n"
                        "    return (group);\n"
                        "}\n");
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPKParameters_bio(out, group);
        else
            i = PEM_write_bio_ECPKParameters(out, group);
        if (!i) {
            BIO_printf(bio_err, "unable to write elliptic "
                       "curve parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (need_rand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    if (genkey) {
        EC_KEY *eckey = EC_KEY_new();

        if (eckey == NULL)
            goto end;

        assert(need_rand);

        if (EC_KEY_set_group(eckey, group) == 0)
            goto end;

        if (!EC_KEY_generate_key(eckey)) {
            EC_KEY_free(eckey);
            goto end;
        }
        if (outformat == FORMAT_ASN1)
            i = i2d_ECPrivateKey_bio(out, eckey);
        else
            i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
                                           NULL, 0, NULL, NULL);
        EC_KEY_free(eckey);
    }

    if (need_rand)
        app_RAND_write_file(NULL);

    ret = 0;
 end:
    BN_free(ec_p);
    BN_free(ec_a);
    BN_free(ec_b);
    BN_free(ec_gen);
    BN_free(ec_order);
    BN_free(ec_cofactor);
    OPENSSL_free(buffer);
    BIO_free(in);
    BIO_free_all(out);
    EC_GROUP_free(group);
    return (ret);
}
Пример #19
0
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
    EC_PKEY_CTX *dctx = ctx->data;
    EC_GROUP *group;
    switch (type) {
    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
        group = EC_GROUP_new_by_curve_name(p1);
        if (group == NULL) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
            return 0;
        }
        EC_GROUP_free(dctx->gen_group);
        dctx->gen_group = group;
        return 1;

    case EVP_PKEY_CTRL_EC_PARAM_ENC:
        if (!dctx->gen_group) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
            return 0;
        }
        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
        return 1;

#ifndef OPENSSL_NO_EC
    case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
        if (p1 == -2) {
            if (dctx->cofactor_mode != -1)
                return dctx->cofactor_mode;
            else {
                EC_KEY *ec_key = ctx->pkey->pkey.ec;
                return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
                    0;
            }
        } else if (p1 < -1 || p1 > 1)
            return -2;
        dctx->cofactor_mode = p1;
        if (p1 != -1) {
            EC_KEY *ec_key = ctx->pkey->pkey.ec;
            if (!ec_key->group)
                return -2;
            /* If cofactor is 1 cofactor mode does nothing */
            if (BN_is_one(ec_key->group->cofactor))
                return 1;
            if (!dctx->co_key) {
                dctx->co_key = EC_KEY_dup(ec_key);
                if (!dctx->co_key)
                    return 0;
            }
            if (p1)
                EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
            else
                EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
        } else {
            EC_KEY_free(dctx->co_key);
            dctx->co_key = NULL;
        }
        return 1;
#endif

    case EVP_PKEY_CTRL_EC_KDF_TYPE:
        if (p1 == -2)
            return dctx->kdf_type;
        if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
            return -2;
        dctx->kdf_type = p1;
        return 1;

#ifndef OPENSSL_NO_SM2
    case EVP_PKEY_CTRL_EC_SCHEME:
        if (p1 == -2) {
            return dctx->ec_scheme;
        }
        if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_EC_SCHEME);
            return 0;
        }
        dctx->ec_scheme = p1;
        return 1;

    case EVP_PKEY_CTRL_SIGNER_ID:
        if (!p2 || !strlen((char *)p2) || strlen((char *)p2) > SM2_MAX_ID_LENGTH) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_SIGNER_ID);
            return 0;
        } else {
            char *id = NULL;
            if (!(id = OPENSSL_strdup((char *)p2))) {
                ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            if (dctx->signer_id)
                OPENSSL_free(dctx->signer_id);
            dctx->signer_id = id;
            if (dctx->ec_scheme == NID_sm_scheme) {
                EC_KEY *ec_key = ctx->pkey->pkey.ec;
                unsigned char zid[SM3_DIGEST_LENGTH];
                size_t zidlen = SM3_DIGEST_LENGTH;
                if (!SM2_compute_id_digest(EVP_sm3(), dctx->signer_id,
                    strlen(dctx->signer_id), zid, &zidlen, ec_key)) {
                    ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB);
                    return 0;
                }
                if (!dctx->signer_zid) {
                    if (!(dctx->signer_zid = OPENSSL_malloc(zidlen))) {
                        ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
                        return 0;
                    }
                }
                memcpy(dctx->signer_zid, zid, zidlen);
            }
        }
        return 1;

    case EVP_PKEY_CTRL_GET_SIGNER_ID:
        *(const char **)p2 = dctx->signer_id;
        return 1;

    case EVP_PKEY_CTRL_GET_SIGNER_ZID:
        if (dctx->ec_scheme != NID_sm_scheme) {
            *(const unsigned char **)p2 = NULL;
            return -2;
        }
        if (!dctx->signer_zid) {
            EC_KEY *ec_key = ctx->pkey->pkey.ec;
            unsigned char *zid;
            size_t zidlen = SM3_DIGEST_LENGTH;
            if (!(zid = OPENSSL_malloc(zidlen))) {
                ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
                return 0;
            }
            if (!SM2_compute_id_digest(EVP_sm3(), SM2_DEFAULT_ID,
                SM2_DEFAULT_ID_LENGTH, zid, &zidlen, ec_key)) {
                ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB);
                OPENSSL_free(zid);
                return 0;
            }
            dctx->signer_zid = zid;
        }
        *(const unsigned char **)p2 = dctx->signer_zid;
        return 1;

    case EVP_PKEY_CTRL_EC_ENCRYPT_PARAM:
        if (p1 == -2) {
            return dctx->ec_encrypt_param;
        }
        dctx->ec_encrypt_param = p1;
        return 1;
#endif

    case EVP_PKEY_CTRL_EC_KDF_MD:
        dctx->kdf_md = p2;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_MD:
        *(const EVP_MD **)p2 = dctx->kdf_md;
        return 1;

    case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
        if (p1 <= 0)
            return -2;
        dctx->kdf_outlen = (size_t)p1;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
        *(int *)p2 = dctx->kdf_outlen;
        return 1;

    case EVP_PKEY_CTRL_EC_KDF_UKM:
        OPENSSL_free(dctx->kdf_ukm);
        dctx->kdf_ukm = p2;
        if (p2)
            dctx->kdf_ukmlen = p1;
        else
            dctx->kdf_ukmlen = 0;
        return 1;

    case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
        *(unsigned char **)p2 = dctx->kdf_ukm;
        return dctx->kdf_ukmlen;

    case EVP_PKEY_CTRL_MD:
        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
#ifndef OPENSSL_NO_SM3
            EVP_MD_type((const EVP_MD *)p2) != NID_sm3 &&
#endif
            EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
            return 0;
        }
        dctx->md = p2;
        return 1;

    case EVP_PKEY_CTRL_GET_MD:
        *(const EVP_MD **)p2 = dctx->md;
        return 1;

    case EVP_PKEY_CTRL_PEER_KEY:
        /* Default behaviour is OK */
    case EVP_PKEY_CTRL_DIGESTINIT:
    case EVP_PKEY_CTRL_PKCS7_SIGN:
    case EVP_PKEY_CTRL_CMS_SIGN:
        return 1;

    default:
        return -2;

    }
}
Пример #20
0
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
	{
	EVP_PKEY *ret=NULL;
	long j;
	int type;
	const unsigned char *p;
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
	const unsigned char *cp;
	X509_ALGOR *a;
#endif

	if (key == NULL) goto err;

	if (key->pkey != NULL)
		{
		CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
		return(key->pkey);
		}

	if (key->public_key == NULL) goto err;

	type=OBJ_obj2nid(key->algor->algorithm);
	if ((ret = EVP_PKEY_new()) == NULL)
		{
		X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
		goto err;
		}
	ret->type = EVP_PKEY_type(type);

	/* the parameters must be extracted before the public key (ECDSA!) */
	
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
	a=key->algor;
#endif

	if (0)
		;
#ifndef OPENSSL_NO_DSA
	else if (ret->type == EVP_PKEY_DSA)
		{
		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
			{
			if ((ret->pkey.dsa = DSA_new()) == NULL)
				{
				X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
				goto err;
				}
			ret->pkey.dsa->write_params=0;
			cp=p=a->parameter->value.sequence->data;
			j=a->parameter->value.sequence->length;
			if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
				goto err;
			}
		ret->save_parameters=1;
		}
#endif
#ifndef OPENSSL_NO_EC
	else if (ret->type == EVP_PKEY_EC)
		{
		if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
			{
			/* type == V_ASN1_SEQUENCE => we have explicit parameters
                         * (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
			 */
			if ((ret->pkey.ec= EC_KEY_new()) == NULL)
				{
				X509err(X509_F_X509_PUBKEY_GET, 
					ERR_R_MALLOC_FAILURE);
				goto err;
				}
			cp = p = a->parameter->value.sequence->data;
			j = a->parameter->value.sequence->length;
			if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
				{
				X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
				goto err;
				}
			}
		else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
			{
			/* type == V_ASN1_OBJECT => the parameters are given
			 * by an asn1 OID
			 */
			EC_KEY   *ec_key;
			EC_GROUP *group;

			if (ret->pkey.ec == NULL)
				ret->pkey.ec = EC_KEY_new();
			ec_key = ret->pkey.ec;
			if (ec_key == NULL)
				goto err;
			group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
			if (group == NULL)
				goto err;
			EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
			if (EC_KEY_set_group(ec_key, group) == 0)
				goto err;
			EC_GROUP_free(group);
			}
			/* the case implicitlyCA is currently not implemented */
		ret->save_parameters = 1;
		}
#endif

	p=key->public_key->data;
        j=key->public_key->length;
        if (!d2i_PublicKey(type, &ret, &p, (long)j))
		{
		X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
		goto err;
		}

	key->pkey = ret;
	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
	return(ret);
err:
	if (ret != NULL)
		EVP_PKEY_free(ret);
	return(NULL);
	}
Пример #21
0
void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
	{
	if (key->group != NULL)
		EC_GROUP_set_asn1_flag(key->group, flag);
	}
Пример #22
0
int main(int argc, char **argv)
{
	int r, i;
	KDF_FUNC kdf = NULL;
	EC_GROUP *ec_group = NULL;
	EC_KEY *ec_key = NULL;
	EVP_PKEY *pkey = NULL;
	EVP_PKEY *pub_key = NULL;
	EVP_PKEY *priv_key = NULL;
	X509_ALGOR *map = NULL;
	CPK_MASTER_SECRET *master = NULL;
	CPK_PUBLIC_PARAMS *params = NULL;
	BIO *bio_out = NULL;
	unsigned char *buf = NULL;
	unsigned char *p;
	const unsigned char *cp;
	int len;

	/* init openssl global functions */
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	/* prepare cpk setup parameters */
	ec_key = EC_KEY_new_by_curve_name(OBJ_sn2nid("prime192v1"));
	assert(ec_key != NULL);

	EC_GROUP_set_asn1_flag((EC_GROUP *)EC_KEY_get0_group(ec_key), OPENSSL_EC_NAMED_CURVE);
	r = EC_KEY_generate_key(ec_key);
	assert(r == 1);

	pkey = EVP_PKEY_new();
	assert(pkey != NULL);
	r = EVP_PKEY_set1_EC_KEY(pkey, ec_key);
	assert(r == 1);
	map = CPK_MAP_new_default();
	assert(map != NULL);


	//EVP_PKEY_print_fp(pkey, stdout);

	/* generate master_secret and public_params */
	master = CPK_MASTER_SECRET_create("domainid", pkey, map);
	OPENSSL_assert(master);

	bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
	OPENSSL_assert(bio_out);

	r = CPK_MASTER_SECRET_print(bio_out, master, 0, 0);
	assert(r == 1);

	EVP_PKEY_free(pkey);
	pkey = NULL;
	pkey = CPK_MASTER_SECRET_extract_private_key(master, "id");
	assert(pkey != NULL);
	EVP_PKEY_free(pkey);
	//pkey = CPK_MASTER_SECRET_extract_private_key(master, NULL);
	//assert(pkey == NULL);
	pkey = CPK_MASTER_SECRET_extract_private_key(master, id_long);
	assert(pkey != NULL);
	printf("EVP_PKEY of '%s':\n", id_long);
	EVP_PKEY_print_fp(pkey, stdout);
	printf("\n");
	
	params = CPK_MASTER_SECRET_extract_public_params(master);
	assert(params);
	r = CPK_PUBLIC_PARAMS_print(bio_out, params, 0, 0);
	assert(r == 1);
	printf("\n");

	printf("test CPK_PUBLIC_PARAMS_extract_public_key()\n");
	pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_short);
	assert(pub_key != NULL);
	EVP_PKEY_free(pub_key);

	pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id_long);
	assert(pub_key != NULL);
	printf("Public Key of '%s':\n", id_long);
	EVP_PKEY_print_fp(pkey, stdout);
	printf("\n");

	
	r = CPK_MASTER_SECRET_validate_public_params(master, params);
	assert(r == 1);
	if (priv_key) EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "identity");
	assert(priv_key);
	r = CPK_PUBLIC_PARAMS_validate_private_key(params, "identity", priv_key);
	assert(r == 1);
	r = CPK_PUBLIC_PARAMS_validate_private_key(params, "id", priv_key);
	assert(r == 0);

	/* der encoding and decoding */
	len = i2d_CPK_MASTER_SECRET(master, NULL);
	assert(len > 0);
	if (buf != NULL) OPENSSL_free(buf);
	buf = OPENSSL_malloc(len);
	assert(buf != NULL);
	p = buf;
	len = i2d_CPK_MASTER_SECRET(master, &p);
	assert(len > 0);
	assert(p - buf == len);

	cp = buf;
	if (master) CPK_MASTER_SECRET_free(master);
	master = NULL;
	master = d2i_CPK_MASTER_SECRET(NULL, &cp, len);
	assert(master != NULL);
	r = CPK_MASTER_SECRET_validate_public_params(master, params);
	assert(r == 1);

	kdf = KDF_get_x9_63(EVP_sha1());
	assert(kdf != NULL);


	if (priv_key != NULL) EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Alice");
	assert(priv_key != NULL);

	if (buf != NULL) OPENSSL_free(buf);
	buf = OPENSSL_malloc(1024);
	assert(buf != NULL);
	r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Bob", priv_key, kdf);
	for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n");

	if (priv_key != NULL)
		EVP_PKEY_free(priv_key);
	priv_key = CPK_MASTER_SECRET_extract_private_key(master, "Bob");
	assert(priv_key != NULL);
	r = CPK_PUBLIC_PARAMS_compute_share_key(params, buf, 64, "Alice", priv_key, kdf);
	for (i = 0; i < 64; i++) printf("%02x", buf[i]); printf("\n");


	printf("ok\n");
	
	return 0;
}