1238384Sjkim/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2238384Sjkim * project 2006. 3238384Sjkim */ 4238384Sjkim/* ==================================================================== 5238384Sjkim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 6238384Sjkim * 7238384Sjkim * Redistribution and use in source and binary forms, with or without 8238384Sjkim * modification, are permitted provided that the following conditions 9238384Sjkim * are met: 10238384Sjkim * 11238384Sjkim * 1. Redistributions of source code must retain the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer. 13238384Sjkim * 14238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 15238384Sjkim * notice, this list of conditions and the following disclaimer in 16238384Sjkim * the documentation and/or other materials provided with the 17238384Sjkim * distribution. 18238384Sjkim * 19238384Sjkim * 3. All advertising materials mentioning features or use of this 20238384Sjkim * software must display the following acknowledgment: 21238384Sjkim * "This product includes software developed by the OpenSSL Project 22238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 23238384Sjkim * 24238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 25238384Sjkim * endorse or promote products derived from this software without 26238384Sjkim * prior written permission. For written permission, please contact 27238384Sjkim * licensing@OpenSSL.org. 28238384Sjkim * 29238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 30238384Sjkim * nor may "OpenSSL" appear in their names without prior written 31238384Sjkim * permission of the OpenSSL Project. 32238384Sjkim * 33238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 34238384Sjkim * acknowledgment: 35238384Sjkim * "This product includes software developed by the OpenSSL Project 36238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 37238384Sjkim * 38238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 39238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 41238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 42238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 47238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 49238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 50238384Sjkim * ==================================================================== 51238384Sjkim * 52238384Sjkim * This product includes cryptographic software written by Eric Young 53238384Sjkim * (eay@cryptsoft.com). This product includes software written by Tim 54238384Sjkim * Hudson (tjh@cryptsoft.com). 55238384Sjkim * 56238384Sjkim */ 57238384Sjkim 58238384Sjkim 59238384Sjkim#include "apps.h" 60238384Sjkim#include <string.h> 61238384Sjkim#include <openssl/err.h> 62238384Sjkim#include <openssl/pem.h> 63238384Sjkim#include <openssl/evp.h> 64238384Sjkim 65238384Sjkim#define KEY_PRIVKEY 1 66238384Sjkim#define KEY_PUBKEY 2 67238384Sjkim#define KEY_CERT 3 68238384Sjkim 69238384Sjkimstatic void usage(void); 70238384Sjkim 71238384Sjkim#undef PROG 72238384Sjkim 73238384Sjkim#define PROG pkeyutl_main 74238384Sjkim 75238384Sjkimstatic EVP_PKEY_CTX *init_ctx(int *pkeysize, 76238384Sjkim char *keyfile, int keyform, int key_type, 77238384Sjkim char *passargin, int pkey_op, ENGINE *e); 78238384Sjkim 79238384Sjkimstatic int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, 80238384Sjkim const char *file); 81238384Sjkim 82238384Sjkimstatic int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 83238384Sjkim unsigned char *out, size_t *poutlen, 84238384Sjkim unsigned char *in, size_t inlen); 85238384Sjkim 86238384Sjkimint MAIN(int argc, char **); 87238384Sjkim 88238384Sjkimint MAIN(int argc, char **argv) 89238384Sjkim{ 90238384Sjkim BIO *in = NULL, *out = NULL; 91238384Sjkim char *infile = NULL, *outfile = NULL, *sigfile = NULL; 92238384Sjkim ENGINE *e = NULL; 93238384Sjkim int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; 94238384Sjkim int keyform = FORMAT_PEM, peerform = FORMAT_PEM; 95238384Sjkim char badarg = 0, rev = 0; 96238384Sjkim char hexdump = 0, asn1parse = 0; 97238384Sjkim EVP_PKEY_CTX *ctx = NULL; 98238384Sjkim char *passargin = NULL; 99238384Sjkim int keysize = -1; 100238384Sjkim 101238384Sjkim unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; 102238384Sjkim size_t buf_outlen; 103238384Sjkim int buf_inlen = 0, siglen = -1; 104238384Sjkim 105238384Sjkim int ret = 1, rv = -1; 106238384Sjkim 107238384Sjkim argc--; 108238384Sjkim argv++; 109238384Sjkim 110238384Sjkim if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 111238384Sjkim 112238384Sjkim if (!load_config(bio_err, NULL)) 113238384Sjkim goto end; 114238384Sjkim ERR_load_crypto_strings(); 115238384Sjkim OpenSSL_add_all_algorithms(); 116238384Sjkim 117238384Sjkim while(argc >= 1) 118238384Sjkim { 119238384Sjkim if (!strcmp(*argv,"-in")) 120238384Sjkim { 121238384Sjkim if (--argc < 1) badarg = 1; 122238384Sjkim else infile= *(++argv); 123238384Sjkim } 124238384Sjkim else if (!strcmp(*argv,"-out")) 125238384Sjkim { 126238384Sjkim if (--argc < 1) badarg = 1; 127238384Sjkim else outfile= *(++argv); 128238384Sjkim } 129238384Sjkim else if (!strcmp(*argv,"-sigfile")) 130238384Sjkim { 131238384Sjkim if (--argc < 1) badarg = 1; 132238384Sjkim else sigfile= *(++argv); 133238384Sjkim } 134238384Sjkim else if(!strcmp(*argv, "-inkey")) 135238384Sjkim { 136238384Sjkim if (--argc < 1) 137238384Sjkim badarg = 1; 138238384Sjkim else 139238384Sjkim { 140238384Sjkim ctx = init_ctx(&keysize, 141238384Sjkim *(++argv), keyform, key_type, 142238384Sjkim passargin, pkey_op, e); 143238384Sjkim if (!ctx) 144238384Sjkim { 145238384Sjkim BIO_puts(bio_err, 146238384Sjkim "Error initializing context\n"); 147238384Sjkim ERR_print_errors(bio_err); 148238384Sjkim badarg = 1; 149238384Sjkim } 150238384Sjkim } 151238384Sjkim } 152238384Sjkim else if (!strcmp(*argv,"-peerkey")) 153238384Sjkim { 154238384Sjkim if (--argc < 1) 155238384Sjkim badarg = 1; 156238384Sjkim else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) 157238384Sjkim badarg = 1; 158238384Sjkim } 159238384Sjkim else if (!strcmp(*argv,"-passin")) 160238384Sjkim { 161238384Sjkim if (--argc < 1) badarg = 1; 162238384Sjkim else passargin= *(++argv); 163238384Sjkim } 164238384Sjkim else if (strcmp(*argv,"-peerform") == 0) 165238384Sjkim { 166238384Sjkim if (--argc < 1) badarg = 1; 167238384Sjkim else peerform=str2fmt(*(++argv)); 168238384Sjkim } 169238384Sjkim else if (strcmp(*argv,"-keyform") == 0) 170238384Sjkim { 171238384Sjkim if (--argc < 1) badarg = 1; 172238384Sjkim else keyform=str2fmt(*(++argv)); 173238384Sjkim } 174238384Sjkim#ifndef OPENSSL_NO_ENGINE 175238384Sjkim else if(!strcmp(*argv, "-engine")) 176238384Sjkim { 177238384Sjkim if (--argc < 1) 178238384Sjkim badarg = 1; 179238384Sjkim else 180238384Sjkim e = setup_engine(bio_err, *(++argv), 0); 181238384Sjkim } 182238384Sjkim#endif 183238384Sjkim else if(!strcmp(*argv, "-pubin")) 184238384Sjkim key_type = KEY_PUBKEY; 185238384Sjkim else if(!strcmp(*argv, "-certin")) 186238384Sjkim key_type = KEY_CERT; 187238384Sjkim else if(!strcmp(*argv, "-asn1parse")) 188238384Sjkim asn1parse = 1; 189238384Sjkim else if(!strcmp(*argv, "-hexdump")) 190238384Sjkim hexdump = 1; 191238384Sjkim else if(!strcmp(*argv, "-sign")) 192238384Sjkim pkey_op = EVP_PKEY_OP_SIGN; 193238384Sjkim else if(!strcmp(*argv, "-verify")) 194238384Sjkim pkey_op = EVP_PKEY_OP_VERIFY; 195238384Sjkim else if(!strcmp(*argv, "-verifyrecover")) 196238384Sjkim pkey_op = EVP_PKEY_OP_VERIFYRECOVER; 197238384Sjkim else if(!strcmp(*argv, "-rev")) 198238384Sjkim rev = 1; 199238384Sjkim else if(!strcmp(*argv, "-encrypt")) 200238384Sjkim pkey_op = EVP_PKEY_OP_ENCRYPT; 201238384Sjkim else if(!strcmp(*argv, "-decrypt")) 202238384Sjkim pkey_op = EVP_PKEY_OP_DECRYPT; 203238384Sjkim else if(!strcmp(*argv, "-derive")) 204238384Sjkim pkey_op = EVP_PKEY_OP_DERIVE; 205238384Sjkim else if (strcmp(*argv,"-pkeyopt") == 0) 206238384Sjkim { 207238384Sjkim if (--argc < 1) 208238384Sjkim badarg = 1; 209238384Sjkim else if (!ctx) 210238384Sjkim { 211238384Sjkim BIO_puts(bio_err, 212238384Sjkim "-pkeyopt command before -inkey\n"); 213238384Sjkim badarg = 1; 214238384Sjkim } 215238384Sjkim else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) 216238384Sjkim { 217238384Sjkim BIO_puts(bio_err, "parameter setting error\n"); 218238384Sjkim ERR_print_errors(bio_err); 219238384Sjkim goto end; 220238384Sjkim } 221238384Sjkim } 222238384Sjkim else badarg = 1; 223238384Sjkim if(badarg) 224238384Sjkim { 225238384Sjkim usage(); 226238384Sjkim goto end; 227238384Sjkim } 228238384Sjkim argc--; 229238384Sjkim argv++; 230238384Sjkim } 231238384Sjkim 232238384Sjkim if (!ctx) 233238384Sjkim { 234238384Sjkim usage(); 235238384Sjkim goto end; 236238384Sjkim } 237238384Sjkim 238238384Sjkim if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) 239238384Sjkim { 240238384Sjkim BIO_puts(bio_err, "Signature file specified for non verify\n"); 241238384Sjkim goto end; 242238384Sjkim } 243238384Sjkim 244238384Sjkim if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) 245238384Sjkim { 246238384Sjkim BIO_puts(bio_err, "No signature file specified for verify\n"); 247238384Sjkim goto end; 248238384Sjkim } 249238384Sjkim 250238384Sjkim/* FIXME: seed PRNG only if needed */ 251238384Sjkim app_RAND_load_file(NULL, bio_err, 0); 252238384Sjkim 253238384Sjkim if (pkey_op != EVP_PKEY_OP_DERIVE) 254238384Sjkim { 255238384Sjkim if(infile) 256238384Sjkim { 257238384Sjkim if(!(in = BIO_new_file(infile, "rb"))) 258238384Sjkim { 259238384Sjkim BIO_puts(bio_err, 260238384Sjkim "Error Opening Input File\n"); 261238384Sjkim ERR_print_errors(bio_err); 262238384Sjkim goto end; 263238384Sjkim } 264238384Sjkim } 265238384Sjkim else 266238384Sjkim in = BIO_new_fp(stdin, BIO_NOCLOSE); 267238384Sjkim } 268238384Sjkim 269238384Sjkim if(outfile) 270238384Sjkim { 271238384Sjkim if(!(out = BIO_new_file(outfile, "wb"))) 272238384Sjkim { 273238384Sjkim BIO_printf(bio_err, "Error Creating Output File\n"); 274238384Sjkim ERR_print_errors(bio_err); 275238384Sjkim goto end; 276238384Sjkim } 277238384Sjkim } 278238384Sjkim else 279238384Sjkim { 280238384Sjkim out = BIO_new_fp(stdout, BIO_NOCLOSE); 281238384Sjkim#ifdef OPENSSL_SYS_VMS 282238384Sjkim { 283238384Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 284238384Sjkim out = BIO_push(tmpbio, out); 285238384Sjkim } 286238384Sjkim#endif 287238384Sjkim } 288238384Sjkim 289238384Sjkim if (sigfile) 290238384Sjkim { 291238384Sjkim BIO *sigbio = BIO_new_file(sigfile, "rb"); 292238384Sjkim if (!sigbio) 293238384Sjkim { 294238384Sjkim BIO_printf(bio_err, "Can't open signature file %s\n", 295238384Sjkim sigfile); 296238384Sjkim goto end; 297238384Sjkim } 298238384Sjkim siglen = bio_to_mem(&sig, keysize * 10, sigbio); 299238384Sjkim BIO_free(sigbio); 300238384Sjkim if (siglen <= 0) 301238384Sjkim { 302238384Sjkim BIO_printf(bio_err, "Error reading signature data\n"); 303238384Sjkim goto end; 304238384Sjkim } 305238384Sjkim } 306238384Sjkim 307238384Sjkim if (in) 308238384Sjkim { 309238384Sjkim /* Read the input data */ 310238384Sjkim buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); 311238384Sjkim if(buf_inlen <= 0) 312238384Sjkim { 313238384Sjkim BIO_printf(bio_err, "Error reading input Data\n"); 314238384Sjkim exit(1); 315238384Sjkim } 316238384Sjkim if(rev) 317238384Sjkim { 318238384Sjkim size_t i; 319238384Sjkim unsigned char ctmp; 320238384Sjkim size_t l = (size_t)buf_inlen; 321238384Sjkim for(i = 0; i < l/2; i++) 322238384Sjkim { 323238384Sjkim ctmp = buf_in[i]; 324238384Sjkim buf_in[i] = buf_in[l - 1 - i]; 325238384Sjkim buf_in[l - 1 - i] = ctmp; 326238384Sjkim } 327238384Sjkim } 328238384Sjkim } 329238384Sjkim 330238384Sjkim if(pkey_op == EVP_PKEY_OP_VERIFY) 331238384Sjkim { 332238384Sjkim rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, 333238384Sjkim buf_in, (size_t)buf_inlen); 334238384Sjkim if (rv == 0) 335238384Sjkim BIO_puts(out, "Signature Verification Failure\n"); 336238384Sjkim else if (rv == 1) 337238384Sjkim BIO_puts(out, "Signature Verified Successfully\n"); 338238384Sjkim if (rv >= 0) 339238384Sjkim goto end; 340238384Sjkim } 341238384Sjkim else 342238384Sjkim { 343238384Sjkim rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, 344238384Sjkim buf_in, (size_t)buf_inlen); 345238384Sjkim if (rv > 0) 346238384Sjkim { 347238384Sjkim buf_out = OPENSSL_malloc(buf_outlen); 348238384Sjkim if (!buf_out) 349238384Sjkim rv = -1; 350238384Sjkim else 351238384Sjkim rv = do_keyop(ctx, pkey_op, 352238384Sjkim buf_out, (size_t *)&buf_outlen, 353238384Sjkim buf_in, (size_t)buf_inlen); 354238384Sjkim } 355238384Sjkim } 356238384Sjkim 357238384Sjkim if(rv <= 0) 358238384Sjkim { 359238384Sjkim BIO_printf(bio_err, "Public Key operation error\n"); 360238384Sjkim ERR_print_errors(bio_err); 361238384Sjkim goto end; 362238384Sjkim } 363238384Sjkim ret = 0; 364238384Sjkim if(asn1parse) 365238384Sjkim { 366238384Sjkim if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) 367238384Sjkim ERR_print_errors(bio_err); 368238384Sjkim } 369238384Sjkim else if(hexdump) 370238384Sjkim BIO_dump(out, (char *)buf_out, buf_outlen); 371238384Sjkim else 372238384Sjkim BIO_write(out, buf_out, buf_outlen); 373238384Sjkim 374238384Sjkim end: 375238384Sjkim if (ctx) 376238384Sjkim EVP_PKEY_CTX_free(ctx); 377238384Sjkim BIO_free(in); 378238384Sjkim BIO_free_all(out); 379238384Sjkim if (buf_in) 380238384Sjkim OPENSSL_free(buf_in); 381238384Sjkim if (buf_out) 382238384Sjkim OPENSSL_free(buf_out); 383238384Sjkim if (sig) 384238384Sjkim OPENSSL_free(sig); 385238384Sjkim return ret; 386238384Sjkim} 387238384Sjkim 388238384Sjkimstatic void usage() 389238384Sjkim{ 390238384Sjkim BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); 391238384Sjkim BIO_printf(bio_err, "-in file input file\n"); 392238384Sjkim BIO_printf(bio_err, "-out file output file\n"); 393238384Sjkim BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n"); 394238384Sjkim BIO_printf(bio_err, "-inkey file input key\n"); 395238384Sjkim BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); 396238384Sjkim BIO_printf(bio_err, "-pubin input is a public key\n"); 397238384Sjkim BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n"); 398238384Sjkim BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); 399238384Sjkim BIO_printf(bio_err, "-sign sign with private key\n"); 400238384Sjkim BIO_printf(bio_err, "-verify verify with public key\n"); 401238384Sjkim BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n"); 402238384Sjkim BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 403238384Sjkim BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 404238384Sjkim BIO_printf(bio_err, "-derive derive shared secret\n"); 405238384Sjkim BIO_printf(bio_err, "-hexdump hex dump output\n"); 406238384Sjkim#ifndef OPENSSL_NO_ENGINE 407238384Sjkim BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); 408238384Sjkim#endif 409238384Sjkim BIO_printf(bio_err, "-passin arg pass phrase source\n"); 410238384Sjkim 411238384Sjkim} 412238384Sjkim 413238384Sjkimstatic EVP_PKEY_CTX *init_ctx(int *pkeysize, 414238384Sjkim char *keyfile, int keyform, int key_type, 415238384Sjkim char *passargin, int pkey_op, ENGINE *e) 416238384Sjkim { 417238384Sjkim EVP_PKEY *pkey = NULL; 418238384Sjkim EVP_PKEY_CTX *ctx = NULL; 419238384Sjkim char *passin = NULL; 420238384Sjkim int rv = -1; 421238384Sjkim X509 *x; 422238384Sjkim if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 423238384Sjkim || (pkey_op == EVP_PKEY_OP_DERIVE)) 424238384Sjkim && (key_type != KEY_PRIVKEY)) 425238384Sjkim { 426238384Sjkim BIO_printf(bio_err, "A private key is needed for this operation\n"); 427238384Sjkim goto end; 428238384Sjkim } 429238384Sjkim if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) 430238384Sjkim { 431238384Sjkim BIO_printf(bio_err, "Error getting password\n"); 432238384Sjkim goto end; 433238384Sjkim } 434238384Sjkim switch(key_type) 435238384Sjkim { 436238384Sjkim case KEY_PRIVKEY: 437238384Sjkim pkey = load_key(bio_err, keyfile, keyform, 0, 438238384Sjkim passin, e, "Private Key"); 439238384Sjkim break; 440238384Sjkim 441238384Sjkim case KEY_PUBKEY: 442238384Sjkim pkey = load_pubkey(bio_err, keyfile, keyform, 0, 443238384Sjkim NULL, e, "Public Key"); 444238384Sjkim break; 445238384Sjkim 446238384Sjkim case KEY_CERT: 447238384Sjkim x = load_cert(bio_err, keyfile, keyform, 448238384Sjkim NULL, e, "Certificate"); 449238384Sjkim if(x) 450238384Sjkim { 451238384Sjkim pkey = X509_get_pubkey(x); 452238384Sjkim X509_free(x); 453238384Sjkim } 454238384Sjkim break; 455238384Sjkim 456238384Sjkim } 457238384Sjkim 458238384Sjkim *pkeysize = EVP_PKEY_size(pkey); 459238384Sjkim 460238384Sjkim if (!pkey) 461238384Sjkim goto end; 462238384Sjkim 463238384Sjkim ctx = EVP_PKEY_CTX_new(pkey, e); 464238384Sjkim 465238384Sjkim EVP_PKEY_free(pkey); 466238384Sjkim 467238384Sjkim if (!ctx) 468238384Sjkim goto end; 469238384Sjkim 470238384Sjkim switch(pkey_op) 471238384Sjkim { 472238384Sjkim case EVP_PKEY_OP_SIGN: 473238384Sjkim rv = EVP_PKEY_sign_init(ctx); 474238384Sjkim break; 475238384Sjkim 476238384Sjkim case EVP_PKEY_OP_VERIFY: 477238384Sjkim rv = EVP_PKEY_verify_init(ctx); 478238384Sjkim break; 479238384Sjkim 480238384Sjkim case EVP_PKEY_OP_VERIFYRECOVER: 481238384Sjkim rv = EVP_PKEY_verify_recover_init(ctx); 482238384Sjkim break; 483238384Sjkim 484238384Sjkim case EVP_PKEY_OP_ENCRYPT: 485238384Sjkim rv = EVP_PKEY_encrypt_init(ctx); 486238384Sjkim break; 487238384Sjkim 488238384Sjkim case EVP_PKEY_OP_DECRYPT: 489238384Sjkim rv = EVP_PKEY_decrypt_init(ctx); 490238384Sjkim break; 491238384Sjkim 492238384Sjkim case EVP_PKEY_OP_DERIVE: 493238384Sjkim rv = EVP_PKEY_derive_init(ctx); 494238384Sjkim break; 495238384Sjkim } 496238384Sjkim 497238384Sjkim if (rv <= 0) 498238384Sjkim { 499238384Sjkim EVP_PKEY_CTX_free(ctx); 500238384Sjkim ctx = NULL; 501238384Sjkim } 502238384Sjkim 503238384Sjkim end: 504238384Sjkim 505238384Sjkim if (passin) 506238384Sjkim OPENSSL_free(passin); 507238384Sjkim 508238384Sjkim return ctx; 509238384Sjkim 510238384Sjkim 511238384Sjkim } 512238384Sjkim 513238384Sjkimstatic int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform, 514238384Sjkim const char *file) 515238384Sjkim { 516238384Sjkim EVP_PKEY *peer = NULL; 517238384Sjkim int ret; 518238384Sjkim if (!ctx) 519238384Sjkim { 520238384Sjkim BIO_puts(err, "-peerkey command before -inkey\n"); 521238384Sjkim return 0; 522238384Sjkim } 523238384Sjkim 524238384Sjkim peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key"); 525238384Sjkim 526238384Sjkim if (!peer) 527238384Sjkim { 528238384Sjkim BIO_printf(bio_err, "Error reading peer key %s\n", file); 529238384Sjkim ERR_print_errors(err); 530238384Sjkim return 0; 531238384Sjkim } 532238384Sjkim 533238384Sjkim ret = EVP_PKEY_derive_set_peer(ctx, peer); 534238384Sjkim 535238384Sjkim EVP_PKEY_free(peer); 536238384Sjkim if (ret <= 0) 537238384Sjkim ERR_print_errors(err); 538238384Sjkim return ret; 539238384Sjkim } 540238384Sjkim 541238384Sjkimstatic int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 542238384Sjkim unsigned char *out, size_t *poutlen, 543238384Sjkim unsigned char *in, size_t inlen) 544238384Sjkim { 545238384Sjkim int rv = 0; 546238384Sjkim switch(pkey_op) 547238384Sjkim { 548238384Sjkim case EVP_PKEY_OP_VERIFYRECOVER: 549238384Sjkim rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); 550238384Sjkim break; 551238384Sjkim 552238384Sjkim case EVP_PKEY_OP_SIGN: 553238384Sjkim rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); 554238384Sjkim break; 555238384Sjkim 556238384Sjkim case EVP_PKEY_OP_ENCRYPT: 557238384Sjkim rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); 558238384Sjkim break; 559238384Sjkim 560238384Sjkim case EVP_PKEY_OP_DECRYPT: 561238384Sjkim rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); 562238384Sjkim break; 563238384Sjkim 564238384Sjkim case EVP_PKEY_OP_DERIVE: 565238384Sjkim rv = EVP_PKEY_derive(ctx, out, poutlen); 566238384Sjkim break; 567238384Sjkim 568238384Sjkim } 569238384Sjkim return rv; 570238384Sjkim } 571