示例#1
0
/* Padding is ignored. We use OAEP by default. Parameter is to support more paddings in the future */
soter_status_t soter_asym_cipher_init(soter_asym_cipher_t* asym_cipher, const void* key, const size_t key_length, soter_asym_cipher_padding_t pad)
{
	EVP_PKEY *pkey;

	if ((!asym_cipher) || (SOTER_ASYM_CIPHER_OAEP != pad))
	{
		return SOTER_INVALID_PARAMETER;
	}

	pkey = EVP_PKEY_new();
	if (!pkey)
	{
		return SOTER_NO_MEMORY;
	}

	/* Only RSA supports asymmetric encryption */
	if (!EVP_PKEY_set_type(pkey, EVP_PKEY_RSA))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}

	asym_cipher->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
	if (!(asym_cipher->pkey_ctx))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}
	SOTER_IF_FAIL(soter_asym_cipher_import_key(asym_cipher, key, key_length)==SOTER_SUCCESS, (EVP_PKEY_free(pkey), EVP_PKEY_CTX_free(asym_cipher->pkey_ctx)));
	return SOTER_SUCCESS;
}
示例#2
0
/*
 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
 * NID and parameters
 */
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
{
    ASN1_OBJECT *palg_obj = NULL;
    int ptype = V_ASN1_UNDEF;
    int pkey_nid = NID_undef, param_nid = NID_undef;
    ASN1_STRING *pval = NULL;
    const unsigned char *p;
    GOST_KEY_PARAMS *gkp = NULL;

    if (!pkey || !palg)
        return 0;
    X509_ALGOR_get0(&palg_obj, &ptype, (void **)&pval, palg);
    if (ptype != V_ASN1_SEQUENCE) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
                GOST_R_BAD_KEY_PARAMETERS_FORMAT);
        return 0;
    }
    p = pval->data;
    pkey_nid = OBJ_obj2nid(palg_obj);

    gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
    if (!gkp) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
                GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
        return 0;
    }
    param_nid = OBJ_obj2nid(gkp->key_params);
    GOST_KEY_PARAMS_free(gkp);
    if (!EVP_PKEY_set_type(pkey, pkey_nid)) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    return gost_decode_nid_params(pkey, pkey_nid, param_nid);
}
示例#3
0
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
	{
	if (!EVP_PKEY_set_type(pkey, type))
		return 0;
	pkey->pkey.ptr=(char*)key;
	return (key != NULL);
	}
示例#4
0
EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp,
                        long length)
{
    EVP_PKEY *ret = NULL;
    const unsigned char *p = *pp;

    if ((a == NULL) || (*a == NULL)) {
        if ((ret = EVP_PKEY_new()) == NULL)
            return NULL;
    } else
        ret = *a;

    if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type))
        goto err;

    if (ret->ameth == NULL || ret->ameth->param_decode == NULL) {
        ASN1err(ASN1_F_D2I_KEYPARAMS, ASN1_R_UNSUPPORTED_TYPE);
        goto err;
    }

    if (!ret->ameth->param_decode(ret, &p, length))
        goto err;

    if (a != NULL)
        (*a) = ret;
    return ret;
