Ejemplo n.º 1
0
Archivo: gost_pmeth.c Proyecto: 5y/node
/* Allocates new gost_pmeth_data structure and assigns it as data */
static int pkey_gost_init(EVP_PKEY_CTX *ctx)
{
    struct gost_pmeth_data *data;
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
    data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
    if (!data)
        return 0;
    memset(data, 0, sizeof(struct gost_pmeth_data));
    if (pkey && EVP_PKEY_get0(pkey)) {
        switch (EVP_PKEY_base_id(pkey)) {
        case NID_id_GostR3410_94:
            data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey));
            break;
        case NID_id_GostR3410_2001:
            data->sign_param_nid =
                EC_GROUP_get_curve_name(EC_KEY_get0_group
                                        (EVP_PKEY_get0((EVP_PKEY *)pkey)));
            break;
        default:
            return 0;
        }
    }
    EVP_PKEY_CTX_set_data(ctx, data);
    return 1;
}
Ejemplo n.º 2
0
/*
 * EVP_PKEY_METHOD callback derive.
 * Implements VKO R 34.10-2001/2012 algorithms
 */
int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
    /*
     * Public key of peer in the ctx field peerkey
     * Our private key in the ctx pkey
     * ukm is in the algorithm specific context data
     */
    EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
    EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
    struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
    int dgst_nid = NID_undef;

    if (!data || !data->shared_ukm) {
        GOSTerr(GOST_F_PKEY_GOST_EC_DERIVE, GOST_R_UKM_NOT_SET);
        return 0;
    }

    if (key == NULL) {
        *keylen = 32;
        return 32;
    }

    EVP_PKEY_get_default_digest_nid(my_key, &dgst_nid);

    *keylen =
        VKO_compute_key(key, 32,
                        EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
                        (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm,
                        dgst_nid);
    return (*keylen) ? 1 : 0;
}
Ejemplo n.º 3
0
int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
{
    EVP_PKEY *pkey;
    int i;
    if (ri->type == CMS_RECIPINFO_TRANS)
        pkey = ri->d.ktri->pkey;
    else if (ri->type == CMS_RECIPINFO_AGREE) {
        EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
        if (!pctx)
            return 0;
        pkey = EVP_PKEY_CTX_get0_pkey(pctx);
        if (!pkey)
            return 0;
    } else
        return 0;
    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
        return 1;
    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
    if (i == -2) {
        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
        return 0;
    }
    if (i <= 0) {
        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
        return 0;
    }
    return 1;
}
Ejemplo n.º 4
0
soter_status_t soter_asym_ka_export_key(soter_asym_ka_t* asym_ka_ctx,
                                        void* key,
                                        size_t* key_length,
                                        bool isprivate)
{
    EVP_PKEY* pkey;

    if (!asym_ka_ctx) {
        return SOTER_INVALID_PARAMETER;
    }

    pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx);

    if (!pkey) {
        return SOTER_INVALID_PARAMETER;
    }

    if (EVP_PKEY_EC != EVP_PKEY_id(pkey)) {
        return SOTER_INVALID_PARAMETER;
    }

    if (isprivate) {
        return soter_engine_specific_to_ec_priv_key((const soter_engine_specific_ec_key_t*)pkey,
                                                    (soter_container_hdr_t*)key,
                                                    key_length);
    }

    return soter_engine_specific_to_ec_pub_key((const soter_engine_specific_ec_key_t*)pkey,
                                               (soter_container_hdr_t*)key,
                                               key_length);
}
Ejemplo n.º 5
0
// Argh! This is one more of these OpenSSL-style schizophrenic APIs, where
// depending on whether a parameter is NULL or not, different values are
// expected...
static int bcrypt_derive(EVP_PKEY_CTX *ctx, unsigned char *outKey, size_t *outKeyLen)
{
  *outKeyLen = X25519_KEYLEN;

  // First usage: a query for how many bytes the caller needs to allocate.
  if (outKey == NULL)
    return 1;

  // Second usage: writing into outkey the derived secret.

  // Note: this does NOT give you the actual bytes for the SECRET_HANDLE. (See
  // http://stackoverflow.com/questions/87694/im-using-wincrypt-for-diffie-hellman-can-i-export-the-shared-secret-in-plain
  // for something vaguely related). BCryptExportKey works for a KEY_HANDLE, not
  // a SECRET_HANDLE... and the type is defined as void* in the public Windows
  // 10 headers.
  bcrypt_x25519_key *pkey = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
  bcrypt_x25519_key *peerkey = EVP_PKEY_get0(EVP_PKEY_CTX_get0_peerkey(ctx));
  BCRYPT_SECRET_HANDLE hSecret = NULL;
  if (!NT_SUCCESS(BCryptSecretAgreement(pkey->pair, peerkey->pair, &hSecret, 0))) {
    fprintf(stderr, "Cannot compute agreement\n");
    return 0;
  }
  // Writing out a dummy value in the meanwhile...
  memset(outKey, 0, X25519_KEYLEN);

  return 1;
}
Ejemplo n.º 6
0
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
	{
	struct gost_mac_pmeth_data *data =
(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);

	switch (type)
		{
		case EVP_PKEY_CTRL_MD:
		{
		if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC)
			{
			GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE);
			return 0;
			}
		data->md = (EVP_MD *)p2;
		return 1;
		}
		break;

		case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
		case EVP_PKEY_CTRL_PKCS7_DECRYPT:
		case EVP_PKEY_CTRL_PKCS7_SIGN:
			return 1;
		case EVP_PKEY_CTRL_SET_MAC_KEY:
			if (p1 != 32) 
				{
				GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
					GOST_R_INVALID_MAC_KEY_LENGTH);
				return 0;
				}

			memcpy(data->key,p2,32);
			data->key_set = 1;
			return 1;
		case EVP_PKEY_CTRL_DIGESTINIT:
			{ 
			EVP_MD_CTX *mctx = p2;
			void *key;
			if (!data->key_set)
				{ 
				EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
				if (!pkey) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				key = EVP_PKEY_get0(pkey);
				if (!key) 
					{
					GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET);
					return 0;
					}
				} else {
				key = &(data->key);
				}
			return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key);
			}  
		}	
	return -2;
	}
