Beispiel #1
0
BOOL crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* PublicKeyLength)
{
	BYTE* ptr;
	int length;
	BOOL status = TRUE;
	EVP_PKEY* pkey = NULL;

	pkey = X509_get_pubkey(cert->px509);
	if (!pkey)
	{
		fprintf(stderr, "%s: X509_get_pubkey() failed\n", __FUNCTION__);
		status = FALSE;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);
	if (length < 1)
	{
		fprintf(stderr, "%s: i2d_PublicKey() failed\n", __FUNCTION__);
		status = FALSE;
		goto exit;
	}

	*PublicKeyLength = (DWORD) length;
	*PublicKey = (BYTE*) malloc(length);
	ptr = (BYTE*) (*PublicKey);

	i2d_PublicKey(pkey, &ptr);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return status;
}
Beispiel #2
0
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key)
{
	uint8* p;
	int length;
	boolean status = true;
	EVP_PKEY* pkey = NULL;

	pkey = X509_get_pubkey(cert->px509);

	if (!pkey)
	{
		printf("crypto_cert_get_public_key: X509_get_pubkey() failed\n");
		status = false;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);

	if (length < 1)
	{
		printf("crypto_cert_get_public_key: i2d_PublicKey() failed\n");
		status = false;
		goto exit;
	}

	freerdp_blob_alloc(public_key, length);
	p = (uint8*) public_key->data;
	i2d_PublicKey(pkey, &p);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return status;
}
Beispiel #3
0
int
crypto_cert_get_public_key(CryptoCert cert, DATABLOB * public_key)
{
	int length;
	int success = 1;
	EVP_PKEY *pkey = NULL;
	unsigned char *p;

	pkey = X509_get_pubkey(cert->px509);
	if (!pkey)
	{
		printf("crypto_cert_get_public_key: X509_get_pubkey() failed\n");
		success = 0;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);

	if (length < 1)
	{
		printf("crypto_cert_get_public_key: i2d_PublicKey() failed\n");
		success = 0;
		goto exit;
	}

	datablob_alloc(public_key, length);
	p = (unsigned char*) public_key->data;
	i2d_PublicKey(pkey, &p);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return success;
}
static int wrap_key(EVP_PKEY* pkey, int type, uint8_t** keyBlob, size_t* keyBlobLength) {
    /* Find the length of each size */
    int publicLen = i2d_PublicKey(pkey, NULL);
    int privateLen = i2d_PrivateKey(pkey, NULL);

    if (privateLen <= 0 || publicLen <= 0) {
        ALOGE("private or public key size was too big");
        return -1;
    }

    /* int type + int size + private key data + int size + public key data */
    *keyBlobLength = get_softkey_header_size() + sizeof(int) + sizeof(int) + privateLen
            + sizeof(int) + publicLen;

    UniquePtr<unsigned char[]> derData(new unsigned char[*keyBlobLength]);
    if (derData.get() == NULL) {
        ALOGE("could not allocate memory for key blob");
        return -1;
    }
    unsigned char* p = derData.get();

    /* Write the magic value for software keys. */
    p = add_softkey_header(p, *keyBlobLength);

    /* Write key type to allocated buffer */
    for (int i = sizeof(int) - 1; i >= 0; i--) {
        *p++ = (type >> (8*i)) & 0xFF;
    }

    /* Write public key to allocated buffer */
    for (int i = sizeof(int) - 1; i >= 0; i--) {
        *p++ = (publicLen >> (8*i)) & 0xFF;
    }
    if (i2d_PublicKey(pkey, &p) != publicLen) {
        logOpenSSLError("wrap_key");
        return -1;
    }

    /* Write private key to allocated buffer */
    for (int i = sizeof(int) - 1; i >= 0; i--) {
        *p++ = (privateLen >> (8*i)) & 0xFF;
    }
    if (i2d_PrivateKey(pkey, &p) != privateLen) {
        logOpenSSLError("wrap_key");
        return -1;
    }

    *keyBlob = derData.release();

    return 0;
}
Beispiel #5
0
int
tls_get_public_key(SSL *connection, DATABLOB *public_key)
{
	int length;
	int success = 1;
	X509 *cert = NULL;
	EVP_PKEY *pkey = NULL;
	unsigned char *p;

	cert = SSL_get_peer_certificate(connection);

	if (!cert)
	{
		printf("tls_get_public_key: SSL_get_peer_certificate() failed\n");
		success = 0;
		goto exit;
	}

	pkey = X509_get_pubkey(cert);

	if (!cert)
	{
		printf("tls_get_public_key: X509_get_pubkey() failed\n");
		success = 0;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);

	if (length < 1)
	{
		printf("tls_get_public_key: i2d_PublicKey() failed\n");
		success = 0;
		goto exit;
	}

	datablob_alloc(public_key, length);
	p = (unsigned char*) public_key->data;
	i2d_PublicKey(pkey, &p);

	exit:
		if (cert)
			X509_free(cert);
		if (pkey)
			EVP_PKEY_free(pkey);

	return success;
}
Beispiel #6
0
static char *
_SSL_get_obj_base64(void *s, int type)
{
	unsigned char *pt, *ppt;
	unsigned char *t;
	int len = 0;
	int i;


	switch (type) {
	    case 0:
		len = i2d_PublicKey(s, NULL);
		break;
	    case 1:
		len = i2d_PrivateKey(s, NULL);
		break;
	    case 2:
		len = i2d_X509(s, NULL);
		break;
	}
	if (len < 0)
		return (NULL);

	pt = ppt = mmalloc(len);

	switch (type) {
	    case 0:
		i2d_PublicKey(s, &pt);
		break;
	    case 1:
		i2d_PrivateKey(s, &pt);
		break;
	    case 2:
		i2d_X509(s, &pt);
		break;
	}

	t = mmalloc(len * 2 + 1);	/* + NULL */
	if ((i = EVP_EncodeBlock(t, ppt, len)) == -1) {
		fprintf(stderr, "_SSL_get_key_base64 :: EVP_EncodeBlock failed\n");
		exit(1);
	}
	free (ppt);

	return (t);
}
Beispiel #7
0
/* Get public key from server of TLS 1.0 connection */
RD_BOOL
tcp_tls_get_server_pubkey(STREAM s)
{
	X509 *cert = NULL;
	EVP_PKEY *pkey = NULL;

	s->data = s->p = NULL;
	s->size = 0;

	if (g_ssl == NULL)
		goto out;

	cert = SSL_get_peer_certificate(g_ssl);
	if (cert == NULL)
	{
		error("tcp_tls_get_server_pubkey: SSL_get_peer_certificate() failed\n");
		goto out;
	}

	pkey = X509_get_pubkey(cert);
	if (pkey == NULL)
	{
		error("tcp_tls_get_server_pubkey: X509_get_pubkey() failed\n");
		goto out;
	}

	s->size = i2d_PublicKey(pkey, NULL);
	if (s->size < 1)
	{
		error("tcp_tls_get_server_pubkey: i2d_PublicKey() failed\n");
		goto out;
	}

	s->data = s->p = xmalloc(s->size);
	i2d_PublicKey(pkey, &s->p);
	s->p = s->data;
	s->end = s->p + s->size;

      out:
	if (cert)
		X509_free(cert);
	if (pkey)
		EVP_PKEY_free(pkey);
	return (s->size != 0);
}
Beispiel #8
0
BOOL crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* PublicKeyLength)
{
	BYTE* ptr;
	int length;
	BOOL status = TRUE;
	EVP_PKEY* pkey = NULL;

	pkey = X509_get_pubkey(cert->px509);
	if (!pkey)
	{
		WLog_ERR(TAG,  "X509_get_pubkey() failed");
		status = FALSE;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);
	if (length < 1)
	{
		WLog_ERR(TAG,  "i2d_PublicKey() failed");
		status = FALSE;
		goto exit;
	}

	*PublicKeyLength = (DWORD) length;
	*PublicKey = (BYTE*) malloc(length);
	ptr = (BYTE*) (*PublicKey);
	if (!ptr)
	{
		status = FALSE;
		goto exit;
	}

	i2d_PublicKey(pkey, &ptr);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return status;
}
Beispiel #9
0
bool Certificate::createDigest(unsigned char digest[SHA_DIGEST_LENGTH], const string data) const
{
	SHA_CTX ctx;
        unsigned char *b, *bp;
        int len;
        
        len = i2d_PublicKey(pubKey, NULL);
        
        if (len < 0)
                return false;
        
        bp = b = new unsigned char[len+1];
        
        if (!b)
                return false;

        len = i2d_PublicKey(pubKey, &bp);
  
        if (len < 0) {
                delete [] b;
                return false;
        }

	SHA1_Init(&ctx);

	SHA1_Update(&ctx, data.c_str(), data.length());
	SHA1_Update(&ctx, subject.c_str(), subject.length());
	SHA1_Update(&ctx, issuer.c_str(), issuer.length());;
	SHA1_Update(&ctx, validity.c_str(), validity.length());
	SHA1_Update(&ctx, b, len);

	SHA1_Final(digest, &ctx);

        delete [] b;

	return true;
}
Beispiel #10
0
boolean crypto_cert_get_public_key(CryptoCert cert, BYTE** PublicKey, DWORD* PublicKeyLength)
{
	BYTE* ptr;
	int length;
	boolean status = true;
	EVP_PKEY* pkey = NULL;

	pkey = X509_get_pubkey(cert->px509);

	if (!pkey)
	{
		printf("crypto_cert_get_public_key: X509_get_pubkey() failed\n");
		status = false;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);

	if (length < 1)
	{
		printf("crypto_cert_get_public_key: i2d_PublicKey() failed\n");
		status = false;
		goto exit;
	}

	*PublicKeyLength = (DWORD) length;
	*PublicKey = (BYTE*) malloc(length);
	ptr = (BYTE*) (*PublicKey);

	i2d_PublicKey(pkey, &ptr);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return status;
}
std::string get_public_key_from_cert(X509* cert)
{
    std::string result;

    EVP_PKEY *pKey =  X509_get_pubkey(cert);
    
    if(!pKey)
    {
        return result;
    }

    std::size_t keyLen = i2d_PublicKey(pKey, NULL);

    if(keyLen > 0)
    {
        std::vector<unsigned char> buf(keyLen, 0x00);

        unsigned char *buffer = &buf[0];

        i2d_PublicKey(pKey, &buffer);

        std::stringstream ssResult;

        ssResult << std::hex;

        for(auto value: buf)
        {
            ssResult << std::setw(2) << std::setfill('0') << (int) (value);
        }

        result = ssResult.str();
    }

    EVP_PKEY_free(pKey);

    return result; 
}
Beispiel #12
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;
	}