err:
    if (a == NULL || *a != ret)
        EVP_PKEY_free(ret);
    return NULL;
}
示例#5
0
/*
 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
 * NID and parameters
 */
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
{
    ASN1_OBJECT *palg_obj = NULL;
    int ptype = V_ASN1_UNDEF;
    int pkey_nid = NID_undef, param_nid = NID_undef;
    void *_pval;
    ASN1_STRING *pval = NULL;
    const unsigned char *p;
    GOST_KEY_PARAMS *gkp = NULL;

    X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
    pval = _pval;
    if (ptype != V_ASN1_SEQUENCE) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
                GOST_R_BAD_KEY_PARAMETERS_FORMAT);
        return 0;
    }
    p = pval->data;
    pkey_nid = OBJ_obj2nid(palg_obj);

    gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
    if (!gkp) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
                GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
        return 0;
    }
    param_nid = OBJ_obj2nid(gkp->key_params);
    GOST_KEY_PARAMS_free(gkp);
    if(!EVP_PKEY_set_type(pkey, pkey_nid)) {
        GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    switch (pkey_nid) {
    case NID_id_GostR3410_94:
        {
            DSA *dsa = EVP_PKEY_get0(pkey);
            if (!dsa) {
                dsa = DSA_new();
                if (!EVP_PKEY_assign(pkey, pkey_nid, dsa))
                    return 0;
            }
            if (!fill_GOST94_params(dsa, param_nid))
                return 0;
            break;
        }
    case NID_id_GostR3410_2001:
        {
            EC_KEY *ec = EVP_PKEY_get0(pkey);
            if (!ec) {
                ec = EC_KEY_new();
                if (!EVP_PKEY_assign(pkey, pkey_nid, ec))
                    return 0;
            }
            if (!fill_GOST2001_params(ec, param_nid))
                return 0;
        }
    }

    return 1;
}
示例#6
0
static int set_pkey_type_from_str(EVP_PKEY *pkey, const char *name, size_t len) {
  int nid = public_key_type_from_str(name, len);
  if (nid == NID_undef) {
    return 0;
  }
  return EVP_PKEY_set_type(pkey, nid);
}
示例#7
0
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
	{
	EVP_PKEY *ret=NULL;

	if (key == NULL) goto error;

	if (key->pkey != NULL)
		{
		return EVP_PKEY_dup(key->pkey);
		}

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

	if ((ret = EVP_PKEY_new()) == NULL)
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, ERR_R_MALLOC_FAILURE);
		goto error;
		}

	if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_UNSUPPORTED_ALGORITHM);
		goto error;
		}

	if (ret->ameth->pub_decode)
		{
		if (!ret->ameth->pub_decode(ret, key))
			{
			OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_PUBLIC_KEY_DECODE_ERROR);
			goto error;
			}
		}
	else
		{
		OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_METHOD_NOT_SUPPORTED);
		goto error;
		}

	/* Check to see if another thread set key->pkey first */
	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
	if (key->pkey)
		{
		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
		EVP_PKEY_free(ret);
		ret = key->pkey;
		}
	else
		{
		key->pkey = ret;
		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
		}

	return EVP_PKEY_dup(ret);

	error:
	if (ret != NULL)
		EVP_PKEY_free(ret);
	return(NULL);
	}
示例#8
0
文件: evp.c 项目: tempbottle/ring
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
    if (!EVP_PKEY_set_type(pkey, type)) {
        return 0;
    }
    pkey->pkey.ptr = key;
    return key != NULL;
}
示例#9
0
文件: p_lib.c 项目: G-P-S/openssl
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
{
    if (to->type == EVP_PKEY_NONE) {
        if (EVP_PKEY_set_type(to, from->type) == 0)
            return 0;
    } else if (to->type != from->type) {
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
        goto err;
    }

    if (EVP_PKEY_missing_parameters(from)) {
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
        goto err;
    }

    if (!EVP_PKEY_missing_parameters(to)) {
        if (EVP_PKEY_cmp_parameters(to, from) == 1)
            return 1;
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
        return 0;
    }

    if (from->ameth && from->ameth->param_copy)
        return from->ameth->param_copy(to, from);
 err:
    return 0;
}
示例#10
0
文件: d2i_pu.c 项目: erbridge/openssl
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
                        long length)
{
    EVP_PKEY *ret;

    if ((a == NULL) || (*a == NULL)) {
        if ((ret = EVP_PKEY_new()) == NULL) {
            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
            return (NULL);
        }
    } else
        ret = *a;

    if (!EVP_PKEY_set_type(ret, type)) {
        ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
        goto err;
    }

    switch (EVP_PKEY_id(ret)) {
#ifndef OPENSSL_NO_RSA
    case EVP_PKEY_RSA:
        if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) {
            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
            goto err;
        }
        break;
#endif
#ifndef OPENSSL_NO_DSA
    case EVP_PKEY_DSA:
        /* TMP UGLY CAST */
        if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) {
            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
            goto err;
        }
        break;
#endif
#ifndef OPENSSL_NO_EC
    case EVP_PKEY_EC:
        if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) {
            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
            goto err;
        }
        break;