Ejemplo n.º 7
0
soter_status_t soter_asym_ka_gen_key(soter_asym_ka_t* asym_ka_ctx)
{
    EVP_PKEY* pkey;
    EC_KEY* ec;

    if (!asym_ka_ctx) {
        return SOTER_INVALID_PARAMETER;
    }

    pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx);

    if (!pkey) {
        return SOTER_INVALID_PARAMETER;
    }

    if (EVP_PKEY_EC != EVP_PKEY_id(pkey)) {
        return SOTER_INVALID_PARAMETER;
    }

    ec = EVP_PKEY_get0_EC_KEY(pkey);
    if (NULL == ec) {
        return SOTER_INVALID_PARAMETER;
    }

    if (1 == EC_KEY_generate_key(ec)) {
        return SOTER_SUCCESS;
    }

    return SOTER_FAIL;
}
Ejemplo n.º 8
0
/* Allocates new gost_pmeth_data structure and assigns it as data */
static int pkey_gost_init(EVP_PKEY_CTX *ctx)
{
    struct gost_pmeth_data *data;
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);

    data = OPENSSL_malloc(sizeof(*data));
    if (!data)
        return 0;
    memset(data, 0, sizeof(*data));
    if (pkey && EVP_PKEY_get0(pkey)) {
        switch (EVP_PKEY_base_id(pkey)) {
        case NID_id_GostR3410_2001:
        case NID_id_GostR3410_2012_256:
        case NID_id_GostR3410_2012_512:
            {
                const EC_GROUP *group =
                    EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey));
                if (group != NULL) {
                    data->sign_param_nid = EC_GROUP_get_curve_name(group);
                    break;
                }
                /* else */
            }
        default:
            OPENSSL_free(data);
            return 0;
        }
    }
    EVP_PKEY_CTX_set_data(ctx, data);
    return 1;
}
Ejemplo n.º 9
0
/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding
 * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */
static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
  const EVP_MD *sigmd, *mgf1md;
  RSA_PSS_PARAMS *pss = NULL;
  ASN1_STRING *os = NULL;
  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
  int saltlen, rv = 0;

  if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) ||
      !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) ||
      !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) {
    goto err;
  }

  if (saltlen == -1) {
    saltlen = EVP_MD_size(sigmd);
  } else if (saltlen == -2) {
    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
      saltlen--;
    }
  } else {
    goto err;
  }

  pss = RSA_PSS_PARAMS_new();
  if (!pss) {
    goto err;
  }

  if (saltlen != 20) {
    pss->saltLength = ASN1_INTEGER_new();
    if (!pss->saltLength ||
        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
      goto err;
    }
  }

  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
    goto err;
  }

  /* Finally create string with pss parameter encoding. */
  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
    goto err;
  }
  rv = 1;

