Exemple #1
0
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
    ASN1_STRING *params = NULL;
    ASN1_INTEGER *prkey = NULL;
    unsigned char *dp = NULL;
    int dplen;

    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key)
    {
        DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_MISSING_PARAMETERS);
        goto err;
    }

    params = ASN1_STRING_new();

    if (!params)
    {
        DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        goto err;
    }

    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
    if (params->length <= 0)
    {
        DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
        goto err;
    }
    params->type = V_ASN1_SEQUENCE;

    /* Get private key into integer */
    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);

    if (!prkey)
    {
        DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
        goto err;
    }

    dplen = i2d_ASN1_INTEGER(prkey, &dp);

    ASN1_INTEGER_free(prkey);

    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
                         V_ASN1_SEQUENCE, params, dp, dplen))
        goto err;

    return 1;

err:
    if (dp != NULL)
        OPENSSL_free(dp);
    if (params != NULL)
        ASN1_STRING_free(params);
    if (prkey != NULL)
        ASN1_INTEGER_free(prkey);
    return 0;
}
Exemple #2
0
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
{
    DSA *dsa;
    int ptype;
    unsigned char *penc = NULL;
    int penclen;
    ASN1_STRING *str = NULL;
    ASN1_INTEGER *pubint = NULL;
    ASN1_OBJECT *aobj;

    dsa = pkey->pkey.dsa;
    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
        str = ASN1_STRING_new();
        if (str == NULL) {
            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        str->length = i2d_DSAparams(dsa, &str->data);
        if (str->length <= 0) {
            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        ptype = V_ASN1_SEQUENCE;
    } else
        ptype = V_ASN1_UNDEF;

    pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL);

    if (pubint == NULL) {
        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    penclen = i2d_ASN1_INTEGER(pubint, &penc);
    ASN1_INTEGER_free(pubint);

    if (penclen <= 0) {
        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    aobj = OBJ_nid2obj(EVP_PKEY_DSA);
    if (aobj == NULL)
        goto err;

    if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen))
        return 1;

 err:
    OPENSSL_free(penc);
    ASN1_STRING_free(str);

    return 0;
}
Exemple #3
0
static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
  ASN1_STRING *params = NULL;
  ASN1_INTEGER *prkey = NULL;
  uint8_t *dp = NULL;
  int dplen;

  if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
    goto err;
  }

  params = ASN1_STRING_new();
  if (!params) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
  if (params->length <= 0) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  params->type = V_ASN1_SEQUENCE;

  /* Get private key into integer. */
  prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);

  if (!prkey) {
    OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
    goto err;
  }

  dplen = i2d_ASN1_INTEGER(prkey, &dp);

  ASN1_INTEGER_free(prkey);
  prkey = NULL;

  if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0,
                       V_ASN1_SEQUENCE, params, dp, dplen)) {
    goto err;
  }

  return 1;

err:
  OPENSSL_free(dp);
  ASN1_STRING_free(params);
  ASN1_INTEGER_free(prkey);
  return 0;
}
static int
dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
{
	DSA *dsa;
	void *pval = NULL;
	int ptype;
	unsigned char *penc = NULL;
	int penclen;

	dsa = pkey->pkey.dsa;
	if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
		ASN1_STRING *str;

		str = ASN1_STRING_new();
		if (str == NULL) {
			DSAerror(ERR_R_MALLOC_FAILURE);
			goto err;
		}
		str->length = i2d_DSAparams(dsa, &str->data);
		if (str->length <= 0) {
			DSAerror(ERR_R_MALLOC_FAILURE);
			ASN1_STRING_free(str);
			goto err;
		}
		pval = str;
		ptype = V_ASN1_SEQUENCE;
	} else
		ptype = V_ASN1_UNDEF;

	dsa->write_params = 0;

	penclen = i2d_DSAPublicKey(dsa, &penc);

	if (penclen <= 0) {
		DSAerror(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
	    penc, penclen))
		return 1;