#endif
    default:
        ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
        goto err;
        /* break; */
    }
    if (a != NULL)
        (*a) = ret;
    return (ret);
 err:
    if (a == NULL || *a != ret)
        EVP_PKEY_free(ret);
    return (NULL);
}
示例#11
0
soter_status_t soter_verify_init_rsa_pss_pkcs8(soter_sign_ctx_t* ctx,
                                               const void* private_key,
                                               const size_t private_key_length,
                                               const void* public_key,
                                               const size_t public_key_length)
{
    /* pkey_ctx init */
    EVP_PKEY* pkey;
    pkey = EVP_PKEY_new();
    if (!pkey) {
        return SOTER_NO_MEMORY;
    }
    if (!EVP_PKEY_set_type(pkey, EVP_PKEY_RSA)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }
    ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (!(ctx->pkey_ctx)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }
    if (private_key && private_key_length != 0) {
        if (soter_rsa_import_key(pkey, private_key, private_key_length) != SOTER_SUCCESS) {
            soter_verify_cleanup_rsa_pss_pkcs8(ctx);
            return SOTER_FAIL;
        }
    }
    if (public_key && public_key_length != 0) {
        if (soter_rsa_import_key(pkey, public_key, public_key_length) != SOTER_SUCCESS) {
            soter_verify_cleanup_rsa_pss_pkcs8(ctx);
            return SOTER_FAIL;
        }
    }

    /*md_ctx init*/
    ctx->md_ctx = EVP_MD_CTX_create();
    if (!(ctx->md_ctx)) {
        soter_verify_cleanup_rsa_pss_pkcs8(ctx);
        return SOTER_NO_MEMORY;
    }
    EVP_PKEY_CTX* md_pkey_ctx = NULL;
    if (!EVP_DigestVerifyInit(ctx->md_ctx, &md_pkey_ctx, EVP_sha256(), NULL, pkey)) {
        soter_verify_cleanup_rsa_pss_pkcs8(ctx);
        return SOTER_FAIL;
    }
    if (!EVP_PKEY_CTX_set_rsa_padding(md_pkey_ctx, RSA_PKCS1_PSS_PADDING)) {
        soter_verify_cleanup_rsa_pss_pkcs8(ctx);
        return SOTER_FAIL;
    }
    if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(md_pkey_ctx, -2)) {
        soter_verify_cleanup_rsa_pss_pkcs8(ctx);
        return SOTER_FAIL;
    }
    return SOTER_SUCCESS;
}
示例#12
0
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
                         long len) {
  EVP_PKEY *ret;

  if (out == NULL || *out == NULL) {
    ret = EVP_PKEY_new();
    if (ret == NULL) {
      OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
      return NULL;
    }
  } else {
    ret = *out;
  }

  if (!EVP_PKEY_set_type(ret, type)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
    goto err;
  }

  const uint8_t *in = *inp;
  if (!ret->ameth->old_priv_decode ||
      !ret->ameth->old_priv_decode(ret, &in, len)) {
    if (ret->ameth->priv_decode) {
      /* Reset |in| in case |old_priv_decode| advanced it on error. */
      in = *inp;
      PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &in, len);
      if (!p8) {
        goto err;
      }
      EVP_PKEY_free(ret);
      ret = EVP_PKCS82PKEY(p8);
      PKCS8_PRIV_KEY_INFO_free(p8);
      if (ret == NULL) {
        goto err;
      }
    } else {
      OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
      goto err;
    }
  }

  if (out != NULL) {
    *out = ret;
  }
  *inp = in;
  return ret;

