Complete key derivation support.
This commit is contained in:
parent
3be34589e8
commit
ffb1ac674c
4
CHANGES
4
CHANGES
@ -4,6 +4,10 @@
|
||||
|
||||
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Add support for key derivation (agreement) in the API, DH method and
|
||||
pkeyutl.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
|
||||
public and private key formats. As a side effect these add additional
|
||||
command line functionality not previously available: DSA signatures can be
|
||||
|
125
apps/pkeyutl.c
125
apps/pkeyutl.c
@ -74,7 +74,10 @@ static void usage(void);
|
||||
|
||||
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
char *keyfile, int keyform, int key_type,
|
||||
char *passargin, int pkey_op, char *engine);
|
||||
char *passargin, int pkey_op, ENGINE *e);
|
||||
|
||||
static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
|
||||
const char *file);
|
||||
|
||||
int MAIN(int argc, char **);
|
||||
|
||||
@ -82,9 +85,9 @@ int MAIN(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *infile = NULL, *outfile = NULL, *sigfile = NULL;
|
||||
char *engine = NULL;
|
||||
ENGINE *e = NULL;
|
||||
int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
|
||||
int keyform = FORMAT_PEM;
|
||||
int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
|
||||
char badarg = 0, rev = 0;
|
||||
char hexdump = 0, asn1parse = 0;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
@ -131,7 +134,7 @@ int MAIN(int argc, char **argv)
|
||||
{
|
||||
ctx = init_ctx(&keysize,
|
||||
*(++argv), keyform, key_type,
|
||||
passargin, pkey_op, engine);
|
||||
passargin, pkey_op, e);
|
||||
if (!ctx)
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
@ -141,11 +144,23 @@ int MAIN(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(*argv,"-peerkey"))
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
|
||||
badarg = 1;
|
||||
}
|
||||
else if (!strcmp(*argv,"-passin"))
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
passargin= *(++argv);
|
||||
}
|
||||
else if (strcmp(*argv,"-peerform") == 0)
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
peerform=str2fmt(*(++argv));
|
||||
}
|
||||
else if (strcmp(*argv,"-keyform") == 0)
|
||||
{
|
||||
if (--argc < 1) badarg = 1;
|
||||
@ -157,7 +172,7 @@ int MAIN(int argc, char **argv)
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
else
|
||||
engine = *(++argv);
|
||||
e = setup_engine(bio_err, *(++argv), 0);
|
||||
}
|
||||
#endif
|
||||
else if(!strcmp(*argv, "-pubin"))
|
||||
@ -180,14 +195,16 @@ int MAIN(int argc, char **argv)
|
||||
pkey_op = EVP_PKEY_OP_ENCRYPT;
|
||||
else if(!strcmp(*argv, "-decrypt"))
|
||||
pkey_op = EVP_PKEY_OP_DECRYPT;
|
||||
else if(!strcmp(*argv, "-derive"))
|
||||
pkey_op = EVP_PKEY_OP_DERIVE;
|
||||
else if (strcmp(*argv,"-pkeyopt") == 0)
|
||||
{
|
||||
if (--argc < 1)
|
||||
badarg = 1;
|
||||
if (!ctx)
|
||||
else if (!ctx)
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
"-param command before -inkey\n");
|
||||
"-pkeyopt command before -inkey\n");
|
||||
badarg = 1;
|
||||
}
|
||||
else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
|
||||
@ -228,17 +245,21 @@ int MAIN(int argc, char **argv)
|
||||
/* FIXME: seed PRNG only if needed */
|
||||
app_RAND_load_file(NULL, bio_err, 0);
|
||||
|
||||
if(infile)
|
||||
if (pkey_op != EVP_PKEY_OP_DERIVE)
|
||||
{
|
||||
if(!(in = BIO_new_file(infile, "rb")))
|
||||
if(infile)
|
||||
{
|
||||
BIO_printf(bio_err, "Error Reading Input File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
if(!(in = BIO_new_file(infile, "rb")))
|
||||
{
|
||||
BIO_puts(bio_err,
|
||||
"Error Opening Input File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
}
|
||||
else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
|
||||
if(outfile)
|
||||
{
|
||||
@ -280,24 +301,28 @@ int MAIN(int argc, char **argv)
|
||||
|
||||
buf_out = OPENSSL_malloc(keysize);
|
||||
|
||||
/* Read the input data */
|
||||
buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
|
||||
if(buf_inlen <= 0)
|
||||
if (in)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading input Data\n");
|
||||
exit(1);
|
||||
}
|
||||
if(rev)
|
||||
{
|
||||
int i;
|
||||
unsigned char ctmp;
|
||||
for(i = 0; i < buf_inlen/2; i++)
|
||||
/* Read the input data */
|
||||
buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
|
||||
if(buf_inlen <= 0)
|
||||
{
|
||||
ctmp = buf_in[i];
|
||||
buf_in[i] = buf_in[buf_inlen - 1 - i];
|
||||
buf_in[buf_inlen - 1 - i] = ctmp;
|
||||
BIO_printf(bio_err, "Error reading input Data\n");
|
||||
exit(1);
|
||||
}
|
||||
if(rev)
|
||||
{
|
||||
int i;
|
||||
unsigned char ctmp;
|
||||
for(i = 0; i < buf_inlen/2; i++)
|
||||
{
|
||||
ctmp = buf_in[i];
|
||||
buf_in[i] = buf_in[buf_inlen - 1 - i];
|
||||
buf_in[buf_inlen - 1 - i] = ctmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(pkey_op)
|
||||
{
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
@ -330,6 +355,10 @@ int MAIN(int argc, char **argv)
|
||||
goto end;
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive(ctx, buf_out, &buf_outlen);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(rv <= 0)
|
||||
@ -387,15 +416,15 @@ static void usage()
|
||||
|
||||
static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
char *keyfile, int keyform, int key_type,
|
||||
char *passargin, int pkey_op, char *engine)
|
||||
char *passargin, int pkey_op, ENGINE *e)
|
||||
{
|
||||
ENGINE *e = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
char *passin = NULL;
|
||||
int rv = -1;
|
||||
X509 *x;
|
||||
if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT))
|
||||
if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
|
||||
|| (pkey_op == EVP_PKEY_OP_DERIVE))
|
||||
&& (key_type != KEY_PRIVKEY))
|
||||
{
|
||||
BIO_printf(bio_err, "A private key is needed for this operation\n");
|
||||
@ -435,7 +464,7 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
ctx = EVP_PKEY_CTX_new(pkey, e);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
@ -463,6 +492,10 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive_init(ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv <= 0)
|
||||
@ -481,3 +514,31 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
|
||||
|
||||
}
|
||||
|
||||
static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
|
||||
const char *file)
|
||||
{
|
||||
EVP_PKEY *peer = NULL;
|
||||
int ret;
|
||||
if (!ctx)
|
||||
{
|
||||
BIO_puts(err, "-peerkey command before -inkey\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
|
||||
|
||||
if (!peer)
|
||||
{
|
||||
BIO_printf(bio_err, "Error reading peer key %s\n", file);
|
||||
ERR_print_errors(err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = EVP_PKEY_derive_set_peer(ctx, peer);
|
||||
|
||||
EVP_PKEY_free(peer);
|
||||
if (ret <= 0)
|
||||
ERR_print_errors(err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -234,6 +234,7 @@ void ERR_load_DH_strings(void);
|
||||
#define DH_F_DH_PUB_ENCODE 109
|
||||
#define DH_F_GENERATE_KEY 103
|
||||
#define DH_F_GENERATE_PARAMETERS 104
|
||||
#define DH_F_PKEY_DH_DERIVE 112
|
||||
#define DH_F_PKEY_DH_KEYGEN 113
|
||||
|
||||
/* Reason codes. */
|
||||
@ -242,6 +243,7 @@ void ERR_load_DH_strings(void);
|
||||
#define DH_R_BN_ERROR 106
|
||||
#define DH_R_DECODE_ERROR 104
|
||||
#define DH_R_INVALID_PUBKEY 102
|
||||
#define DH_R_KEYS_NOT_SET 108
|
||||
#define DH_R_NO_PARAMETERS_SET 107
|
||||
#define DH_R_NO_PRIVATE_VALUE 100
|
||||
#define DH_R_PARAMETER_ENCODING_ERROR 105
|
||||
|
@ -397,6 +397,15 @@ static int dh_bits(const EVP_PKEY *pkey)
|
||||
return BN_num_bits(pkey->pkey.dh->p);
|
||||
}
|
||||
|
||||
static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
|
||||
BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
{
|
||||
BIGNUM *a;
|
||||
@ -409,20 +418,18 @@ static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
|
||||
if ((a=BN_dup(from->pkey.dh->g)) == NULL)
|
||||
return 0;
|
||||
if (to->pkey.dsa->g != NULL)
|
||||
if (to->pkey.dh->g != NULL)
|
||||
BN_free(to->pkey.dh->g);
|
||||
to->pkey.dh->g=a;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
static int dh_missing_parameters(const EVP_PKEY *a)
|
||||
{
|
||||
if ( BN_cmp(a->pkey.dh->p,b->pkey.dsa->p) ||
|
||||
BN_cmp(a->pkey.dh->g,b->pkey.dsa->g))
|
||||
return 0;
|
||||
else
|
||||
if (!a->pkey.dh->p || !a->pkey.dh->g)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
@ -481,7 +488,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
|
||||
|
||||
dh_param_decode,
|
||||
dh_param_encode,
|
||||
0,
|
||||
dh_missing_parameters,
|
||||
dh_copy_parameters,
|
||||
dh_cmp_parameters,
|
||||
dh_param_print,
|
||||
|
@ -82,6 +82,7 @@ static ERR_STRING_DATA DH_str_functs[]=
|
||||
{ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"},
|
||||
{ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"},
|
||||
{ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"},
|
||||
{ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"},
|
||||
{ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"},
|
||||
{0,NULL}
|
||||
};
|
||||
@ -93,6 +94,7 @@ static ERR_STRING_DATA DH_str_reasons[]=
|
||||
{ERR_REASON(DH_R_BN_ERROR) ,"bn error"},
|
||||
{ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"},
|
||||
{ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"},
|
||||
{ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"},
|
||||
{ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"},
|
||||
{ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"},
|
||||
{ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR),"parameter encoding error"},
|
||||
|
@ -115,11 +115,16 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
dctx->generator = p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_PEER_KEY:
|
||||
/* Default behaviour is OK */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
const char *type, const char *value)
|
||||
@ -182,6 +187,22 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
return DH_generate_key(pkey->pkey.dh);
|
||||
}
|
||||
|
||||
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *keylen)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx->pkey || !ctx->peerkey)
|
||||
{
|
||||
DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
|
||||
ctx->pkey->pkey.dh);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*keylen = ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD dh_pkey_meth =
|
||||
{
|
||||
EVP_PKEY_DH,
|
||||
@ -209,7 +230,8 @@ const EVP_PKEY_METHOD dh_pkey_meth =
|
||||
|
||||
0,0,
|
||||
|
||||
0,0,
|
||||
0,
|
||||
pkey_dh_derive,
|
||||
|
||||
pkey_dh_ctrl,
|
||||
pkey_dh_ctrl_str
|
||||
|
@ -933,6 +933,7 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
EVP_PKEY_CTRL_MD, 0, (void *)md)
|
||||
|
||||
#define EVP_PKEY_CTRL_MD 1
|
||||
#define EVP_PKEY_CTRL_PEER_KEY 2
|
||||
|
||||
#define EVP_PKEY_ALG_CTRL 0x1000
|
||||
|
||||
@ -972,6 +973,10 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out, int *outlen,
|
||||
const unsigned char *in, int inlen);
|
||||
|
||||
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
|
||||
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
|
||||
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *keylen);
|
||||
|
||||
typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
|
||||
|
||||
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
|
||||
@ -1018,6 +1023,7 @@ void ERR_load_EVP_strings(void);
|
||||
#define EVP_F_EVP_PKEY_DECRYPT_OLD 151
|
||||
#define EVP_F_EVP_PKEY_DERIVE 153
|
||||
#define EVP_F_EVP_PKEY_DERIVE_INIT 154
|
||||
#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155
|
||||
#define EVP_F_EVP_PKEY_ENCRYPT 105
|
||||
#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139
|
||||
#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152
|
||||
@ -1061,6 +1067,7 @@ void ERR_load_EVP_strings(void);
|
||||
#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138
|
||||
#define EVP_R_DECODE_ERROR 114
|
||||
#define EVP_R_DIFFERENT_KEY_TYPES 101
|
||||
#define EVP_R_DIFFERENT_PARAMETERS 153
|
||||
#define EVP_R_ENCODE_ERROR 115
|
||||
#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119
|
||||
#define EVP_R_EXPECTING_AN_RSA_KEY 127
|
||||
@ -1080,6 +1087,7 @@ void ERR_load_EVP_strings(void);
|
||||
#define EVP_R_NO_CIPHER_SET 131
|
||||
#define EVP_R_NO_DIGEST_SET 139
|
||||
#define EVP_R_NO_DSA_PARAMETERS 116
|
||||
#define EVP_R_NO_KEY_SET 154
|
||||
#define EVP_R_NO_OPERATION_SET 149
|
||||
#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
|
||||
#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
|
||||
|
@ -97,6 +97,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_DERIVE"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_DERIVE_INIT"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_DERIVE_SET_PEER"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
|
||||
@ -143,6 +144,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
||||
{ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
|
||||
{ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"},
|
||||
{ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"},
|
||||
{ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"},
|
||||
{ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"},
|
||||
{ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
|
||||
{ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"},
|
||||
@ -162,6 +164,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
||||
{ERR_REASON(EVP_R_NO_CIPHER_SET) ,"no cipher set"},
|
||||
{ERR_REASON(EVP_R_NO_DIGEST_SET) ,"no digest set"},
|
||||
{ERR_REASON(EVP_R_NO_DSA_PARAMETERS) ,"no dsa parameters"},
|
||||
{ERR_REASON(EVP_R_NO_KEY_SET) ,"no key set"},
|
||||
{ERR_REASON(EVP_R_NO_OPERATION_SET) ,"no operation set"},
|
||||
{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED),"no sign function configured"},
|
||||
{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
|
||||
|
@ -262,6 +262,66 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive || !ctx->pmeth->ctrl)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_DERIVE)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 2)
|
||||
return 1;
|
||||
|
||||
if (!ctx->pkey)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->pkey->type != peer->type)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_missing_parameters(peer) &&
|
||||
!EVP_PKEY_cmp_parameters(ctx->pkey, peer))
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
|
||||
EVP_R_DIFFERENT_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->peerkey = peer;
|
||||
|
||||
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
ctx->peerkey = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *pkeylen)
|
||||
{
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
|
||||
|
@ -153,6 +153,8 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
||||
ctx->pmeth->cleanup(ctx);
|
||||
if (ctx->pkey)
|
||||
EVP_PKEY_free(ctx->pkey);
|
||||
if (ctx->peerkey)
|
||||
EVP_PKEY_free(ctx->peerkey);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user