int CPK_MAP_str2index(const X509_ALGOR *algor, const char *str, int *index) { int ret = 0; const EVP_MD *md; unsigned char dgst[EVP_MAX_MD_SIZE]; unsigned int dgstlen; BIGNUM *bn = NULL; int i, num_index, num_subset; OPENSSL_assert(algor); OPENSSL_assert(algor->algorithm); OPENSSL_assert(str); OPENSSL_assert(strlen(str) > 0); if (!CPK_MAP_is_valid(algor)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, CPK_R_INVALID_MAP_ALGOR); goto err; } if (!index) { ret = CPK_MAP_num_index(algor); goto err; } if (!(md = EVP_get_digestbyobj(algor->algorithm))) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_EVP_LIB); goto err; } if (!EVP_Digest(str, strlen(str), dgst, &dgstlen, md, NULL)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_EVP_LIB); return 0; } if (!(bn = BN_new())) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_BN_LIB); goto err; } if (!BN_bin2bn(dgst, dgstlen, bn)) { CPKerr(CPK_F_CPK_MAP_STR2INDEX, ERR_R_BN_LIB); goto err; } num_index = CPK_MAP_num_index(algor); num_subset = CPK_MAP_num_subset(algor); for (i = 0; i < num_index; i++) { int r = BN_mod_word(bn, num_subset); index[i] = num_subset * i + r; } ret = num_index; err: if (bn) BN_free(bn); return ret; }
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; }
static DSA *X509_ALGOR_get1_DSA(X509_ALGOR *algor) { DSA *dsa = NULL; int ptype; void *pval; ASN1_OCTET_STRING *pstr; const unsigned char *p; X509_ALGOR_get0(NULL, &ptype, &pval, algor); if (ptype != V_ASN1_SEQUENCE) { CPKerr(CPK_F_X509_ALGOR_GET1_DSA, CPK_R_BAD_DATA); return NULL; } pstr = (ASN1_OCTET_STRING *)pval; p = pstr->data; if (!(dsa = d2i_DSAparams(NULL, &p, pstr->length))) { CPKerr(CPK_F_X509_ALGOR_GET1_DSA, ERR_R_DSA_LIB); return NULL; } return dsa; }
int CPK_PUBLIC_PARAMS_compute_share_key(CPK_PUBLIC_PARAMS *params, void *out, size_t outlen, const char *id, EVP_PKEY *priv_key, void *(*kdf)(const void *in, size_t inlen, void *out, size_t *outlen)) { int ret = 0; EVP_PKEY *pub_key = NULL; int pkey_type = OBJ_obj2nid(params->pkey_algor->algorithm); OPENSSL_assert(kdf != NULL); printf("%d\n", __LINE__); if (EVP_PKEY_id(priv_key) != pkey_type) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_COMPUTE_SHARE_KEY, ERR_R_MALLOC_FAILURE); //FIXME: ERR_R_XXX goto err; } if (!(pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_COMPUTE_SHARE_KEY, ERR_R_MALLOC_FAILURE); //FIXME: ERR_R_XXX goto err; } if (pkey_type == EVP_PKEY_EC) { if (!ECDH_compute_key(out, outlen, EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0(pub_key)), (EC_KEY *)EVP_PKEY_get0(priv_key), kdf)) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_COMPUTE_SHARE_KEY, ERR_R_MALLOC_FAILURE); //FIXME: ERR_R_XXX goto err; } } else if (pkey_type == EVP_PKEY_DH) { // not supported yet goto err; } ret = 1; err: return ret; }
X509_ALGOR *CPK_MAP_new_default() { X509_ALGOR *algor = NULL; const EVP_MD *md = EVP_sha1(); if (md != EVP_sha1() && md != EVP_sha384()) { CPKerr(CPK_F_CPK_MAP_NEW_DEFAULT, CPK_R_BAD_ARGUMENT); goto end; } if (!(algor = X509_ALGOR_new())) { CPKerr(CPK_F_CPK_MAP_NEW_DEFAULT, ERR_R_X509_LIB); goto end; } if (!X509_ALGOR_set0(algor, OBJ_nid2obj(EVP_MD_nid(md)), V_ASN1_UNDEF, NULL)) { X509_ALGOR_free(algor); algor = NULL; CPKerr(CPK_F_CPK_MAP_NEW_DEFAULT, ERR_R_X509_LIB); goto end; } end: return algor; }
int CPK_PUBLIC_PARAMS_validate_private_key(CPK_PUBLIC_PARAMS *params, const char *id, const EVP_PKEY *priv_key) { int ret = -3; EVP_PKEY *pub_key = NULL; if (!(pub_key = CPK_PUBLIC_PARAMS_extract_public_key(params, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_VALIDATE_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } ret = EVP_PKEY_cmp(pub_key, priv_key); err: if (pub_key) EVP_PKEY_free(pub_key); return ret; }
CPK_MASTER_SECRET *CPK_MASTER_SECRET_create(const char *domain_id, EVP_PKEY *pkey, X509_ALGOR *map_algor) { int e = 1; CPK_MASTER_SECRET *master = NULL; BIGNUM *bn = NULL, *order = NULL; X509_PUBKEY *pubkey = NULL; int pkey_type; int i, bn_size, num_factors; unsigned char *bn_ptr; if (strlen(domain_id) <= 0 || strlen(domain_id) > CPK_MAX_ID_LENGTH) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, CPK_R_INVALID_ID_LENGTH); goto err; } pkey_type = EVP_PKEY_id(pkey); if (pkey_type == EVP_PKEY_DSA) { if (!(order = ((DSA *)EVP_PKEY_get0(pkey))->q)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, CPK_R_BAD_ARGUMENT); goto err; } } else if (pkey_type == EVP_PKEY_EC) { const EC_GROUP *ec_group; if (!(order = BN_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_MALLOC_FAILURE); goto err; } ec_group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0(pkey)); if (!EC_GROUP_get_order(ec_group, order, NULL)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_X509_LIB); goto err; } //FIXME OPENSSL_assert assert(EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0(pkey)) != NULL); } else { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, CPK_R_INVALID_PKEY_TYPE); goto err; } if (!(master = CPK_MASTER_SECRET_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_MALLOC_FAILURE); goto err; } master->version = 1; if (!X509_NAME_add_entry_by_NID(master->id, NID_organizationName, MBSTRING_UTF8, (unsigned char *)domain_id, -1, -1, 0)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_X509_LIB); goto err; } /* * convert EVP_PKEY to X509_ALGOR through X509_PUBKEY_set * X509_ALGOR_set0() is another choice but require more code */ // FIXME: X509_PUBKEY require pkey has a public key if (!X509_PUBKEY_set(&pubkey, pkey)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_X509_LIB); goto err; } X509_ALGOR_free(master->pkey_algor); if (!(master->pkey_algor = X509_ALGOR_dup(pubkey->algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_X509_LIB); goto err; } //FIXME: check the validity of CPK_MAP X509_ALGOR_free(master->map_algor); if (!(master->map_algor = X509_ALGOR_dup(map_algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_MALLOC_FAILURE); goto err; } if ((num_factors = CPK_MAP_num_factors(map_algor)) <= 0) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, CPK_R_INVALID_MAP_ALGOR); goto err; } /* * create secret factors, for both DSA and EC, * the private keys are both big integers, */ bn_size = BN_num_bytes(order); if (!ASN1_STRING_set(master->secret_factors, NULL, bn_size * num_factors)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_ASN1_LIB); goto err; } bn_ptr = M_ASN1_STRING_data(master->secret_factors); memset(bn_ptr, 0, M_ASN1_STRING_length(master->secret_factors)); if (!(bn = BN_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_MALLOC_FAILURE); goto err; } for (i = 0; i < num_factors; i++) { do { if (!BN_rand_range(bn, order)) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_RAND_LIB); goto err; } } while (BN_is_zero(bn)); if (!BN_bn2bin(bn, bn_ptr + bn_size - BN_num_bytes(bn))) { CPKerr(CPK_F_CPK_MASTER_SECRET_CREATE, ERR_R_BN_LIB); goto err; } bn_ptr += bn_size; } e = 0; err: if (e && master) { CPK_MASTER_SECRET_free(master); master = NULL; } if (pubkey) X509_PUBKEY_free(pubkey); if (order && pkey_type == EVP_PKEY_EC) BN_free(order); if (bn) BN_free(bn); return master; }
EVP_PKEY *CPK_PUBLIC_PARAMS_extract_public_key(CPK_PUBLIC_PARAMS *param, const char *id) { EVP_PKEY *pkey = NULL; int pkey_type; //char domain_id[CPK_MAX_ID_LENGTH + 1]; if (!(pkey = EVP_PKEY_new())) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_MALLOC_FAILURE); goto err; } pkey_type = OBJ_obj2nid(param->pkey_algor->algorithm); if (pkey_type == EVP_PKEY_DSA) { DSA *dsa = NULL; if (!(dsa = extract_dsa_pub_key(param, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { DSA_free(dsa); CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_EVP_LIB); goto err; } } else if (pkey_type == EVP_PKEY_EC) { EC_KEY *ec_key = NULL; if (!(ec_key = extract_ec_pub_key(param, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { EC_KEY_free(ec_key); CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_EVP_LIB); goto err; } } else { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, CPK_R_INVALID_PKEY_TYPE); goto err; } /* * add id to EVP_PKEY attributes */ /* if(!X509_NAME_get_text_by_NID(param->id, NID_organizationName, domain_id, sizeof(domain_id) - 1)) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_organizationName, MBSTRING_UTF8, (const unsigned char *)domain_id, strlen(domain_id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_commonName, MBSTRING_UTF8, (const unsigned char *)id, strlen(id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } */ return pkey; err: if (pkey) EVP_PKEY_free(pkey); return NULL; }
EVP_PKEY *CPK_MASTER_SECRET_extract_private_key( CPK_MASTER_SECRET *master, const char *id) { EVP_PKEY *pkey = NULL; int pkey_type; if (!(pkey = EVP_PKEY_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); goto err; } pkey_type = OBJ_obj2nid(master->pkey_algor->algorithm); if (pkey_type == EVP_PKEY_DSA) { DSA *dsa; if (!(dsa = extract_dsa_priv_key(master, id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { DSA_free(dsa); CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } } else if (pkey_type == EVP_PKEY_EC) { EC_KEY *ec_key; if (!(ec_key = extract_ec_priv_key(master, id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { EC_KEY_free(ec_key); CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } } else { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, CPK_R_INVALID_PKEY_TYPE); goto err; } /* * add id to EVP_PKEY attributes */ /* if(!X509_NAME_get_text_by_NID(master->id, NID_organizationName, domain_id, sizeof(domain_id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_organizationName, V_ASN1_PRINTABLESTRING, (const unsigned char *)domain_id, strlen(domain_id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_commonName, V_ASN1_PRINTABLESTRING, (const unsigned char *)id, strlen(id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } */ return pkey; err: if (pkey) EVP_PKEY_free(pkey); return NULL; }
CPK_PUBLIC_PARAMS *CPK_MASTER_SECRET_extract_public_params(CPK_MASTER_SECRET *master) { CPK_PUBLIC_PARAMS *param = NULL; int pkey_type; pkey_type = OBJ_obj2nid(master->pkey_algor->algorithm); if (!(param = CPK_PUBLIC_PARAMS_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } param->version = master->version; X509_NAME_free(param->id); if (!(param->id = X509_NAME_dup(master->id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } X509_ALGOR_free(param->pkey_algor); if (!(param->pkey_algor = X509_ALGOR_dup(master->pkey_algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } X509_ALGOR_free(param->map_algor); if (!(param->map_algor = X509_ALGOR_dup(master->map_algor))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_MALLOC_FAILURE); goto err; } switch (pkey_type) { case EVP_PKEY_DSA: if (!extract_dsa_params(master, param)) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_CPK_LIB); goto err; } break; case EVP_PKEY_EC: if (!extract_ec_params(master, param)) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, ERR_R_CPK_LIB); goto err; } break; default: CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS, CPK_R_INVALID_PKEY_TYPE); goto err; } return param; err: if (param) CPK_PUBLIC_PARAMS_free(param); return NULL; }