err:
  if (out == NULL || *out != ret) {
    EVP_PKEY_free(ret);
  }
  return NULL;
}
示例#13
0
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
    EVP_PKEY *ret = NULL;

    if (key == NULL)
        goto error;

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

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

    if ((ret = EVP_PKEY_new()) == NULL) {
        X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
        goto error;
    }

    if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
        X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
        goto error;
    }

    if (ret->ameth->pub_decode) {
        if (!ret->ameth->pub_decode(ret, key)) {
            X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
            goto error;
        }
    } else {
        X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
        goto error;
    }

    /* Check to see if another thread set key->pkey first */
    CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
    if (key->pkey) {
        CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
        EVP_PKEY_free(ret);
        ret = key->pkey;
    } else {
        key->pkey = ret;
        CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
    }
    CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);

    return ret;

 error:
    EVP_PKEY_free(ret);
    return (NULL);
}
示例#14
0
soter_status_t soter_verify_init_ecdsa_none_pkcs8(soter_sign_ctx_t* ctx,
                                                  const void* private_key,
                                                  const size_t private_key_length,
                                                  const void* public_key,
                                                  const size_t public_key_length)
{
    /* pkey_ctx init */
    EVP_PKEY* pkey;
    pkey = EVP_PKEY_new();
    if (!pkey) {
        return SOTER_NO_MEMORY;
    }
    if (!EVP_PKEY_set_type(pkey, EVP_PKEY_EC)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }
    ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (!(ctx->pkey_ctx)) {
        EVP_PKEY_free(pkey);
        return SOTER_FAIL;
    }

    /* TODO: Review needed */
    if ((private_key) && (private_key_length)) {
        if (soter_ec_import_key(pkey, private_key, private_key_length) != SOTER_SUCCESS) {
            soter_verify_cleanup_ecdsa_none_pkcs8(ctx);
            return SOTER_FAIL;
        }
    }

    if ((public_key) && (public_key_length)) {
        if (soter_ec_import_key(pkey, public_key, public_key_length) != SOTER_SUCCESS) {
            soter_verify_cleanup_ecdsa_none_pkcs8(ctx);
            return SOTER_FAIL;
        }
    }

    /*md_ctx init*/
    ctx->md_ctx = EVP_MD_CTX_create();
    if (!(ctx->md_ctx)) {
        soter_verify_cleanup_ecdsa_none_pkcs8(ctx);
        return SOTER_NO_MEMORY;
    }
    if (!EVP_DigestVerifyInit(ctx->md_ctx, NULL, EVP_sha256(), NULL, pkey)) {
        soter_verify_cleanup_ecdsa_none_pkcs8(ctx);
        return SOTER_FAIL;
    }
    return SOTER_SUCCESS;
}
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
{
	EVP_PKEY *pkey = NULL;
	ASN1_OBJECT *algoid;
	char obj_tmp[80];

	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
		return NULL;

	if (!(pkey = EVP_PKEY_new())) {
		EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
		{
		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
		ERR_add_error_data(2, "TYPE=", obj_tmp);
		goto error;
		}

	if (pkey->ameth->priv_decode)
		{
		if (!pkey->ameth->priv_decode(pkey, p8))
			{
			EVPerr(EVP_F_EVP_PKCS82PKEY,
					EVP_R_PRIVATE_KEY_DECODE_ERROR);
			goto error;
			}
		}
	else
		{
		EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
		goto error;
		}

	return pkey;

	error:
	EVP_PKEY_free (pkey);
	return NULL;
}
示例#16
0
soter_status_t soter_asym_ka_init(soter_asym_ka_t* asym_ka_ctx, soter_asym_ka_alg_t alg)
{
	EVP_PKEY *pkey;
	int nid = soter_alg_to_curve_nid(alg);

	if ((!asym_ka_ctx) || (0 == nid))
	{
		return SOTER_INVALID_PARAMETER;
	}

	pkey = EVP_PKEY_new();
	if (!pkey)
	{
		return SOTER_NO_MEMORY;
	}

	if (!EVP_PKEY_set_type(pkey, EVP_PKEY_EC))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}

	asym_ka_ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
	if (!(asym_ka_ctx->pkey_ctx))
	{
		EVP_PKEY_free(pkey);
		return SOTER_FAIL;
	}
	EC_KEY* ec = EC_KEY_new_by_curve_name(nid);
	if( !ec ){
		EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx);
		return SOTER_FAIL;
	}
	
	if(1!=EVP_PKEY_set1_EC_KEY(pkey, ec)){
		EVP_PKEY_CTX_free(asym_ka_ctx->pkey_ctx);
		EC_KEY_free(ec);
		return SOTER_FAIL;
	}
	EC_KEY_free(ec);
	return SOTER_SUCCESS;
}
示例#17
0
EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
  // Parse the SubjectPublicKeyInfo.
  CBS spki, algorithm, key;
  int type;
  uint8_t padding;
  if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
      !parse_key_type(&algorithm, &type) ||
      !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
      CBS_len(&spki) != 0 ||
      // Every key type defined encodes the key as a byte string with the same
      // conversion to BIT STRING.
      !CBS_get_u8(&key, &padding) ||
      padding != 0) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return NULL;
  }

  // Set up an |EVP_PKEY| of the appropriate type.
  EVP_PKEY *ret = EVP_PKEY_new();
  if (ret == NULL ||
      !EVP_PKEY_set_type(ret, type)) {
    goto err;
  }

  // Call into the type-specific SPKI decoding function.
  if (ret->ameth->pub_decode == NULL) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
    goto err;
  }
  if (!ret->ameth->pub_decode(ret, &algorithm, &key)) {
    goto err;
  }

  return ret;

