1*f5b1c8a1SJohn Marino /* $OpenBSD: pkeyutl.c,v 1.9 2015/10/17 07:51:10 semarie Exp $ */ 2*f5b1c8a1SJohn Marino /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3*f5b1c8a1SJohn Marino * project 2006. 4*f5b1c8a1SJohn Marino */ 5*f5b1c8a1SJohn Marino /* ==================================================================== 6*f5b1c8a1SJohn Marino * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 7*f5b1c8a1SJohn Marino * 8*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 9*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 10*f5b1c8a1SJohn Marino * are met: 11*f5b1c8a1SJohn Marino * 12*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright 13*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 14*f5b1c8a1SJohn Marino * 15*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 16*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in 17*f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the 18*f5b1c8a1SJohn Marino * distribution. 19*f5b1c8a1SJohn Marino * 20*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this 21*f5b1c8a1SJohn Marino * software must display the following acknowledgment: 22*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 23*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*f5b1c8a1SJohn Marino * 25*f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*f5b1c8a1SJohn Marino * endorse or promote products derived from this software without 27*f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact 28*f5b1c8a1SJohn Marino * licensing@OpenSSL.org. 29*f5b1c8a1SJohn Marino * 30*f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL" 31*f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written 32*f5b1c8a1SJohn Marino * permission of the OpenSSL Project. 33*f5b1c8a1SJohn Marino * 34*f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following 35*f5b1c8a1SJohn Marino * acknowledgment: 36*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 37*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*f5b1c8a1SJohn Marino * 39*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE. 51*f5b1c8a1SJohn Marino * ==================================================================== 52*f5b1c8a1SJohn Marino * 53*f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young 54*f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim 55*f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com). 56*f5b1c8a1SJohn Marino * 57*f5b1c8a1SJohn Marino */ 58*f5b1c8a1SJohn Marino 59*f5b1c8a1SJohn Marino #include <string.h> 60*f5b1c8a1SJohn Marino 61*f5b1c8a1SJohn Marino #include "apps.h" 62*f5b1c8a1SJohn Marino 63*f5b1c8a1SJohn Marino #include <openssl/err.h> 64*f5b1c8a1SJohn Marino #include <openssl/evp.h> 65*f5b1c8a1SJohn Marino #include <openssl/pem.h> 66*f5b1c8a1SJohn Marino 67*f5b1c8a1SJohn Marino #define KEY_PRIVKEY 1 68*f5b1c8a1SJohn Marino #define KEY_PUBKEY 2 69*f5b1c8a1SJohn Marino #define KEY_CERT 3 70*f5b1c8a1SJohn Marino 71*f5b1c8a1SJohn Marino static void usage(void); 72*f5b1c8a1SJohn Marino 73*f5b1c8a1SJohn Marino static EVP_PKEY_CTX *init_ctx(int *pkeysize, 74*f5b1c8a1SJohn Marino char *keyfile, int keyform, int key_type, 75*f5b1c8a1SJohn Marino char *passargin, int pkey_op); 76*f5b1c8a1SJohn Marino 77*f5b1c8a1SJohn Marino static int setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, 78*f5b1c8a1SJohn Marino const char *file); 79*f5b1c8a1SJohn Marino 80*f5b1c8a1SJohn Marino static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, 81*f5b1c8a1SJohn Marino unsigned char *out, size_t * poutlen, 82*f5b1c8a1SJohn Marino unsigned char *in, size_t inlen); 83*f5b1c8a1SJohn Marino 84*f5b1c8a1SJohn Marino int 85*f5b1c8a1SJohn Marino pkeyutl_main(int argc, char **argv) 86*f5b1c8a1SJohn Marino { 87*f5b1c8a1SJohn Marino BIO *in = NULL, *out = NULL; 88*f5b1c8a1SJohn Marino char *infile = NULL, *outfile = NULL, *sigfile = NULL; 89*f5b1c8a1SJohn Marino int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; 90*f5b1c8a1SJohn Marino int keyform = FORMAT_PEM, peerform = FORMAT_PEM; 91*f5b1c8a1SJohn Marino char badarg = 0, rev = 0; 92*f5b1c8a1SJohn Marino char hexdump = 0, asn1parse = 0; 93*f5b1c8a1SJohn Marino EVP_PKEY_CTX *ctx = NULL; 94*f5b1c8a1SJohn Marino char *passargin = NULL; 95*f5b1c8a1SJohn Marino int keysize = -1; 96*f5b1c8a1SJohn Marino 97*f5b1c8a1SJohn Marino unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; 98*f5b1c8a1SJohn Marino size_t buf_outlen; 99*f5b1c8a1SJohn Marino int buf_inlen = 0, siglen = -1; 100*f5b1c8a1SJohn Marino 101*f5b1c8a1SJohn Marino int ret = 1, rv = -1; 102*f5b1c8a1SJohn Marino 103*f5b1c8a1SJohn Marino if (single_execution) { 104*f5b1c8a1SJohn Marino if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { 105*f5b1c8a1SJohn Marino perror("pledge"); 106*f5b1c8a1SJohn Marino exit(1); 107*f5b1c8a1SJohn Marino } 108*f5b1c8a1SJohn Marino } 109*f5b1c8a1SJohn Marino 110*f5b1c8a1SJohn Marino argc--; 111*f5b1c8a1SJohn Marino argv++; 112*f5b1c8a1SJohn Marino 113*f5b1c8a1SJohn Marino while (argc >= 1) { 114*f5b1c8a1SJohn Marino if (!strcmp(*argv, "-in")) { 115*f5b1c8a1SJohn Marino if (--argc < 1) 116*f5b1c8a1SJohn Marino badarg = 1; 117*f5b1c8a1SJohn Marino else 118*f5b1c8a1SJohn Marino infile = *(++argv); 119*f5b1c8a1SJohn Marino } else if (!strcmp(*argv, "-out")) { 120*f5b1c8a1SJohn Marino if (--argc < 1) 121*f5b1c8a1SJohn Marino badarg = 1; 122*f5b1c8a1SJohn Marino else 123*f5b1c8a1SJohn Marino outfile = *(++argv); 124*f5b1c8a1SJohn Marino } else if (!strcmp(*argv, "-sigfile")) { 125*f5b1c8a1SJohn Marino if (--argc < 1) 126*f5b1c8a1SJohn Marino badarg = 1; 127*f5b1c8a1SJohn Marino else 128*f5b1c8a1SJohn Marino sigfile = *(++argv); 129*f5b1c8a1SJohn Marino } else if (!strcmp(*argv, "-inkey")) { 130*f5b1c8a1SJohn Marino if (--argc < 1) 131*f5b1c8a1SJohn Marino badarg = 1; 132*f5b1c8a1SJohn Marino else { 133*f5b1c8a1SJohn Marino ctx = init_ctx(&keysize, 134*f5b1c8a1SJohn Marino *(++argv), keyform, key_type, 135*f5b1c8a1SJohn Marino passargin, pkey_op); 136*f5b1c8a1SJohn Marino if (!ctx) { 137*f5b1c8a1SJohn Marino BIO_puts(bio_err, 138*f5b1c8a1SJohn Marino "Error initializing context\n"); 139*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 140*f5b1c8a1SJohn Marino badarg = 1; 141*f5b1c8a1SJohn Marino } 142*f5b1c8a1SJohn Marino } 143*f5b1c8a1SJohn Marino } else if (!strcmp(*argv, "-peerkey")) { 144*f5b1c8a1SJohn Marino if (--argc < 1) 145*f5b1c8a1SJohn Marino badarg = 1; 146*f5b1c8a1SJohn Marino else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) 147*f5b1c8a1SJohn Marino badarg = 1; 148*f5b1c8a1SJohn Marino } else if (!strcmp(*argv, "-passin")) { 149*f5b1c8a1SJohn Marino if (--argc < 1) 150*f5b1c8a1SJohn Marino badarg = 1; 151*f5b1c8a1SJohn Marino else 152*f5b1c8a1SJohn Marino passargin = *(++argv); 153*f5b1c8a1SJohn Marino } else if (strcmp(*argv, "-peerform") == 0) { 154*f5b1c8a1SJohn Marino if (--argc < 1) 155*f5b1c8a1SJohn Marino badarg = 1; 156*f5b1c8a1SJohn Marino else 157*f5b1c8a1SJohn Marino peerform = str2fmt(*(++argv)); 158*f5b1c8a1SJohn Marino } else if (strcmp(*argv, "-keyform") == 0) { 159*f5b1c8a1SJohn Marino if (--argc < 1) 160*f5b1c8a1SJohn Marino badarg = 1; 161*f5b1c8a1SJohn Marino else 162*f5b1c8a1SJohn Marino keyform = str2fmt(*(++argv)); 163*f5b1c8a1SJohn Marino } 164*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-pubin")) 165*f5b1c8a1SJohn Marino key_type = KEY_PUBKEY; 166*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-certin")) 167*f5b1c8a1SJohn Marino key_type = KEY_CERT; 168*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-asn1parse")) 169*f5b1c8a1SJohn Marino asn1parse = 1; 170*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-hexdump")) 171*f5b1c8a1SJohn Marino hexdump = 1; 172*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-sign")) 173*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_SIGN; 174*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-verify")) 175*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_VERIFY; 176*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-verifyrecover")) 177*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_VERIFYRECOVER; 178*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-rev")) 179*f5b1c8a1SJohn Marino rev = 1; 180*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-encrypt")) 181*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_ENCRYPT; 182*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-decrypt")) 183*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_DECRYPT; 184*f5b1c8a1SJohn Marino else if (!strcmp(*argv, "-derive")) 185*f5b1c8a1SJohn Marino pkey_op = EVP_PKEY_OP_DERIVE; 186*f5b1c8a1SJohn Marino else if (strcmp(*argv, "-pkeyopt") == 0) { 187*f5b1c8a1SJohn Marino if (--argc < 1) 188*f5b1c8a1SJohn Marino badarg = 1; 189*f5b1c8a1SJohn Marino else if (!ctx) { 190*f5b1c8a1SJohn Marino BIO_puts(bio_err, 191*f5b1c8a1SJohn Marino "-pkeyopt command before -inkey\n"); 192*f5b1c8a1SJohn Marino badarg = 1; 193*f5b1c8a1SJohn Marino } else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) { 194*f5b1c8a1SJohn Marino BIO_puts(bio_err, "parameter setting error\n"); 195*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 196*f5b1c8a1SJohn Marino goto end; 197*f5b1c8a1SJohn Marino } 198*f5b1c8a1SJohn Marino } else 199*f5b1c8a1SJohn Marino badarg = 1; 200*f5b1c8a1SJohn Marino if (badarg) { 201*f5b1c8a1SJohn Marino usage(); 202*f5b1c8a1SJohn Marino goto end; 203*f5b1c8a1SJohn Marino } 204*f5b1c8a1SJohn Marino argc--; 205*f5b1c8a1SJohn Marino argv++; 206*f5b1c8a1SJohn Marino } 207*f5b1c8a1SJohn Marino 208*f5b1c8a1SJohn Marino if (!ctx) { 209*f5b1c8a1SJohn Marino usage(); 210*f5b1c8a1SJohn Marino goto end; 211*f5b1c8a1SJohn Marino } 212*f5b1c8a1SJohn Marino if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { 213*f5b1c8a1SJohn Marino BIO_puts(bio_err, "Signature file specified for non verify\n"); 214*f5b1c8a1SJohn Marino goto end; 215*f5b1c8a1SJohn Marino } 216*f5b1c8a1SJohn Marino if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { 217*f5b1c8a1SJohn Marino BIO_puts(bio_err, "No signature file specified for verify\n"); 218*f5b1c8a1SJohn Marino goto end; 219*f5b1c8a1SJohn Marino } 220*f5b1c8a1SJohn Marino 221*f5b1c8a1SJohn Marino if (pkey_op != EVP_PKEY_OP_DERIVE) { 222*f5b1c8a1SJohn Marino if (infile) { 223*f5b1c8a1SJohn Marino if (!(in = BIO_new_file(infile, "rb"))) { 224*f5b1c8a1SJohn Marino BIO_puts(bio_err, 225*f5b1c8a1SJohn Marino "Error Opening Input File\n"); 226*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 227*f5b1c8a1SJohn Marino goto end; 228*f5b1c8a1SJohn Marino } 229*f5b1c8a1SJohn Marino } else 230*f5b1c8a1SJohn Marino in = BIO_new_fp(stdin, BIO_NOCLOSE); 231*f5b1c8a1SJohn Marino } 232*f5b1c8a1SJohn Marino if (outfile) { 233*f5b1c8a1SJohn Marino if (!(out = BIO_new_file(outfile, "wb"))) { 234*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error Creating Output File\n"); 235*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 236*f5b1c8a1SJohn Marino goto end; 237*f5b1c8a1SJohn Marino } 238*f5b1c8a1SJohn Marino } else { 239*f5b1c8a1SJohn Marino out = BIO_new_fp(stdout, BIO_NOCLOSE); 240*f5b1c8a1SJohn Marino } 241*f5b1c8a1SJohn Marino 242*f5b1c8a1SJohn Marino if (sigfile) { 243*f5b1c8a1SJohn Marino BIO *sigbio = BIO_new_file(sigfile, "rb"); 244*f5b1c8a1SJohn Marino if (!sigbio) { 245*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Can't open signature file %s\n", 246*f5b1c8a1SJohn Marino sigfile); 247*f5b1c8a1SJohn Marino goto end; 248*f5b1c8a1SJohn Marino } 249*f5b1c8a1SJohn Marino siglen = bio_to_mem(&sig, keysize * 10, sigbio); 250*f5b1c8a1SJohn Marino BIO_free(sigbio); 251*f5b1c8a1SJohn Marino if (siglen <= 0) { 252*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error reading signature data\n"); 253*f5b1c8a1SJohn Marino goto end; 254*f5b1c8a1SJohn Marino } 255*f5b1c8a1SJohn Marino } 256*f5b1c8a1SJohn Marino if (in) { 257*f5b1c8a1SJohn Marino /* Read the input data */ 258*f5b1c8a1SJohn Marino buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); 259*f5b1c8a1SJohn Marino if (buf_inlen <= 0) { 260*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error reading input Data\n"); 261*f5b1c8a1SJohn Marino exit(1); 262*f5b1c8a1SJohn Marino } 263*f5b1c8a1SJohn Marino if (rev) { 264*f5b1c8a1SJohn Marino size_t i; 265*f5b1c8a1SJohn Marino unsigned char ctmp; 266*f5b1c8a1SJohn Marino size_t l = (size_t) buf_inlen; 267*f5b1c8a1SJohn Marino for (i = 0; i < l / 2; i++) { 268*f5b1c8a1SJohn Marino ctmp = buf_in[i]; 269*f5b1c8a1SJohn Marino buf_in[i] = buf_in[l - 1 - i]; 270*f5b1c8a1SJohn Marino buf_in[l - 1 - i] = ctmp; 271*f5b1c8a1SJohn Marino } 272*f5b1c8a1SJohn Marino } 273*f5b1c8a1SJohn Marino } 274*f5b1c8a1SJohn Marino if (pkey_op == EVP_PKEY_OP_VERIFY) { 275*f5b1c8a1SJohn Marino rv = EVP_PKEY_verify(ctx, sig, (size_t) siglen, 276*f5b1c8a1SJohn Marino buf_in, (size_t) buf_inlen); 277*f5b1c8a1SJohn Marino if (rv == 1) { 278*f5b1c8a1SJohn Marino BIO_puts(out, "Signature Verified Successfully\n"); 279*f5b1c8a1SJohn Marino ret = 0; 280*f5b1c8a1SJohn Marino } else 281*f5b1c8a1SJohn Marino BIO_puts(out, "Signature Verification Failure\n"); 282*f5b1c8a1SJohn Marino if (rv >= 0) 283*f5b1c8a1SJohn Marino goto end; 284*f5b1c8a1SJohn Marino } else { 285*f5b1c8a1SJohn Marino rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, 286*f5b1c8a1SJohn Marino buf_in, (size_t) buf_inlen); 287*f5b1c8a1SJohn Marino if (rv > 0) { 288*f5b1c8a1SJohn Marino buf_out = malloc(buf_outlen); 289*f5b1c8a1SJohn Marino if (!buf_out) 290*f5b1c8a1SJohn Marino rv = -1; 291*f5b1c8a1SJohn Marino else 292*f5b1c8a1SJohn Marino rv = do_keyop(ctx, pkey_op, 293*f5b1c8a1SJohn Marino buf_out, (size_t *) & buf_outlen, 294*f5b1c8a1SJohn Marino buf_in, (size_t) buf_inlen); 295*f5b1c8a1SJohn Marino } 296*f5b1c8a1SJohn Marino } 297*f5b1c8a1SJohn Marino 298*f5b1c8a1SJohn Marino if (rv <= 0) { 299*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Public Key operation error\n"); 300*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 301*f5b1c8a1SJohn Marino goto end; 302*f5b1c8a1SJohn Marino } 303*f5b1c8a1SJohn Marino ret = 0; 304*f5b1c8a1SJohn Marino if (asn1parse) { 305*f5b1c8a1SJohn Marino if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) 306*f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 307*f5b1c8a1SJohn Marino } else if (hexdump) 308*f5b1c8a1SJohn Marino BIO_dump(out, (char *) buf_out, buf_outlen); 309*f5b1c8a1SJohn Marino else 310*f5b1c8a1SJohn Marino BIO_write(out, buf_out, buf_outlen); 311*f5b1c8a1SJohn Marino 312*f5b1c8a1SJohn Marino end: 313*f5b1c8a1SJohn Marino if (ctx) 314*f5b1c8a1SJohn Marino EVP_PKEY_CTX_free(ctx); 315*f5b1c8a1SJohn Marino BIO_free(in); 316*f5b1c8a1SJohn Marino BIO_free_all(out); 317*f5b1c8a1SJohn Marino free(buf_in); 318*f5b1c8a1SJohn Marino free(buf_out); 319*f5b1c8a1SJohn Marino free(sig); 320*f5b1c8a1SJohn Marino 321*f5b1c8a1SJohn Marino return ret; 322*f5b1c8a1SJohn Marino } 323*f5b1c8a1SJohn Marino 324*f5b1c8a1SJohn Marino static void 325*f5b1c8a1SJohn Marino usage() 326*f5b1c8a1SJohn Marino { 327*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Usage: pkeyutl [options]\n"); 328*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-in file input file\n"); 329*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-out file output file\n"); 330*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-sigfile file signature file (verify operation only)\n"); 331*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-inkey file input key\n"); 332*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); 333*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-pubin input is a public key\n"); 334*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-certin input is a certificate carrying a public key\n"); 335*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-pkeyopt X:Y public key options\n"); 336*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-sign sign with private key\n"); 337*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-verify verify with public key\n"); 338*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-verifyrecover verify with public key, recover original data\n"); 339*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 340*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 341*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-derive derive shared secret\n"); 342*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-hexdump hex dump output\n"); 343*f5b1c8a1SJohn Marino BIO_printf(bio_err, "-passin arg pass phrase source\n"); 344*f5b1c8a1SJohn Marino 345*f5b1c8a1SJohn Marino } 346*f5b1c8a1SJohn Marino 347*f5b1c8a1SJohn Marino static EVP_PKEY_CTX * 348*f5b1c8a1SJohn Marino init_ctx(int *pkeysize, 349*f5b1c8a1SJohn Marino char *keyfile, int keyform, int key_type, 350*f5b1c8a1SJohn Marino char *passargin, int pkey_op) 351*f5b1c8a1SJohn Marino { 352*f5b1c8a1SJohn Marino EVP_PKEY *pkey = NULL; 353*f5b1c8a1SJohn Marino EVP_PKEY_CTX *ctx = NULL; 354*f5b1c8a1SJohn Marino char *passin = NULL; 355*f5b1c8a1SJohn Marino int rv = -1; 356*f5b1c8a1SJohn Marino X509 *x; 357*f5b1c8a1SJohn Marino if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 358*f5b1c8a1SJohn Marino || (pkey_op == EVP_PKEY_OP_DERIVE)) 359*f5b1c8a1SJohn Marino && (key_type != KEY_PRIVKEY)) { 360*f5b1c8a1SJohn Marino BIO_printf(bio_err, "A private key is needed for this operation\n"); 361*f5b1c8a1SJohn Marino goto end; 362*f5b1c8a1SJohn Marino } 363*f5b1c8a1SJohn Marino if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 364*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error getting password\n"); 365*f5b1c8a1SJohn Marino goto end; 366*f5b1c8a1SJohn Marino } 367*f5b1c8a1SJohn Marino switch (key_type) { 368*f5b1c8a1SJohn Marino case KEY_PRIVKEY: 369*f5b1c8a1SJohn Marino pkey = load_key(bio_err, keyfile, keyform, 0, 370*f5b1c8a1SJohn Marino passin, "Private Key"); 371*f5b1c8a1SJohn Marino break; 372*f5b1c8a1SJohn Marino 373*f5b1c8a1SJohn Marino case KEY_PUBKEY: 374*f5b1c8a1SJohn Marino pkey = load_pubkey(bio_err, keyfile, keyform, 0, 375*f5b1c8a1SJohn Marino NULL, "Public Key"); 376*f5b1c8a1SJohn Marino break; 377*f5b1c8a1SJohn Marino 378*f5b1c8a1SJohn Marino case KEY_CERT: 379*f5b1c8a1SJohn Marino x = load_cert(bio_err, keyfile, keyform, 380*f5b1c8a1SJohn Marino NULL, "Certificate"); 381*f5b1c8a1SJohn Marino if (x) { 382*f5b1c8a1SJohn Marino pkey = X509_get_pubkey(x); 383*f5b1c8a1SJohn Marino X509_free(x); 384*f5b1c8a1SJohn Marino } 385*f5b1c8a1SJohn Marino break; 386*f5b1c8a1SJohn Marino 387*f5b1c8a1SJohn Marino } 388*f5b1c8a1SJohn Marino 389*f5b1c8a1SJohn Marino *pkeysize = EVP_PKEY_size(pkey); 390*f5b1c8a1SJohn Marino 391*f5b1c8a1SJohn Marino if (!pkey) 392*f5b1c8a1SJohn Marino goto end; 393*f5b1c8a1SJohn Marino 394*f5b1c8a1SJohn Marino ctx = EVP_PKEY_CTX_new(pkey, NULL); 395*f5b1c8a1SJohn Marino 396*f5b1c8a1SJohn Marino EVP_PKEY_free(pkey); 397*f5b1c8a1SJohn Marino 398*f5b1c8a1SJohn Marino if (!ctx) 399*f5b1c8a1SJohn Marino goto end; 400*f5b1c8a1SJohn Marino 401*f5b1c8a1SJohn Marino switch (pkey_op) { 402*f5b1c8a1SJohn Marino case EVP_PKEY_OP_SIGN: 403*f5b1c8a1SJohn Marino rv = EVP_PKEY_sign_init(ctx); 404*f5b1c8a1SJohn Marino break; 405*f5b1c8a1SJohn Marino 406*f5b1c8a1SJohn Marino case EVP_PKEY_OP_VERIFY: 407*f5b1c8a1SJohn Marino rv = EVP_PKEY_verify_init(ctx); 408*f5b1c8a1SJohn Marino break; 409*f5b1c8a1SJohn Marino 410*f5b1c8a1SJohn Marino case EVP_PKEY_OP_VERIFYRECOVER: 411*f5b1c8a1SJohn Marino rv = EVP_PKEY_verify_recover_init(ctx); 412*f5b1c8a1SJohn Marino break; 413*f5b1c8a1SJohn Marino 414*f5b1c8a1SJohn Marino case EVP_PKEY_OP_ENCRYPT: 415*f5b1c8a1SJohn Marino rv = EVP_PKEY_encrypt_init(ctx); 416*f5b1c8a1SJohn Marino break; 417*f5b1c8a1SJohn Marino 418*f5b1c8a1SJohn Marino case EVP_PKEY_OP_DECRYPT: 419*f5b1c8a1SJohn Marino rv = EVP_PKEY_decrypt_init(ctx); 420*f5b1c8a1SJohn Marino break; 421*f5b1c8a1SJohn Marino 422*f5b1c8a1SJohn Marino case EVP_PKEY_OP_DERIVE: 423*f5b1c8a1SJohn Marino rv = EVP_PKEY_derive_init(ctx); 424*f5b1c8a1SJohn Marino break; 425*f5b1c8a1SJohn Marino } 426*f5b1c8a1SJohn Marino 427*f5b1c8a1SJohn Marino if (rv <= 0) { 428*f5b1c8a1SJohn Marino EVP_PKEY_CTX_free(ctx); 429*f5b1c8a1SJohn Marino ctx = NULL; 430*f5b1c8a1SJohn Marino } 431*f5b1c8a1SJohn Marino end: 432*f5b1c8a1SJohn Marino 433*f5b1c8a1SJohn Marino free(passin); 434*f5b1c8a1SJohn Marino 435*f5b1c8a1SJohn Marino return ctx; 436*f5b1c8a1SJohn Marino 437*f5b1c8a1SJohn Marino 438*f5b1c8a1SJohn Marino } 439*f5b1c8a1SJohn Marino 440*f5b1c8a1SJohn Marino static int 441*f5b1c8a1SJohn Marino setup_peer(BIO * err, EVP_PKEY_CTX * ctx, int peerform, 442*f5b1c8a1SJohn Marino const char *file) 443*f5b1c8a1SJohn Marino { 444*f5b1c8a1SJohn Marino EVP_PKEY *peer = NULL; 445*f5b1c8a1SJohn Marino int ret; 446*f5b1c8a1SJohn Marino if (!ctx) { 447*f5b1c8a1SJohn Marino BIO_puts(err, "-peerkey command before -inkey\n"); 448*f5b1c8a1SJohn Marino return 0; 449*f5b1c8a1SJohn Marino } 450*f5b1c8a1SJohn Marino peer = load_pubkey(bio_err, file, peerform, 0, NULL, "Peer Key"); 451*f5b1c8a1SJohn Marino 452*f5b1c8a1SJohn Marino if (!peer) { 453*f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error reading peer key %s\n", file); 454*f5b1c8a1SJohn Marino ERR_print_errors(err); 455*f5b1c8a1SJohn Marino return 0; 456*f5b1c8a1SJohn Marino } 457*f5b1c8a1SJohn Marino ret = EVP_PKEY_derive_set_peer(ctx, peer); 458*f5b1c8a1SJohn Marino 459*f5b1c8a1SJohn Marino EVP_PKEY_free(peer); 460*f5b1c8a1SJohn Marino if (ret <= 0) 461*f5b1c8a1SJohn Marino ERR_print_errors(err); 462*f5b1c8a1SJohn Marino return ret; 463*f5b1c8a1SJohn Marino } 464*f5b1c8a1SJohn Marino 465*f5b1c8a1SJohn Marino static int 466*f5b1c8a1SJohn Marino do_keyop(EVP_PKEY_CTX * ctx, int pkey_op, 467*f5b1c8a1SJohn Marino unsigned char *out, size_t * poutlen, 468*f5b1c8a1SJohn Marino unsigned char *in, size_t inlen) 469*f5b1c8a1SJohn Marino { 470*f5b1c8a1SJohn Marino int rv = 0; 471*f5b1c8a1SJohn Marino switch (pkey_op) { 472*f5b1c8a1SJohn Marino case EVP_PKEY_OP_VERIFYRECOVER: 473*f5b1c8a1SJohn Marino rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); 474*f5b1c8a1SJohn Marino break; 475*f5b1c8a1SJohn Marino 476*f5b1c8a1SJohn Marino case EVP_PKEY_OP_SIGN: 477*f5b1c8a1SJohn Marino rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); 478*f5b1c8a1SJohn Marino break; 479*f5b1c8a1SJohn Marino 480*f5b1c8a1SJohn Marino case EVP_PKEY_OP_ENCRYPT: 481*f5b1c8a1SJohn Marino rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); 482*f5b1c8a1SJohn Marino break; 483*f5b1c8a1SJohn Marino 484*f5b1c8a1SJohn Marino case EVP_PKEY_OP_DECRYPT: 485*f5b1c8a1SJohn Marino rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); 486*f5b1c8a1SJohn Marino break; 487*f5b1c8a1SJohn Marino 488*f5b1c8a1SJohn Marino case EVP_PKEY_OP_DERIVE: 489*f5b1c8a1SJohn Marino rv = EVP_PKEY_derive(ctx, out, poutlen); 490*f5b1c8a1SJohn Marino break; 491*f5b1c8a1SJohn Marino 492*f5b1c8a1SJohn Marino } 493*f5b1c8a1SJohn Marino return rv; 494*f5b1c8a1SJohn Marino } 495