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; }
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; }
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); }
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; }
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(); }
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; }
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; }
/* * 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; }
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); } } }
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; }
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); }
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; } }
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; }
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; }
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); }
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); }
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; } }
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); }
void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) { if (key->group != NULL) EC_GROUP_set_asn1_flag(key->group, flag); }
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; }