err:
  EVP_PKEY_free(ret);
  return NULL;
}
soter_status_t soter_rsa_key_pair_gen_init(soter_rsa_key_pair_gen_t* ctx, const unsigned key_length){
    EVP_PKEY *pkey;
    pkey = EVP_PKEY_new();
    SOTER_CHECK(pkey);
    /* Only RSA supports asymmetric encryption */
    SOTER_IF_FAIL(EVP_PKEY_set_type(pkey, EVP_PKEY_RSA), EVP_PKEY_free(pkey));
    ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
    SOTER_IF_FAIL(ctx->pkey_ctx,EVP_PKEY_free(pkey));
    BIGNUM *pub_exp;
    SOTER_IF_FAIL(EVP_PKEY_keygen_init(ctx->pkey_ctx), EVP_PKEY_CTX_free(ctx->pkey_ctx));

    /* Although it seems that OpenSSL/LibreSSL use 0x10001 as default public exponent, we will set it explicitly just in case */
    pub_exp = BN_new();
    SOTER_CHECK(pub_exp);
    SOTER_IF_FAIL(BN_set_word(pub_exp, RSA_F4), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx)));

    SOTER_IF_FAIL(1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pub_exp), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx)));
    /* Override default key size for RSA key. Currently OpenSSL has default key size of 1024. LibreSSL has 2048. We will put 2048 explicitly */
    SOTER_IF_FAIL((1 <= EVP_PKEY_CTX_ctrl(ctx->pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, rsa_key_length(key_length), NULL)), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx)));
    SOTER_IF_FAIL(EVP_PKEY_keygen(ctx->pkey_ctx, &pkey), (BN_free(pub_exp), EVP_PKEY_CTX_free(ctx->pkey_ctx)));
    return SOTER_SUCCESS;
}
示例#19
0
EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
  // Parse the PrivateKeyInfo.
  CBS pkcs8, algorithm, key;
  uint64_t version;
  int type;
  if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1_uint64(&pkcs8, &version) ||
      version != 0 ||
      !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
      !parse_key_type(&algorithm, &type) ||
      !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return NULL;
  }

  // A PrivateKeyInfo ends with a SET of Attributes which we ignore.

  // Set up an |EVP_PKEY| of the appropriate type.
  EVP_PKEY *ret = EVP_PKEY_new();
  if (ret == NULL ||
      !EVP_PKEY_set_type(ret, type)) {
    goto err;
  }

  // Call into the type-specific PrivateKeyInfo decoding function.
  if (ret->ameth->priv_decode == NULL) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
    goto err;
  }
  if (!ret->ameth->priv_decode(ret, &algorithm, &key)) {
    goto err;
  }

  return ret;

err:
  EVP_PKEY_free(ret);
  return NULL;
}
示例#20
0
文件: x_pubkey.c 项目: cedral/openssl
static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
    {
    EVP_PKEY *pkey = EVP_PKEY_new();

    if (pkey == NULL) {
        X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
        return -1;
    }

    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
        X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
        goto error;
    }

    if (pkey->ameth->pub_decode) {
        /*
         * Treat any failure of pub_decode as a decode error. In
         * future we could have different return codes for decode
         * errors and fatal errors such as malloc failure.
         */
        if (!pkey->ameth->pub_decode(pkey, key)) {
            X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
            goto error;
        }
    } else {
        X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
        goto error;
    }

    *ppkey = pkey;
    return 1;

 error:
    EVP_PKEY_free(pkey);
    return 0;
}
示例#21
0
/*
 * Process a key_share extension received in the ClientHello. |pkt| contains
 * the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
 * If a failure occurs then |*al| is set to an appropriate alert value.
 */