Beispiel #13
0
static LUA_FUNCTION(openssl_pkey_export)
{
  EVP_PKEY * key;
  int ispriv = 0;
  int exraw = 0;
  int expem = 1;
  size_t passphrase_len = 0;
  BIO * bio_out = NULL;
  int ret = 0;
  const EVP_CIPHER * cipher;
  const char * passphrase = NULL;

  key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey");
  ispriv = openssl_pkey_is_private(key);

  if (!lua_isnoneornil(L, 2))
    expem = lua_toboolean(L, 2);

  if (expem)
  {
    if (!lua_isnoneornil(L, 3))
      exraw = lua_toboolean(L, 3);
    passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len);
  } else
  {
    passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len);
  }

  if (passphrase)
  {
    cipher = (EVP_CIPHER *) EVP_des_ede3_cbc();
  }
  else
  {
    cipher = NULL;
  }

  bio_out = BIO_new(BIO_s_mem());
  if (expem)
  {
    if (exraw==0)
    {
      ret = ispriv ?
        PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) :
        PEM_write_bio_PUBKEY(bio_out, key);
    }
    else
    {
      /* export raw key format */
      switch (EVP_PKEY_type(key->type))
      {
      case EVP_PKEY_RSA:
      case EVP_PKEY_RSA2:
        ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
          : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa);
      break;
      case EVP_PKEY_DSA:
      case EVP_PKEY_DSA2:
      case EVP_PKEY_DSA3:
      case EVP_PKEY_DSA4:
      {
        ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
          : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa);
      }
      break;
      case EVP_PKEY_DH:
        ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh);
      break;
#ifndef OPENSSL_NO_EC
      case EVP_PKEY_EC:
        ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL)
        : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec);
      break;
#endif
      default:
      ret = 0;
      break;
      }
    }
  }
  else
  {
    if (ispriv)
    {
      if (passphrase == NULL)
      {
        ret = i2d_PrivateKey_bio(bio_out, key);
      } else
      {
        ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL);
      }
    } else
    {
      int l;
      l = i2d_PublicKey(key, NULL);
      if (l > 0)
      {
        unsigned char* p = malloc(l);
        unsigned char* pp = p;
        l = i2d_PublicKey(key, &pp);
        if (l > 0)
        {
          BIO_write(bio_out, p, l);
          ret = 1;
        } else
          ret = 0;
        free(p);
      } else
        ret = 0;
    }
  }

  
  if (ret)
  {
    char * bio_mem_ptr;
    long bio_mem_len;

    bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr);

    lua_pushlstring(L, bio_mem_ptr, bio_mem_len);
    ret  = 1;
  }

  if (bio_out)
  {
    BIO_free(bio_out);
  }
  return ret;
}
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;
	}