We do the below for this operation:
1>How we convert public part of 'EVP_PKEY' structure to 'unsigned char*
//Extract a public key from a PKEY struct.
ec_copy_public(EVP_PKEY *pKey, uint8_t *keybuf)
EC_KEY *pEcKey;
uint8_t encoded_key[MAX_KEYLEN_X962];
uint8_t *pMem;
int keylen = 0;
/* Get the EC_KEY struct pointer. */
pEcKey = (EC_KEY *)EVP_PKEY_get0(pKey);
/* Extract the private key from the EC key struct. */
if (pEcKey) {
pMem = encoded_key;
keylen = i2o_ECPublicKey(pEcKey, &pMem);
/* Copy the decoded public key into the provided buffer. */
if (keylen) {
keylen = ipsec_ec_x962_decode(pEcKey, encoded_key, keylen, keybuf);
//fn defined in the end
}
}
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2>How we get the peerkey to pass to EVP_PKEY_derive_set_peer(pctx, peerkey);
//The below function takes a character string as input and converts it to a
public key.
Prototype:
EVP_PKEY *ec_create_static_public(uint8_t *public_key, int keylen, int curve)
EC_KEY *pEcKey = NULL;
EC_KEY *pEcKeyTemp;
uint8_t encoded_key[MAX_KEYLEN_X962];
const uint8_t *pMem;
EC_POINT *pEcPoint = NULL;
BIGNUM *pBignum = NULL;
EVP_PKEY *pKey = NULL;
switch(curve) {
case NID_secp384r1:
pEcKey = EC_KEY_new_by_curve_name(curve);
break;
default:
pEcKey = NULL;
}
/* Encode the public key string into X9.62 format. */ defined later
ec_x962_encode(pEcKey, public_key, keylen, encoded_key);
pMem = encoded_key;
pEcKeyTemp = pEcKey;
/* Place the encoded public key in the EC_KEY struct. */
pEcKeyTemp = o2i_ECPublicKey(&pEcKeyTemp, &pMem, keylen);
/* Allocate an EVP_PKEY struct for the EC_KEY. */
pKey = EVP_PKEY_new();
/* Assign the public key to the EVP_PKEY wrapper. */
EVP_PKEY_assign_EC_KEY(pKey, pEcKey);
pEcKey = NULL;
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int
ec_x962_encode(EC_KEY *pEcKey, uint8_t *key, int keylen, uint8_t *conv)
{
point_conversion_form_t form;
/* Get the conversion format. */
form = EC_KEY_get_conv_form(pEcKey);
/* Make sure the format is supported. If so, the first byte of the encoded
data will be the format identifier. */
switch (form) {
case POINT_CONVERSION_UNCOMPRESSED:
conv[0] = POINT_CONVERSION_UNCOMPRESSED;
conv++;
break;
case POINT_CONVERSION_COMPRESSED:
case POINT_CONVERSION_HYBRID:
default:
keylen = 0;
break;
}
/* If the format is valid, copy the key into the destination buffer. */
if (keylen) {
memcpy(conv, key, keylen);
keylen++;
}
return(keylen);
}
Thanks,
Bala
--------------------------------------------
On Sun, 6/29/14, pratyush parimal <[email protected]> wrote:
Subject: Fwd: Converting public part of 'EVP_PKEY' structure to 'unsigned
char*' , and back.
To: [email protected]
Date: Sunday, June 29, 2014, 11:43 PM
Hi all,
Did anyone have any luck with this
one?
Thanks,Pratyush Parimal.
---------- Forwarded
message ----------
From: pratyush
parimal <[email protected]>
Date: Wed, Jun 25, 2014 at 10:43 AM
Subject: Converting public part of 'EVP_PKEY'
structure to 'unsigned char*' , and back.
To: [email protected]
Hi all,
I was trying to use ECDH (in OpenSSL v1.0.1f) for
a project, and after generating the EVP_PKEY structure, I
needed to extract its public key and send it over to the
other party. I was unable to find a straightforward way
which worked for me.
What I tried was this:
EVP_PKEY*extract_peerkey_3(EVP_PKEY*
EVP_PKEY_both) //'both' meaning it contains public +
private{ int len =
0;
len =
i2d_PUBKEY(EVP_PKEY_both, NULL); //find out required buffer
length unsigned char *buf,
*p;
buf = (unsigned
char*) malloc(len); //allocate p =
buf; len =
i2d_PUBKEY(EVP_PKEY_both, &p);
const
unsigned char* p2 = buf; EVP_PKEY*
EVP_PKEY_public = d2i_PUBKEY(NULL, &p2, len);
if
(EVP_PKEY_public == NULL) { handleCryptoError("d2i
failed", ERR_get_error());
}
return
EVP_PKEY_public;}
The function doesn't throw an error, but when
I pass the returned 'EVP_PKEY_public' structure to
the function 'EVP_PKEY_derive_set_peer', I get an
error message "error:10071065:elliptic curve
routines:EC_POINT_cmp:incompatible objects".
I also tried to follow the steps given at
http://stackoverflow.com/questions/18155559/how-does-one-access-the-raw-ecdh-public-key-private-key-and-params-inside-opens.
When i reconstruct the EVP_PKEY using the steps EC_POINT_oct2point()
-> EC_KEY_set_public_key()
-> EVP_PKEY_set1_EC_KEY(),
the resulting EVP_PKEY does work for me. In fact I'm
able to derive the same secret on both sides using this
sequence, but I feel it's too roundabout.
I
also saw the following:
http://marc.info/?l=openssl-users&m=116474297608094&w=2,
which talks about using 'i2d_PUBKEY',
but I haven't been able to make it work so
far.
Is my usage of d2i_PUBKEY or i2d_PUBKEY wrong in
some way? Does anyone know how to use them
properly?Any help will be
appreciated.
Thanks!
Pratyush Parimal
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]