int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, int *al)
{
    unsigned int group_id;
    PACKET key_share_list, encoded_pt;
    const unsigned char *clntcurves, *srvrcurves;
    size_t clnt_num_curves, srvr_num_curves;
    int group_nid, found = 0;
    unsigned int curve_flags;

    if (s->hit)
        return 1;

    /* Sanity check */
    if (s->s3->peer_tmp != NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) {
        *al = SSL_AD_HANDSHAKE_FAILURE;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
        return 0;
    }

    /* Get our list of supported curves */
    if (!tls1_get_curvelist(s, 0, &srvrcurves, &srvr_num_curves)) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    /*
     * Get the clients list of supported curves.
     * TODO(TLS1.3): We should validate that we actually received
     * supported_groups!
     */
    if (!tls1_get_curvelist(s, 1, &clntcurves, &clnt_num_curves)) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    while (PACKET_remaining(&key_share_list) > 0) {
        if (!PACKET_get_net_2(&key_share_list, &group_id)
                || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt)
                || PACKET_remaining(&encoded_pt) == 0) {
            *al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                   SSL_R_LENGTH_MISMATCH);
            return 0;
        }

        /*
         * If we already found a suitable key_share we loop through the
         * rest to verify the structure, but don't process them.
         */
        if (found)
            continue;

        /* Check if this share is in supported_groups sent from client */
        if (!check_in_list(s, group_id, clntcurves, clnt_num_curves, 0)) {
            *al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
            return 0;
        }

        /* Check if this share is for a group we can use */
        if (!check_in_list(s, group_id, srvrcurves, srvr_num_curves, 1)) {
            /* Share not suitable */
            continue;
        }

        group_nid = tls1_ec_curve_id2nid(group_id, &curve_flags);

        if (group_nid == 0) {
            *al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                   SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
            return 0;
        }

        if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
            /* Can happen for some curves, e.g. X25519 */
            EVP_PKEY *key = EVP_PKEY_new();

            if (key == NULL || !EVP_PKEY_set_type(key, group_nid)) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_free(key);
                return 0;
            }
            s->s3->peer_tmp = key;
        } else {
            /* Set up EVP_PKEY with named curve as parameters */
            EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);

            if (pctx == NULL
                    || EVP_PKEY_paramgen_init(pctx) <= 0
                    || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
                                                              group_nid) <= 0
                    || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_CTX_free(pctx);
                return 0;
            }
            EVP_PKEY_CTX_free(pctx);
            pctx = NULL;
        }
        s->s3->group_id = group_id;

        if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
                PACKET_data(&encoded_pt),
                PACKET_remaining(&encoded_pt))) {
            *al = SSL_AD_DECODE_ERROR;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_ECPOINT);
            return 0;
        }

        found = 1;
    }

    return 1;
}
示例#22
0
static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len,
		const unsigned char *params, int params_len,
		unsigned char *data, int data_len,
		unsigned char *signat, int signat_len)
{
	EVP_PKEY *pkey;
	EVP_PKEY_CTX *pkey_ctx;
	EC_POINT *P;
	BIGNUM *X, *Y;
	ASN1_OCTET_STRING *octet;
	const EC_GROUP *group = NULL;
	char paramset[2] = "A";
	int r = -1, ret_vrf = 0;

	pkey = EVP_PKEY_new();
	if (!pkey)
		return CKR_HOST_MEMORY;
	r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001);
	if (r == 1) {
		pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
		if (!pkey_ctx) {
			EVP_PKEY_free(pkey);
			return CKR_HOST_MEMORY;
		}
		/* FIXME: fully check params[] */
		if (params_len > 0 && params[params_len - 1] >= 1 &&
				params[params_len - 1] <= 3) {
			paramset[0] += params[params_len - 1] - 1;
			r = EVP_PKEY_CTX_ctrl_str(pkey_ctx, "paramset", paramset);
		}
		else
			r = -1;
		if (r == 1)
			r = EVP_PKEY_paramgen_init(pkey_ctx);
		if (r == 1)
			r = EVP_PKEY_paramgen(pkey_ctx, &pkey);
		if (r == 1 && EVP_PKEY_get0(pkey) != NULL)
			group = EC_KEY_get0_group(EVP_PKEY_get0(pkey));
		r = -1;
		if (group)
			octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey, (long)pubkey_len);
		if (group && octet) {
			reverse(octet->data, octet->length);
			Y = BN_bin2bn(octet->data, octet->length / 2, NULL);
			X = BN_bin2bn((const unsigned char*)octet->data +
					octet->length / 2, octet->length / 2, NULL);
			ASN1_OCTET_STRING_free(octet);
			P = EC_POINT_new(group);
			if (P && X && Y)
				r = EC_POINT_set_affine_coordinates_GFp(group,
						P, X, Y, NULL);
			BN_free(X);
			BN_free(Y);
			if (r == 1 && EVP_PKEY_get0(pkey) && P)
				r = EC_KEY_set_public_key(EVP_PKEY_get0(pkey), P);
			EC_POINT_free(P);
		}
		if (r == 1) {
			r = EVP_PKEY_verify_init(pkey_ctx);
			reverse(data, data_len);
			if (r == 1)
				ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len,
						data, data_len);
		}
	}
	EVP_PKEY_CTX_free(pkey_ctx);
	EVP_PKEY_free(pkey);
	if (r != 1)
		return CKR_GENERAL_ERROR;
	return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID;
}
示例#23
0
/*
 * Process a key_share extension received in the ClientHello. |pkt| contains
 * the raw PACKET data for the extension. Returns 1 on success or 0 on failure.
 * If a failure occurs then |*al| is set to an appropriate alert value.
 */