err:
	free(penc);
	ASN1_STRING_free(pval);

	return 0;
}
Exemple #5
0
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
  DSA *dsa;
  ASN1_STRING *pval = NULL;
  uint8_t *penc = NULL;
  int penclen;

  dsa = pkey->pkey.dsa;
  dsa->write_params = 0;

  int ptype;
  if (dsa->p && dsa->q && dsa->g) {
    pval = ASN1_STRING_new();
    if (!pval) {
      OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    pval->length = i2d_DSAparams(dsa, &pval->data);
    if (pval->length <= 0) {
      OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ptype = V_ASN1_SEQUENCE;
  } else {
    ptype = V_ASN1_UNDEF;
  }

  penclen = i2d_DSAPublicKey(dsa, &penc);
  if (penclen <= 0) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval,
                             penc, penclen)) {
    return 1;
  }

err:
  OPENSSL_free(penc);
  ASN1_STRING_free(pval);

  return 0;
}
Exemple #6
0
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
	{
	X509_PUBKEY *pk=NULL;
	X509_ALGOR *a;
	ASN1_OBJECT *o;
	unsigned char *s,*p = NULL;
	int i;

	if (x == NULL) return(0);

	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
	a=pk->algor;

	/* set the algorithm id */
	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
	ASN1_OBJECT_free(a->algorithm);
	a->algorithm=o;

	/* Set the parameter list */
	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
		{
		if ((a->parameter == NULL) ||
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			if (!(a->parameter=ASN1_TYPE_new()))
				{
				X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			a->parameter->type=V_ASN1_NULL;
			}
		}
#ifndef OPENSSL_NO_DSA
	else if (pkey->type == EVP_PKEY_DSA)
		{
		unsigned char *pp;
		DSA *dsa;
		
		dsa=pkey->pkey.dsa;
		dsa->write_params=0;
		ASN1_TYPE_free(a->parameter);
		if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
			goto err;
		if (!(p=(unsigned char *)OPENSSL_malloc(i)))
			{
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		pp=p;
		i2d_DSAparams(dsa,&pp);
		if (!(a->parameter=ASN1_TYPE_new()))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		a->parameter->type=V_ASN1_SEQUENCE;
		if (!(a->parameter->value.sequence=ASN1_STRING_new()))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!ASN1_STRING_set(a->parameter->value.sequence,p,i))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		OPENSSL_free(p);
		}
#endif
#ifndef OPENSSL_NO_EC
	else if (pkey->type == EVP_PKEY_EC)
		{
		int nid=0;
		unsigned char *pp;
		EC_KEY *ec_key;
		const EC_GROUP *group;
		
		ec_key = pkey->pkey.ec;
		ASN1_TYPE_free(a->parameter);

		if ((a->parameter = ASN1_TYPE_new()) == NULL)
			{
			X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
			goto err;
			}

		group = EC_KEY_get0_group(ec_key);
		if (EC_GROUP_get_asn1_flag(group)
                     && (nid = EC_GROUP_get_curve_name(group)))
			{
			/* just set the OID */
			a->parameter->type = V_ASN1_OBJECT;
			a->parameter->value.object = OBJ_nid2obj(nid);
			}
		else /* explicit parameters */
			{
			if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
				{
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
				goto err;
				}
			if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
				{
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
				goto err;
				}	
			pp = p;
			if (!i2d_ECParameters(ec_key, &pp))
				{
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
				OPENSSL_free(p);
				goto err;
				}
			a->parameter->type = V_ASN1_SEQUENCE;
			if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
				{
				X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
				OPENSSL_free(p);
				goto err;
				}
			ASN1_STRING_set(a->parameter->value.sequence, p, i);
			OPENSSL_free(p);
			}
		}
#endif
	else if (1)
		{
		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
		goto err;
		}

	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
		{
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=s;
	i2d_PublicKey(pkey,&p);
	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
		{
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
		goto err;
		}
  	/* Set number of unused bits to zero */
	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;

	OPENSSL_free(s);

#if 0
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	pk->pkey=pkey;
#endif

	if (*x != NULL)
		X509_PUBKEY_free(*x);

	*x=pk;

	return 1;
err:
	if (pk != NULL) X509_PUBKEY_free(pk);
	return 0;
	}
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
  ASN1_STRING *params = NULL;
  ASN1_INTEGER *prkey = NULL;
  ASN1_TYPE *ttmp = NULL;
  STACK_OF(ASN1_TYPE) *ndsa = NULL;
  unsigned char *p = NULL, *q;
  int len;

  p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
  len = i2d_DSAparams (pkey->pkey.dsa, NULL);
  if (!(p = OPENSSL_malloc(len))) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  q = p;
  i2d_DSAparams (pkey->pkey.dsa, &q);
  if (!(params = ASN1_STRING_new())) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  if (!ASN1_STRING_set(params, p, len)) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  OPENSSL_free(p);
  p = NULL;
  /* Get private key into integer */
  if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
    goto err;
  }

  switch(p8->broken) {

    case PKCS8_OK:
    case PKCS8_NO_OCTET:

    if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
           &p8->pkey->value.octet_string)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    M_ASN1_INTEGER_free (prkey);
    prkey = NULL;
    p8->pkeyalg->parameter->value.sequence = params;
    params = NULL;
    p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;

    break;

    case PKCS8_NS_DB:

    p8->pkeyalg->parameter->value.sequence = params;
    params = NULL;
    p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
    if (!(ndsa = sk_ASN1_TYPE_new_null())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp->value.integer =
      BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
      goto err;
    }
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.integer = prkey;
    prkey = NULL;
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp = NULL;

    if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
           &p8->pkey->value.octet_string->data,
           &p8->pkey->value.octet_string->length)) {

      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    break;

    case PKCS8_EMBEDDED_PARAM:

    p8->pkeyalg->parameter->type = V_ASN1_NULL;
    if (!(ndsa = sk_ASN1_TYPE_new_null())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.sequence = params;
    params = NULL;
    ttmp->type = V_ASN1_SEQUENCE;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.integer = prkey;
    prkey = NULL;
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp = NULL;

    if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
           &p8->pkey->value.octet_string->data,
           &p8->pkey->value.octet_string->length)) {

      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    break;
  }
  return 1;