err:
  if (pss) {
    RSA_PSS_PARAMS_free(pss);
  }
  if (rv) {
    return os;
  }
  if (os) {
    ASN1_STRING_free(os);
  }
  return NULL;
}
Ejemplo n.º 10
0
static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
                                size_t *siglen, const unsigned char *tbs,
                                size_t tbs_len)
{
    DSA_SIG *unpacked_sig = NULL;
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
    int order = 0;

    if (!siglen)
        return 0;
    if (!pkey)
        return 0;

    switch (EVP_PKEY_base_id(pkey)) {
    case NID_id_GostR3410_2001:
    case NID_id_GostR3410_2012_256:
        order = 64;
        break;
    case NID_id_GostR3410_2012_512:
        order = 128;
        break;
    default:
        return 0;
    }

    if (!sig) {
        *siglen = order;
        return 1;
    }
    unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey));
    if (!unpacked_sig) {
        return 0;
    }
    return pack_sign_cp(unpacked_sig, order / 2, sig, siglen);
}
Ejemplo n.º 11
0
static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
    EVP_PKEY *pk;
    ASN1_OCTET_STRING *key;
    switch (type) {

    case EVP_PKEY_CTRL_SET_MAC_KEY:
        if ((!p2 && p1 > 0) || (p1 < -1))
            return 0;
        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
            return 0;
        break;

    case EVP_PKEY_CTRL_MD:
        hctx->md = p2;
        break;

    case EVP_PKEY_CTRL_DIGESTINIT:
        pk = EVP_PKEY_CTX_get0_pkey(ctx);
        key = EVP_PKEY_get0(pk);
        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL))
            return 0;
        break;

    default:
        return -2;

    }
    return 1;
}
Ejemplo n.º 12
0
static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
{
    ASN1_OBJECT *aoid;
    int atype;
    void *aval;
    ASN1_INTEGER *public_key = NULL;
    int rv = 0;
    EVP_PKEY *pkpeer = NULL, *pk = NULL;
    DH *dhpeer = NULL;
    const unsigned char *p;
    int plen;

    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
        goto err;
    /* Only absent parameters allowed in RFC XXXX */
    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
        goto err;

    pk = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!pk)
        goto err;
    if (pk->type != EVP_PKEY_DHX)
        goto err;
    /* Get parameters from parent key */
    dhpeer = DHparams_dup(pk->pkey.dh);
    /* We have parameters now set public key */
    plen = ASN1_STRING_length(pubkey);
    p = ASN1_STRING_data(pubkey);
    if (!p || !plen)
        goto err;

    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
        goto err;
    }

    /* We have parameters now set public key */
    if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
        goto err;
    }

    pkpeer = EVP_PKEY_new();
    if (!pkpeer)
        goto err;
    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
    dhpeer = NULL;
    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
        rv = 1;
 err:
    if (public_key)
        ASN1_INTEGER_free(public_key);
    if (pkpeer)
        EVP_PKEY_free(pkpeer);
    if (dhpeer)
        DH_free(dhpeer);
    return rv;
}
Ejemplo n.º 13
0
/*
 * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001
 * algorithm
 */
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
                         size_t *keylen)
{
    /*
     * Public key of peer in the ctx field peerkey Our private key in the ctx
     * pkey ukm is in the algorithm specific context data
     */
    EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
    EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
    struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);

    if (!data->shared_ukm) {
        GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
        return 0;
    }

    if (key == NULL) {
        *keylen = 32;
        return 32;
    }

    *keylen =
        VKO_compute_key(key, 32,
                        EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
                        (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm);
    return 1;
}
Ejemplo n.º 14
0
soter_status_t soter_ec_gen_key(EVP_PKEY_CTX *pkey_ctx)
{
  EVP_PKEY *pkey;
  EC_KEY *ec=NULL;
  if (!pkey_ctx){
    return SOTER_INVALID_PARAMETER;
  }
  pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx);
  if (!pkey){
    return SOTER_INVALID_PARAMETER;
  }
  if (EVP_PKEY_EC != EVP_PKEY_id(pkey)){
    return SOTER_INVALID_PARAMETER;
  }
  /* ec = EVP_PKEY_get0_EC_KEY(pkey); */
  /* if (NULL == ec){ */
  /*   return SOTER_INVALID_PARAMETER; */
  /* } */
  ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  if(!ec){
    return SOTER_ENGINE_FAIL;
  }
  if (!EC_KEY_generate_key(ec)){
    return SOTER_ENGINE_FAIL;
  }
  if(!EVP_PKEY_set1_EC_KEY(pkey, ec)){
    return SOTER_ENGINE_FAIL;
  }
  EC_KEY_free(ec);
  return SOTER_SUCCESS;
}
int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen)
	{
		EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
		EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
		*keylen = 32;
		if (key == NULL) return 1;

		return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
	}