int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                             size_t chainidx, int *al)
{
#ifndef OPENSSL_NO_TLS1_3
    unsigned int group_id;
    PACKET key_share_list, encoded_pt;
    const unsigned char *clntcurves, *srvrcurves;
    size_t clnt_num_curves, srvr_num_curves;
    int group_nid, found = 0;
    unsigned int curve_flags;

    if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0)
        return 1;

    /* Sanity check */
    if (s->s3->peer_tmp != NULL) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) {
        *al = SSL_AD_DECODE_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_LENGTH_MISMATCH);
        return 0;
    }

    /* Get our list of supported curves */
    if (!tls1_get_curvelist(s, 0, &srvrcurves, &srvr_num_curves)) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }

    /* Get the clients list of supported curves. */
    if (!tls1_get_curvelist(s, 1, &clntcurves, &clnt_num_curves)) {
        *al = SSL_AD_INTERNAL_ERROR;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_INTERNAL_ERROR);
        return 0;
    }
    if (clnt_num_curves == 0) {
        /*
         * This can only happen if the supported_groups extension was not sent,
         * because we verify that the length is non-zero when we process that
         * extension.
         */
        *al = SSL_AD_MISSING_EXTENSION;
        SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
               SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION);
        return 0;
    }

    while (PACKET_remaining(&key_share_list) > 0) {
        if (!PACKET_get_net_2(&key_share_list, &group_id)
                || !PACKET_get_length_prefixed_2(&key_share_list, &encoded_pt)
                || PACKET_remaining(&encoded_pt) == 0) {
            *al = SSL_AD_DECODE_ERROR;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                   SSL_R_LENGTH_MISMATCH);
            return 0;
        }

        /*
         * If we already found a suitable key_share we loop through the
         * rest to verify the structure, but don't process them.
         */
        if (found)
            continue;

        /* Check if this share is in supported_groups sent from client */
        if (!check_in_list(s, group_id, clntcurves, clnt_num_curves, 0)) {
            *al = SSL_AD_ILLEGAL_PARAMETER;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_KEY_SHARE);
            return 0;
        }

        /* Check if this share is for a group we can use */
        if (!check_in_list(s, group_id, srvrcurves, srvr_num_curves, 1)) {
            /* Share not suitable */
            continue;
        }

        group_nid = tls1_ec_curve_id2nid(group_id, &curve_flags);

        if (group_nid == 0) {
            *al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE,
                   SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
            return 0;
        }

        if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
            /* Can happen for some curves, e.g. X25519 */
            EVP_PKEY *key = EVP_PKEY_new();

            if (key == NULL || !EVP_PKEY_set_type(key, group_nid)) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_free(key);
                return 0;
            }
            s->s3->peer_tmp = key;
        } else {
            /* Set up EVP_PKEY with named curve as parameters */
            EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);

            if (pctx == NULL
                    || EVP_PKEY_paramgen_init(pctx) <= 0
                    || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
                                                              group_nid) <= 0
                    || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
                *al = SSL_AD_INTERNAL_ERROR;
                SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB);
                EVP_PKEY_CTX_free(pctx);
                return 0;
            }
            EVP_PKEY_CTX_free(pctx);
            pctx = NULL;
        }
        s->s3->group_id = group_id;

        if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
                PACKET_data(&encoded_pt),
                PACKET_remaining(&encoded_pt))) {
            *al = SSL_AD_ILLEGAL_PARAMETER;
            SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_BAD_ECPOINT);
            return 0;
        }

        found = 1;
    }
#endif

    return 1;
}
示例#24
0
/*
 * Key parameter decoder.
 */