err:
  if (p != NULL) OPENSSL_free(p);
  if (params != NULL) ASN1_STRING_free(params);
  if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
  if (ttmp != NULL) ASN1_TYPE_free(ttmp);
  if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
  return 0;
}
Exemple #8
0
static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
    return i2d_DSAparams(pkey->pkey.dsa, pder);
}
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
	{
	X509_PUBKEY *pk=NULL;
	X509_ALGOR *a;
	ASN1_OBJECT *o;
	unsigned char *s,*p = NULL;
	int i;

	if (x == NULL) return(0);

	if ((pk=X509_PUBKEY_new()) == NULL) goto err;
	a=pk->algor;

	/* set the algorithm id */
	if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
	ASN1_OBJECT_free(a->algorithm);
	a->algorithm=o;

	/* Set the parameter list */
	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
		{
		if ((a->parameter == NULL) ||
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			if (!(a->parameter=ASN1_TYPE_new()))
				{
				X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			a->parameter->type=V_ASN1_NULL;
			}
		}
	else
#ifndef OPENSSL_NO_DSA
		if (pkey->type == EVP_PKEY_DSA)
		{
		unsigned char *pp;
		DSA *dsa;

		dsa=pkey->pkey.dsa;
		dsa->write_params=0;
		ASN1_TYPE_free(a->parameter);
		if ((i=i2d_DSAparams(dsa,NULL)) <= 0)
			goto err;
		if (!(p=(unsigned char *)OPENSSL_malloc(i)))
			{
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		pp=p;
		i2d_DSAparams(dsa,&pp);
		if (!(a->parameter=ASN1_TYPE_new()))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		a->parameter->type=V_ASN1_SEQUENCE;
		if (!(a->parameter->value.sequence=ASN1_STRING_new()))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		if (!ASN1_STRING_set(a->parameter->value.sequence,p,i))
			{
			OPENSSL_free(p);
			X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		OPENSSL_free(p);
		}
	else
#endif
		{
		X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
		goto err;
		}

	if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
	if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
		{
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=s;
	i2d_PublicKey(pkey,&p);
	if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i))
		{
		X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	/* Set number of unused bits to zero */
	pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;

	OPENSSL_free(s);

#if 0
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	pk->pkey=pkey;
#endif

	if (*x != NULL)
		X509_PUBKEY_free(*x);

	*x=pk;

	return 1;
err:
	if (pk != NULL) X509_PUBKEY_free(pk);
	return 0;
	}