Ejemplo n.º 16
0
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
				X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
	{
	ASN1_OBJECT *aoid;
	int atype;
	void *aval;
	int rv = 0;
	EVP_PKEY *pkpeer = NULL;
	EC_KEY *ecpeer = NULL;
	const unsigned char *p;
	int plen;
	X509_ALGOR_get0(&aoid, &atype, &aval, alg);
	if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
		goto err;
	/* If absent parameters get group from main key */
	if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL)
		{
		const EC_GROUP *grp;
		EVP_PKEY *pk;
		pk = EVP_PKEY_CTX_get0_pkey(pctx);
		if (!pk)
			goto err;
		grp = EC_KEY_get0_group(pk->pkey.ec);
		ecpeer = EC_KEY_new();
		if (!ecpeer)
			goto err;
		if (!EC_KEY_set_group(ecpeer, grp))
			goto err;
		}
	else
		{
		ecpeer = eckey_type2param(atype, aval);
		if (!ecpeer)
			goto err;
		}
	/* We have parameters now set public key */
	plen = ASN1_STRING_length(pubkey);
	p = ASN1_STRING_data(pubkey);
	if (!p || !plen)
		goto err;
	if (!o2i_ECPublicKey(&ecpeer, &p, plen))
		goto err;
	pkpeer = EVP_PKEY_new();
	if (!pkpeer)
		goto err;
	EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
	if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
		rv = 1;
	err:
	if (ecpeer)
		EC_KEY_free(ecpeer);
	if (pkpeer)
		EVP_PKEY_free(pkpeer);
	return rv;
	}
Ejemplo n.º 17
0
int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
  const EVP_MD *sigmd, *mgf1md;
  int saltlen;
  if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) ||
      !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) ||
      !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) {
    return 0;
  }

  EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
  if (saltlen == -1) {
    saltlen = EVP_MD_size(sigmd);
  } else if (saltlen == -2) {
    saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
    if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
      saltlen--;
    }
  } else {
    return 0;
  }

  int ret = 0;
  ASN1_STRING *os = NULL;
  RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new();
  if (!pss) {
    goto err;
  }

  if (saltlen != 20) {
    pss->saltLength = ASN1_INTEGER_new();
    if (!pss->saltLength ||
        !ASN1_INTEGER_set(pss->saltLength, saltlen)) {
      goto err;
    }
  }

  if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) ||
      !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) {
    goto err;
  }

  /* Finally create string with pss parameter encoding. */
  if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) {
    goto err;
  }

  X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
  os = NULL;
  ret = 1;

err:
  RSA_PSS_PARAMS_free(pss);
  ASN1_STRING_free(os);
  return ret;
}
Ejemplo n.º 18
0
static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
	{
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
	if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
	}