static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
                                          const char *pem_header,
                                          const unsigned char *blob,
                                          size_t len, void **pctx,
                                          int *matchcount,
                                          const UI_METHOD *ui_method,
                                          void *ui_data)
{
    OSSL_STORE_INFO *store_info = NULL;
    int slen = 0;
    EVP_PKEY *pkey = NULL;
    const EVP_PKEY_ASN1_METHOD *ameth = NULL;
    int ok = 0;

    if (pem_name != NULL) {
        if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) == 0)
            return NULL;
        *matchcount = 1;
    }

    if (slen > 0) {
        if ((pkey = EVP_PKEY_new()) == NULL) {
            OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
            return NULL;
        }


        if (EVP_PKEY_set_type_str(pkey, pem_name, slen)
            && (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
            && ameth->param_decode != NULL
            && ameth->param_decode(pkey, &blob, len))
            ok = 1;
    } else {
        int i;
        EVP_PKEY *tmp_pkey = NULL;

        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
            const unsigned char *tmp_blob = blob;

            if (tmp_pkey == NULL && (tmp_pkey = EVP_PKEY_new()) == NULL) {
                OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
                break;
            }

            ameth = EVP_PKEY_asn1_get0(i);
            if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
                continue;

            if (EVP_PKEY_set_type(tmp_pkey, ameth->pkey_id)
                && (ameth = EVP_PKEY_get0_asn1(tmp_pkey)) != NULL
                && ameth->param_decode != NULL
                && ameth->param_decode(tmp_pkey, &tmp_blob, len)) {
                if (pkey != NULL)
                    EVP_PKEY_free(tmp_pkey);
                else
                    pkey = tmp_pkey;
                tmp_pkey = NULL;
                (*matchcount)++;
            }
        }

        EVP_PKEY_free(tmp_pkey);
        if (*matchcount == 1) {
            ok = 1;
        }
    }

    if (ok)
        store_info = OSSL_STORE_INFO_new_PARAMS(pkey);
    if (store_info == NULL)
        EVP_PKEY_free(pkey);

    return store_info;
}
soter_status_t soter_sign_init_ecdsa_none_pkcs8(soter_sign_ctx_t* ctx, const void* private_key, const size_t private_key_length, const void* public_key, const size_t public_key_length)
{
  /* pkey_ctx init */  
  EVP_PKEY *pkey;
  pkey = EVP_PKEY_new();
  if (!pkey){
    return SOTER_NO_MEMORY;
  }
  if (!EVP_PKEY_set_type(pkey, EVP_PKEY_EC)){
    EVP_PKEY_free(pkey);
    return SOTER_FAIL;
  }
  ctx->pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL);
  if (!(ctx->pkey_ctx)){
    EVP_PKEY_free(pkey);
    return SOTER_FAIL;
  }
  if (!EVP_PKEY_paramgen_init(ctx->pkey_ctx)){
    soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
    return SOTER_FAIL;
  }
  if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx->pkey_ctx, NID_X9_62_prime256v1)){
    soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
    return SOTER_FAIL;
  }
  if (!EVP_PKEY_paramgen(ctx->pkey_ctx, &pkey)){
    soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
    return SOTER_FAIL;
  }
  if((!private_key)&&(!public_key)){
    if(soter_ec_gen_key(ctx->pkey_ctx)!=SOTER_SUCCESS){
      soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
      return SOTER_FAIL;
    }
  }else{
    if(private_key!=NULL){
      if(soter_ec_import_key(pkey, private_key, private_key_length)!=SOTER_SUCCESS){
        soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
	return SOTER_FAIL;
      }
    }
    if(public_key!=NULL){
      if(soter_ec_import_key(pkey, public_key, public_key_length)!=SOTER_SUCCESS){
        soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
	return SOTER_FAIL;
      }
    }
  }

  /*md_ctx init*/
    ctx->md_ctx = EVP_MD_CTX_create();
    if(!(ctx->md_ctx)){
        soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
	return SOTER_NO_MEMORY;
    }
  if(EVP_DigestSignInit(ctx->md_ctx, NULL, EVP_sha256(), NULL, pkey)!=1){
    soter_sign_cleanup_ecdsa_none_pkcs8(ctx);
    return SOTER_FAIL;
  }
  return SOTER_SUCCESS;
}
示例#26
-1
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                         long length)
{
    EVP_PKEY *ret;
    const unsigned char *p = *pp;

    if ((a == NULL) || (*a == NULL)) {
        if ((ret = EVP_PKEY_new()) == NULL) {
            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
            return (NULL);
        }
    } else {
        ret = *a;
#ifndef OPENSSL_NO_ENGINE
        if (ret->engine) {
            ENGINE_finish(ret->engine);
            ret->engine = NULL;
        }
#endif
    }

    if (!EVP_PKEY_set_type(ret, type)) {
        ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
        goto err;
    }

    if (!ret->ameth->old_priv_decode ||
        !ret->ameth->old_priv_decode(ret, &p, length)) {
        if (ret->ameth->priv_decode) {
            EVP_PKEY *tmp;
            PKCS8_PRIV_KEY_INFO *p8 = NULL;
            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
            if (!p8)
                goto err;
            tmp = EVP_PKCS82PKEY(p8);
            PKCS8_PRIV_KEY_INFO_free(p8);
            if (tmp == NULL)
                goto err;
            EVP_PKEY_free(ret);
            ret = tmp;
        } else {
            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
            goto err;
        }
    }
    *pp = p;
    if (a != NULL)
        (*a) = ret;
    return (ret);
 err:
    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        EVP_PKEY_free(ret);
    return (NULL);
}