Ejemplo n.º 19
0
static int
pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
	struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);

	switch (type) {
	case EVP_PKEY_CTRL_MD:
		if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) {
			GOSTerror(GOST_R_INVALID_DIGEST_TYPE);
			return 0;
		}
		data->md = p2;
		return 1;

	case EVP_PKEY_CTRL_SET_MAC_KEY:
		if (p1 != 32) {
			GOSTerror(GOST_R_INVALID_MAC_KEY_LENGTH);
			return 0;
		}

		memcpy(data->key, p2, 32);
		data->key_set = 1;
		return 1;

	case EVP_PKEY_CTRL_DIGESTINIT:
	    {
		EVP_MD_CTX *mctx = p2;
		void *key;

		if (!data->key_set) {
			EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
			if (pkey == NULL) {
				GOSTerror(GOST_R_MAC_KEY_NOT_SET);
				return 0;
			}
			key = EVP_PKEY_get0(pkey);
			if (key == NULL) {
				GOSTerror(GOST_R_MAC_KEY_NOT_SET);
				return 0;
			}
		} else {
			key = &(data->key);
		}
		if (mctx->digest->md_ctrl == NULL)
			return 0;
		return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32 * 8,
		    key);
	    }

	}

	return -2;
}
Ejemplo n.º 20
0
static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
    MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
    ASN1_OCTET_STRING *key = NULL;
    int rv = 1;
    /*
     * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that
     * gets the key passed as an ASN.1 OCTET STRING, we set the key here,
     * as this may be only time it's set during a DigestSign.
     *
     * MACs that pass around the key in form of EVP_MAC_CTX are setting
     * the key through other mechanisms.  (this is only CMAC for now)
     */
    int set_key =
        hctx->type == MAC_TYPE_RAW
        && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;

    if (set_key) {
        if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))
            != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx)))
            return 0;
        key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx));
        if (key == NULL)
            return 0;
    }

    /* Some MACs don't support this control...  that's fine */
    EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS,
                 EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));

    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
    EVP_MD_CTX_set_update_fn(mctx, int_update);

    if (set_key)
        rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data,
                          key->length);
    return rv > 0;
}
Ejemplo n.º 21
0
soter_status_t soter_asym_ka_cleanup(soter_asym_ka_t* asym_ka_ctx)
{
	if (!asym_ka_ctx)
	{
		return SOTER_INVALID_PARAMETER;
	}
	if (asym_ka_ctx->pkey_ctx)
	{
		EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx);
		if(pkey)EVP_PKEY_free(pkey);
		EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx);
	}
	return SOTER_SUCCESS;
}
Ejemplo n.º 22
0
//We can control the state of our engine by commands
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
    struct te_mac_pmeth_data *data = (struct te_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
    switch (type) {
    case EVP_PKEY_CTRL_MD:
        if (EVP_MD_type((const EVP_MD *)p2) != NID_hmac_sha1) {
            printf("Error: unsupported digest type\n");
            return 0;
        }
        data->md = (EVP_MD*)p2;
        return 1;
    case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
    case EVP_PKEY_CTRL_PKCS7_DECRYPT:
    case EVP_PKEY_CTRL_PKCS7_SIGN:
        return 1;
    case EVP_PKEY_CTRL_SET_MAC_KEY:                             //here we can insert pkey extraction
        printf("Got set user id command: %s\n", (char*)p2);     //or save user id for further operations
        if(strcmp((char*)p2, "123")) {
            printf("Error: unknown user (id = %s)\n", (char*)p2);
            return 0;
        }
        memcpy(data->uid, p2, p1);
        memcpy(data->key, "user_123_key\0", 13);
        data->key_ln = 12;
        data->key_set = 1;
        return 1;
    case EVP_PKEY_CTRL_DIGESTINIT: {                            //this request runs in different context (for unknown reason)
        printf("Got digest init command\n");                    //but has the key that we have installed in keygen request
        void *key = 0;                                          //in this request we must transfer the key into digest context
        int keyln = 0;                                          //so digest must support control commands
        if(!data->key_set) {
            EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
            if (!pkey) {
                printf("Error: unable to set key\n");
                return 0;
            }
            key = EVP_PKEY_get0(pkey);
            if (!key) {
                printf("Error: unable to set key\n");
                return 0;
            }
            keyln = strlen((char *)key);    //it's so dangerous
        } else {
            key = &(data->key);
            keyln = data->key_ln;
        }
        return ((EVP_MD_CTX*)p2)->digest->md_ctrl((EVP_MD_CTX*)p2, EVP_MD_CTRL_SET_KEY, keyln, key);
    }
    }
    return -2;
}
Ejemplo n.º 23
0
soter_status_t soter_rsa_key_pair_gen_export_key(soter_rsa_key_pair_gen_t* ctx, void* key, size_t* key_length, bool isprivate){
    EVP_PKEY *pkey;
    SOTER_CHECK_PARAM(ctx);
    pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
    SOTER_CHECK_PARAM(pkey);
    SOTER_CHECK_PARAM(EVP_PKEY_RSA == EVP_PKEY_id(pkey));
    if (isprivate)
    {
	return soter_engine_specific_to_rsa_priv_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length);
    }
    else
    {
	return soter_engine_specific_to_rsa_pub_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length);
    }
}
Ejemplo n.º 24
0
soter_status_t soter_sign_final_rsa_pss_pkcs8(soter_sign_ctx_t* ctx, void* signature, size_t* signature_length)
{
    EVP_PKEY* pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
    if (!pkey) {
        return SOTER_INVALID_PARAMETER;
    }
    if ((*signature_length) < (size_t)EVP_PKEY_size(pkey)) {
        (*signature_length) = (size_t)EVP_PKEY_size(pkey);
        return SOTER_BUFFER_TOO_SMALL;
    }
    if (!EVP_DigestSignFinal(ctx->md_ctx, signature, signature_length)) {
        return SOTER_FAIL;
    }
    return SOTER_SUCCESS;
}
Ejemplo n.º 25
0
soter_status_t soter_rsa_export_key(soter_sign_ctx_t* ctx, void* key, size_t* key_length, bool isprivate)
{
  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
  
  if (!pkey){
    return SOTER_INVALID_PARAMETER;
  }
  if(isprivate)
    {
      return soter_engine_specific_to_rsa_priv_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length);
    }
  else
    {
      return soter_engine_specific_to_rsa_pub_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length);
    }  
}
soter_status_t soter_sign_final_ecdsa_none_pkcs8(soter_sign_ctx_t* ctx, void* signature, size_t *signature_length)
{
  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
  if (!pkey && EVP_PKEY_base_id(pkey)!=EVP_PKEY_EC){
    return SOTER_INVALID_PARAMETER;
  } /* TODO: need review */
  soter_status_t res = SOTER_SUCCESS;
  if(!signature || (*signature_length)<(size_t)EVP_PKEY_size(pkey)){
    (*signature_length)=(size_t)EVP_PKEY_size(pkey);
    res = SOTER_BUFFER_TOO_SMALL;
  } else {
      if(EVP_DigestSignFinal(ctx->md_ctx, signature, signature_length)!=1)
	res = SOTER_INVALID_SIGNATURE;
  }
  return res;
}
Ejemplo n.º 27
0
soter_status_t soter_verify_cleanup_rsa_pss_pkcs8(soter_sign_ctx_t* ctx)
{
  if(!ctx){
    return SOTER_INVALID_PARAMETER;
  }
  if(ctx->pkey_ctx){
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
    if(pkey)EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(ctx->pkey_ctx);
    ctx->pkey_ctx=NULL;
  }
  if(ctx->md_ctx){
    EVP_MD_CTX_destroy(ctx->md_ctx);
    ctx->md_ctx=NULL;
  }
  return SOTER_SUCCESS;
}
Ejemplo n.º 28
0
soter_status_t soter_verify_final_rsa_pss_pkcs8(soter_sign_ctx_t* ctx, const void* signature, const size_t signature_length)
{
  if (!ctx){
    return SOTER_INVALID_PARAMETER;
  }
  EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx);
  if (!pkey){
    return SOTER_INVALID_PARAMETER;
  }
  if(signature_length!=EVP_PKEY_size(pkey)){
    return SOTER_FAIL;
  }
  if(!EVP_DigestVerifyFinal(ctx->md_ctx, (unsigned char*)signature, signature_length)){
    return SOTER_FAIL;
  }
  return SOTER_SUCCESS;
}
Ejemplo n.º 29
0
static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
	size_t siglen, const unsigned char *tbs, size_t tbs_len)
	{
	int ok = 0;
	EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
	DSA_SIG *s=unpack_cp_signature(sig,siglen);
	if (!s) return 0;
#ifdef DEBUG_SIGN	
	fprintf(stderr,"R=");
	BN_print_fp(stderr,s->r);
	fprintf(stderr,"\nS=");
	BN_print_fp(stderr,s->s);
	fprintf(stderr,"\n");
#endif	
	if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
	DSA_SIG_free(s);
	return ok;
	}
Ejemplo n.º 30
0
static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
	const unsigned char *tbs, size_t tbs_len)
	{
	DSA_SIG *unpacked_sig=NULL;
	EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
	if (!siglen) return 0;
	if (!sig)
		{
		*siglen= 64; /* better to check size of curve order*/
		return 1;
		}	
	unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
	if (!unpacked_sig)
		{
		return 0;
		}
	return pack_sign_cp(unpacked_sig,32,sig,siglen);
	}