1 1.2 christos /* 2 1.2 christos * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.2 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.2 christos * this file except in compliance with the License. You can obtain a copy 6 1.2 christos * in the file LICENSE in the source distribution or at 7 1.2 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include "apps.h" 11 1.2 christos #include "progs.h" 12 1.1 christos #include <string.h> 13 1.1 christos #include <openssl/err.h> 14 1.1 christos #include <openssl/pem.h> 15 1.1 christos #include <openssl/evp.h> 16 1.2 christos #include <sys/stat.h> 17 1.1 christos 18 1.2 christos #define KEY_NONE 0 19 1.2 christos #define KEY_PRIVKEY 1 20 1.2 christos #define KEY_PUBKEY 2 21 1.2 christos #define KEY_CERT 3 22 1.2 christos 23 1.2 christos static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, 24 1.2 christos const char *keyfile, int keyform, int key_type, 25 1.2 christos char *passinarg, int pkey_op, ENGINE *e, 26 1.2 christos const int impl, int rawin, EVP_PKEY **ppkey, 27 1.2 christos EVP_MD_CTX *mctx, const char *digestname, 28 1.2 christos OSSL_LIB_CTX *libctx, const char *propq); 29 1.1 christos 30 1.2 christos static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, 31 1.2 christos ENGINE *e); 32 1.1 christos 33 1.2 christos static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 34 1.2 christos unsigned char *out, size_t *poutlen, 35 1.2 christos const unsigned char *in, size_t inlen); 36 1.1 christos 37 1.2 christos static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, 38 1.2 christos EVP_PKEY *pkey, BIO *in, 39 1.2 christos int filesize, unsigned char *sig, int siglen, 40 1.2 christos unsigned char **out, size_t *poutlen); 41 1.2 christos 42 1.2 christos typedef enum OPTION_choice { 43 1.2 christos OPT_COMMON, 44 1.2 christos OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT, 45 1.2 christos OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN, 46 1.2 christos OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT, 47 1.2 christos OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN, 48 1.2 christos OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_PKEYOPT_PASSIN, OPT_KDF, 49 1.2 christos OPT_KDFLEN, OPT_R_ENUM, OPT_PROV_ENUM, 50 1.2 christos OPT_CONFIG, 51 1.2 christos OPT_RAWIN, OPT_DIGEST 52 1.2 christos } OPTION_CHOICE; 53 1.2 christos 54 1.2 christos const OPTIONS pkeyutl_options[] = { 55 1.2 christos OPT_SECTION("General"), 56 1.2 christos {"help", OPT_HELP, '-', "Display this summary"}, 57 1.2 christos #ifndef OPENSSL_NO_ENGINE 58 1.2 christos {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 59 1.2 christos {"engine_impl", OPT_ENGINE_IMPL, '-', 60 1.2 christos "Also use engine given by -engine for crypto operations"}, 61 1.2 christos #endif 62 1.2 christos {"sign", OPT_SIGN, '-', "Sign input data with private key"}, 63 1.2 christos {"verify", OPT_VERIFY, '-', "Verify with public key"}, 64 1.2 christos {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"}, 65 1.2 christos {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"}, 66 1.2 christos {"derive", OPT_DERIVE, '-', "Derive shared secret"}, 67 1.2 christos OPT_CONFIG_OPTION, 68 1.2 christos 69 1.2 christos OPT_SECTION("Input"), 70 1.2 christos {"in", OPT_IN, '<', "Input file - default stdin"}, 71 1.2 christos {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"}, 72 1.2 christos {"pubin", OPT_PUBIN, '-', "Input is a public key"}, 73 1.2 christos {"inkey", OPT_INKEY, 's', "Input private key file"}, 74 1.2 christos {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, 75 1.2 christos {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"}, 76 1.2 christos {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"}, 77 1.2 christos {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"}, 78 1.2 christos {"rev", OPT_REV, '-', "Reverse the order of the input buffer"}, 79 1.2 christos {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"}, 80 1.2 christos {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"}, 81 1.2 christos 82 1.2 christos OPT_SECTION("Output"), 83 1.2 christos {"out", OPT_OUT, '>', "Output file - default stdout"}, 84 1.3 christos {"asn1parse", OPT_ASN1PARSE, '-', 85 1.3 christos "parse the output as ASN.1 data to check its DER encoding and print errors"}, 86 1.2 christos {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"}, 87 1.2 christos {"verifyrecover", OPT_VERIFYRECOVER, '-', 88 1.3 christos "Verify RSA signature, recovering original signature input data"}, 89 1.2 christos 90 1.2 christos OPT_SECTION("Signing/Derivation"), 91 1.2 christos {"digest", OPT_DIGEST, 's', 92 1.2 christos "Specify the digest algorithm when signing the raw input data"}, 93 1.2 christos {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, 94 1.2 christos {"pkeyopt_passin", OPT_PKEYOPT_PASSIN, 's', 95 1.2 christos "Public key option that is read as a passphrase argument opt:passphrase"}, 96 1.2 christos {"kdf", OPT_KDF, 's', "Use KDF algorithm"}, 97 1.2 christos {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"}, 98 1.2 christos 99 1.2 christos OPT_R_OPTIONS, 100 1.2 christos OPT_PROV_OPTIONS, 101 1.2 christos {NULL} 102 1.2 christos }; 103 1.1 christos 104 1.2 christos int pkeyutl_main(int argc, char **argv) 105 1.2 christos { 106 1.2 christos CONF *conf = NULL; 107 1.2 christos BIO *in = NULL, *out = NULL; 108 1.2 christos ENGINE *e = NULL; 109 1.2 christos EVP_PKEY_CTX *ctx = NULL; 110 1.2 christos EVP_PKEY *pkey = NULL; 111 1.2 christos char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; 112 1.2 christos char hexdump = 0, asn1parse = 0, rev = 0, *prog; 113 1.2 christos unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; 114 1.2 christos OPTION_CHOICE o; 115 1.2 christos int buf_inlen = 0, siglen = -1; 116 1.2 christos int keyform = FORMAT_UNDEF, peerform = FORMAT_UNDEF; 117 1.2 christos int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; 118 1.2 christos int engine_impl = 0; 119 1.2 christos int ret = 1, rv = -1; 120 1.2 christos size_t buf_outlen; 121 1.2 christos const char *inkey = NULL; 122 1.2 christos const char *peerkey = NULL; 123 1.2 christos const char *kdfalg = NULL, *digestname = NULL; 124 1.2 christos int kdflen = 0; 125 1.2 christos STACK_OF(OPENSSL_STRING) *pkeyopts = NULL; 126 1.2 christos STACK_OF(OPENSSL_STRING) *pkeyopts_passin = NULL; 127 1.2 christos int rawin = 0; 128 1.2 christos EVP_MD_CTX *mctx = NULL; 129 1.2 christos EVP_MD *md = NULL; 130 1.2 christos int filesize = -1; 131 1.2 christos OSSL_LIB_CTX *libctx = app_get0_libctx(); 132 1.2 christos 133 1.2 christos prog = opt_init(argc, argv, pkeyutl_options); 134 1.2 christos while ((o = opt_next()) != OPT_EOF) { 135 1.2 christos switch (o) { 136 1.2 christos case OPT_EOF: 137 1.2 christos case OPT_ERR: 138 1.2 christos opthelp: 139 1.2 christos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 140 1.2 christos goto end; 141 1.2 christos case OPT_HELP: 142 1.2 christos opt_help(pkeyutl_options); 143 1.2 christos ret = 0; 144 1.2 christos goto end; 145 1.2 christos case OPT_IN: 146 1.2 christos infile = opt_arg(); 147 1.2 christos break; 148 1.2 christos case OPT_OUT: 149 1.2 christos outfile = opt_arg(); 150 1.2 christos break; 151 1.2 christos case OPT_SIGFILE: 152 1.2 christos sigfile = opt_arg(); 153 1.2 christos break; 154 1.2 christos case OPT_ENGINE_IMPL: 155 1.2 christos engine_impl = 1; 156 1.2 christos break; 157 1.2 christos case OPT_INKEY: 158 1.2 christos inkey = opt_arg(); 159 1.2 christos break; 160 1.2 christos case OPT_PEERKEY: 161 1.2 christos peerkey = opt_arg(); 162 1.2 christos break; 163 1.2 christos case OPT_PASSIN: 164 1.2 christos passinarg = opt_arg(); 165 1.2 christos break; 166 1.2 christos case OPT_PEERFORM: 167 1.2 christos if (!opt_format(opt_arg(), OPT_FMT_ANY, &peerform)) 168 1.2 christos goto opthelp; 169 1.2 christos break; 170 1.2 christos case OPT_KEYFORM: 171 1.2 christos if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) 172 1.2 christos goto opthelp; 173 1.2 christos break; 174 1.2 christos case OPT_R_CASES: 175 1.2 christos if (!opt_rand(o)) 176 1.2 christos goto end; 177 1.2 christos break; 178 1.2 christos case OPT_CONFIG: 179 1.2 christos conf = app_load_config_modules(opt_arg()); 180 1.2 christos if (conf == NULL) 181 1.2 christos goto end; 182 1.2 christos break; 183 1.2 christos case OPT_PROV_CASES: 184 1.2 christos if (!opt_provider(o)) 185 1.2 christos goto end; 186 1.2 christos break; 187 1.2 christos case OPT_ENGINE: 188 1.2 christos e = setup_engine(opt_arg(), 0); 189 1.2 christos break; 190 1.2 christos case OPT_PUBIN: 191 1.2 christos key_type = KEY_PUBKEY; 192 1.2 christos break; 193 1.2 christos case OPT_CERTIN: 194 1.2 christos key_type = KEY_CERT; 195 1.2 christos break; 196 1.2 christos case OPT_ASN1PARSE: 197 1.2 christos asn1parse = 1; 198 1.2 christos break; 199 1.2 christos case OPT_HEXDUMP: 200 1.2 christos hexdump = 1; 201 1.2 christos break; 202 1.2 christos case OPT_SIGN: 203 1.2 christos pkey_op = EVP_PKEY_OP_SIGN; 204 1.2 christos break; 205 1.2 christos case OPT_VERIFY: 206 1.2 christos pkey_op = EVP_PKEY_OP_VERIFY; 207 1.2 christos break; 208 1.2 christos case OPT_VERIFYRECOVER: 209 1.2 christos pkey_op = EVP_PKEY_OP_VERIFYRECOVER; 210 1.2 christos break; 211 1.2 christos case OPT_ENCRYPT: 212 1.2 christos pkey_op = EVP_PKEY_OP_ENCRYPT; 213 1.2 christos break; 214 1.2 christos case OPT_DECRYPT: 215 1.2 christos pkey_op = EVP_PKEY_OP_DECRYPT; 216 1.2 christos break; 217 1.2 christos case OPT_DERIVE: 218 1.2 christos pkey_op = EVP_PKEY_OP_DERIVE; 219 1.2 christos break; 220 1.2 christos case OPT_KDF: 221 1.2 christos pkey_op = EVP_PKEY_OP_DERIVE; 222 1.2 christos key_type = KEY_NONE; 223 1.2 christos kdfalg = opt_arg(); 224 1.2 christos break; 225 1.2 christos case OPT_KDFLEN: 226 1.2 christos kdflen = atoi(opt_arg()); 227 1.2 christos break; 228 1.2 christos case OPT_REV: 229 1.2 christos rev = 1; 230 1.2 christos break; 231 1.2 christos case OPT_PKEYOPT: 232 1.2 christos if ((pkeyopts == NULL && 233 1.2 christos (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) || 234 1.2 christos sk_OPENSSL_STRING_push(pkeyopts, opt_arg()) == 0) { 235 1.2 christos BIO_puts(bio_err, "out of memory\n"); 236 1.2 christos goto end; 237 1.2 christos } 238 1.2 christos break; 239 1.2 christos case OPT_PKEYOPT_PASSIN: 240 1.2 christos if ((pkeyopts_passin == NULL && 241 1.2 christos (pkeyopts_passin = sk_OPENSSL_STRING_new_null()) == NULL) || 242 1.2 christos sk_OPENSSL_STRING_push(pkeyopts_passin, opt_arg()) == 0) { 243 1.2 christos BIO_puts(bio_err, "out of memory\n"); 244 1.2 christos goto end; 245 1.2 christos } 246 1.2 christos break; 247 1.2 christos case OPT_RAWIN: 248 1.2 christos rawin = 1; 249 1.2 christos break; 250 1.2 christos case OPT_DIGEST: 251 1.2 christos digestname = opt_arg(); 252 1.2 christos break; 253 1.2 christos } 254 1.2 christos } 255 1.2 christos 256 1.2 christos /* No extra arguments. */ 257 1.2 christos argc = opt_num_rest(); 258 1.2 christos if (argc != 0) 259 1.2 christos goto opthelp; 260 1.2 christos 261 1.2 christos if (!app_RAND_load()) 262 1.2 christos goto end; 263 1.2 christos 264 1.2 christos if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) { 265 1.2 christos BIO_printf(bio_err, 266 1.2 christos "%s: -rawin can only be used with -sign or -verify\n", 267 1.2 christos prog); 268 1.2 christos goto opthelp; 269 1.2 christos } 270 1.2 christos 271 1.2 christos if (digestname != NULL && !rawin) { 272 1.2 christos BIO_printf(bio_err, 273 1.2 christos "%s: -digest can only be used with -rawin\n", 274 1.2 christos prog); 275 1.2 christos goto opthelp; 276 1.2 christos } 277 1.2 christos 278 1.2 christos if (rawin && rev) { 279 1.2 christos BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n", 280 1.2 christos prog); 281 1.2 christos goto opthelp; 282 1.2 christos } 283 1.2 christos 284 1.2 christos if (kdfalg != NULL) { 285 1.2 christos if (kdflen == 0) { 286 1.2 christos BIO_printf(bio_err, 287 1.2 christos "%s: no KDF length given (-kdflen parameter).\n", prog); 288 1.2 christos goto opthelp; 289 1.2 christos } 290 1.2 christos } else if (inkey == NULL) { 291 1.2 christos BIO_printf(bio_err, 292 1.2 christos "%s: no private key given (-inkey parameter).\n", prog); 293 1.2 christos goto opthelp; 294 1.2 christos } else if (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE) { 295 1.2 christos BIO_printf(bio_err, 296 1.2 christos "%s: no peer key given (-peerkey parameter).\n", prog); 297 1.2 christos goto opthelp; 298 1.2 christos } 299 1.2 christos 300 1.2 christos if (rawin) { 301 1.2 christos if ((mctx = EVP_MD_CTX_new()) == NULL) { 302 1.2 christos BIO_printf(bio_err, "Error: out of memory\n"); 303 1.2 christos goto end; 304 1.2 christos } 305 1.2 christos } 306 1.2 christos ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type, 307 1.2 christos passinarg, pkey_op, e, engine_impl, rawin, &pkey, 308 1.2 christos mctx, digestname, libctx, app_get0_propq()); 309 1.2 christos if (ctx == NULL) { 310 1.2 christos BIO_printf(bio_err, "%s: Error initializing context\n", prog); 311 1.2 christos goto end; 312 1.2 christos } 313 1.2 christos if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) { 314 1.2 christos BIO_printf(bio_err, "%s: Error setting up peer key\n", prog); 315 1.2 christos goto end; 316 1.2 christos } 317 1.2 christos if (pkeyopts != NULL) { 318 1.2 christos int num = sk_OPENSSL_STRING_num(pkeyopts); 319 1.2 christos int i; 320 1.2 christos 321 1.2 christos for (i = 0; i < num; ++i) { 322 1.2 christos const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i); 323 1.2 christos 324 1.2 christos if (pkey_ctrl_string(ctx, opt) <= 0) { 325 1.2 christos BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", 326 1.2 christos prog, opt); 327 1.2 christos goto end; 328 1.2 christos } 329 1.2 christos } 330 1.2 christos } 331 1.2 christos if (pkeyopts_passin != NULL) { 332 1.2 christos int num = sk_OPENSSL_STRING_num(pkeyopts_passin); 333 1.2 christos int i; 334 1.2 christos 335 1.2 christos for (i = 0; i < num; i++) { 336 1.2 christos char *opt = sk_OPENSSL_STRING_value(pkeyopts_passin, i); 337 1.2 christos char *passin = strchr(opt, ':'); 338 1.2 christos char *passwd; 339 1.2 christos 340 1.2 christos if (passin == NULL) { 341 1.2 christos /* Get password interactively */ 342 1.2 christos char passwd_buf[4096]; 343 1.2 christos int r; 344 1.2 christos 345 1.2 christos BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); 346 1.2 christos r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, 347 1.2 christos passwd_buf, 0); 348 1.2 christos if (r < 0) { 349 1.2 christos if (r == -2) 350 1.2 christos BIO_puts(bio_err, "user abort\n"); 351 1.2 christos else 352 1.2 christos BIO_puts(bio_err, "entry failed\n"); 353 1.2 christos goto end; 354 1.2 christos } 355 1.2 christos passwd = OPENSSL_strdup(passwd_buf); 356 1.2 christos if (passwd == NULL) { 357 1.2 christos BIO_puts(bio_err, "out of memory\n"); 358 1.2 christos goto end; 359 1.2 christos } 360 1.2 christos } else { 361 1.2 christos /* Get password as a passin argument: First split option name 362 1.2 christos * and passphrase argument into two strings */ 363 1.2 christos *passin = 0; 364 1.2 christos passin++; 365 1.2 christos if (app_passwd(passin, NULL, &passwd, NULL) == 0) { 366 1.2 christos BIO_printf(bio_err, "failed to get '%s'\n", opt); 367 1.2 christos goto end; 368 1.2 christos } 369 1.2 christos } 370 1.2 christos 371 1.2 christos if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) { 372 1.2 christos BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n", 373 1.2 christos prog, opt); 374 1.2 christos goto end; 375 1.2 christos } 376 1.2 christos OPENSSL_free(passwd); 377 1.2 christos } 378 1.2 christos } 379 1.2 christos 380 1.2 christos if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) { 381 1.2 christos BIO_printf(bio_err, 382 1.2 christos "%s: Signature file specified for non verify\n", prog); 383 1.2 christos goto end; 384 1.2 christos } 385 1.2 christos 386 1.2 christos if (sigfile == NULL && (pkey_op == EVP_PKEY_OP_VERIFY)) { 387 1.2 christos BIO_printf(bio_err, 388 1.2 christos "%s: No signature file specified for verify\n", prog); 389 1.2 christos goto end; 390 1.2 christos } 391 1.2 christos 392 1.2 christos if (pkey_op != EVP_PKEY_OP_DERIVE) { 393 1.2 christos in = bio_open_default(infile, 'r', FORMAT_BINARY); 394 1.2 christos if (infile != NULL) { 395 1.2 christos struct stat st; 396 1.2 christos 397 1.2 christos if (stat(infile, &st) == 0 && st.st_size <= INT_MAX) 398 1.2 christos filesize = (int)st.st_size; 399 1.2 christos } 400 1.2 christos if (in == NULL) 401 1.2 christos goto end; 402 1.2 christos } 403 1.2 christos out = bio_open_default(outfile, 'w', FORMAT_BINARY); 404 1.2 christos if (out == NULL) 405 1.2 christos goto end; 406 1.2 christos 407 1.2 christos if (sigfile != NULL) { 408 1.2 christos BIO *sigbio = BIO_new_file(sigfile, "rb"); 409 1.2 christos 410 1.2 christos if (sigbio == NULL) { 411 1.2 christos BIO_printf(bio_err, "Can't open signature file %s\n", sigfile); 412 1.2 christos goto end; 413 1.2 christos } 414 1.2 christos siglen = bio_to_mem(&sig, keysize * 10, sigbio); 415 1.2 christos BIO_free(sigbio); 416 1.2 christos if (siglen < 0) { 417 1.2 christos BIO_printf(bio_err, "Error reading signature data\n"); 418 1.2 christos goto end; 419 1.2 christos } 420 1.2 christos } 421 1.2 christos 422 1.2 christos /* Raw input data is handled elsewhere */ 423 1.2 christos if (in != NULL && !rawin) { 424 1.2 christos /* Read the input data */ 425 1.2 christos buf_inlen = bio_to_mem(&buf_in, -1, in); 426 1.2 christos if (buf_inlen < 0) { 427 1.2 christos BIO_printf(bio_err, "Error reading input Data\n"); 428 1.2 christos goto end; 429 1.2 christos } 430 1.2 christos if (rev) { 431 1.2 christos size_t i; 432 1.2 christos unsigned char ctmp; 433 1.2 christos size_t l = (size_t)buf_inlen; 434 1.2 christos for (i = 0; i < l / 2; i++) { 435 1.2 christos ctmp = buf_in[i]; 436 1.2 christos buf_in[i] = buf_in[l - 1 - i]; 437 1.2 christos buf_in[l - 1 - i] = ctmp; 438 1.2 christos } 439 1.2 christos } 440 1.2 christos } 441 1.2 christos 442 1.2 christos /* Sanity check the input if the input is not raw */ 443 1.2 christos if (!rawin 444 1.2 christos && buf_inlen > EVP_MAX_MD_SIZE 445 1.2 christos && (pkey_op == EVP_PKEY_OP_SIGN 446 1.2 christos || pkey_op == EVP_PKEY_OP_VERIFY)) { 447 1.2 christos BIO_printf(bio_err, 448 1.2 christos "Error: The input data looks too long to be a hash\n"); 449 1.2 christos goto end; 450 1.2 christos } 451 1.2 christos 452 1.2 christos if (pkey_op == EVP_PKEY_OP_VERIFY) { 453 1.2 christos if (rawin) { 454 1.2 christos rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, sig, siglen, 455 1.2 christos NULL, 0); 456 1.2 christos } else { 457 1.2 christos rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, 458 1.2 christos buf_in, (size_t)buf_inlen); 459 1.2 christos } 460 1.2 christos if (rv == 1) { 461 1.2 christos BIO_puts(out, "Signature Verified Successfully\n"); 462 1.2 christos ret = 0; 463 1.2 christos } else { 464 1.2 christos BIO_puts(out, "Signature Verification Failure\n"); 465 1.2 christos } 466 1.2 christos goto end; 467 1.2 christos } 468 1.2 christos if (rawin) { 469 1.2 christos /* rawin allocates the buffer in do_raw_keyop() */ 470 1.2 christos rv = do_raw_keyop(pkey_op, mctx, pkey, in, filesize, NULL, 0, 471 1.2 christos &buf_out, (size_t *)&buf_outlen); 472 1.2 christos } else { 473 1.2 christos if (kdflen != 0) { 474 1.2 christos buf_outlen = kdflen; 475 1.2 christos rv = 1; 476 1.2 christos } else { 477 1.2 christos rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, 478 1.2 christos buf_in, (size_t)buf_inlen); 479 1.2 christos } 480 1.2 christos if (rv > 0 && buf_outlen != 0) { 481 1.2 christos buf_out = app_malloc(buf_outlen, "buffer output"); 482 1.2 christos rv = do_keyop(ctx, pkey_op, 483 1.2 christos buf_out, (size_t *)&buf_outlen, 484 1.2 christos buf_in, (size_t)buf_inlen); 485 1.2 christos } 486 1.2 christos } 487 1.2 christos if (rv <= 0) { 488 1.2 christos if (pkey_op != EVP_PKEY_OP_DERIVE) { 489 1.2 christos BIO_puts(bio_err, "Public Key operation error\n"); 490 1.2 christos } else { 491 1.2 christos BIO_puts(bio_err, "Key derivation failed\n"); 492 1.2 christos } 493 1.2 christos goto end; 494 1.2 christos } 495 1.2 christos ret = 0; 496 1.2 christos 497 1.2 christos if (asn1parse) { 498 1.2 christos if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) 499 1.2 christos ERR_print_errors(bio_err); /* but still return success */ 500 1.2 christos } else if (hexdump) { 501 1.2 christos BIO_dump(out, (char *)buf_out, buf_outlen); 502 1.2 christos } else { 503 1.2 christos BIO_write(out, buf_out, buf_outlen); 504 1.2 christos } 505 1.2 christos 506 1.2 christos end: 507 1.2 christos if (ret != 0) 508 1.2 christos ERR_print_errors(bio_err); 509 1.2 christos EVP_MD_CTX_free(mctx); 510 1.2 christos EVP_PKEY_CTX_free(ctx); 511 1.2 christos EVP_MD_free(md); 512 1.2 christos release_engine(e); 513 1.2 christos BIO_free(in); 514 1.2 christos BIO_free_all(out); 515 1.2 christos OPENSSL_free(buf_in); 516 1.2 christos OPENSSL_free(buf_out); 517 1.2 christos OPENSSL_free(sig); 518 1.2 christos sk_OPENSSL_STRING_free(pkeyopts); 519 1.2 christos sk_OPENSSL_STRING_free(pkeyopts_passin); 520 1.2 christos NCONF_free(conf); 521 1.2 christos return ret; 522 1.2 christos } 523 1.1 christos 524 1.2 christos static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, 525 1.2 christos const char *keyfile, int keyform, int key_type, 526 1.2 christos char *passinarg, int pkey_op, ENGINE *e, 527 1.2 christos const int engine_impl, int rawin, 528 1.2 christos EVP_PKEY **ppkey, EVP_MD_CTX *mctx, const char *digestname, 529 1.2 christos OSSL_LIB_CTX *libctx, const char *propq) 530 1.2 christos { 531 1.2 christos EVP_PKEY *pkey = NULL; 532 1.2 christos EVP_PKEY_CTX *ctx = NULL; 533 1.2 christos ENGINE *impl = NULL; 534 1.2 christos char *passin = NULL; 535 1.2 christos int rv = -1; 536 1.2 christos X509 *x; 537 1.2 christos 538 1.2 christos if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 539 1.2 christos || (pkey_op == EVP_PKEY_OP_DERIVE)) 540 1.2 christos && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { 541 1.2 christos BIO_printf(bio_err, "A private key is needed for this operation\n"); 542 1.2 christos goto end; 543 1.2 christos } 544 1.2 christos if (!app_passwd(passinarg, NULL, &passin, NULL)) { 545 1.2 christos BIO_printf(bio_err, "Error getting password\n"); 546 1.2 christos goto end; 547 1.2 christos } 548 1.2 christos switch (key_type) { 549 1.2 christos case KEY_PRIVKEY: 550 1.2 christos pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); 551 1.2 christos break; 552 1.2 christos 553 1.2 christos case KEY_PUBKEY: 554 1.2 christos pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); 555 1.2 christos break; 556 1.2 christos 557 1.2 christos case KEY_CERT: 558 1.2 christos x = load_cert(keyfile, keyform, "Certificate"); 559 1.2 christos if (x) { 560 1.2 christos pkey = X509_get_pubkey(x); 561 1.2 christos X509_free(x); 562 1.2 christos } 563 1.2 christos break; 564 1.1 christos 565 1.2 christos case KEY_NONE: 566 1.2 christos break; 567 1.1 christos 568 1.2 christos } 569 1.1 christos 570 1.1 christos #ifndef OPENSSL_NO_ENGINE 571 1.2 christos if (engine_impl) 572 1.2 christos impl = e; 573 1.1 christos #endif 574 1.1 christos 575 1.2 christos if (kdfalg != NULL) { 576 1.2 christos int kdfnid = OBJ_sn2nid(kdfalg); 577 1.2 christos 578 1.2 christos if (kdfnid == NID_undef) { 579 1.2 christos kdfnid = OBJ_ln2nid(kdfalg); 580 1.2 christos if (kdfnid == NID_undef) { 581 1.2 christos BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n", 582 1.2 christos kdfalg); 583 1.2 christos goto end; 584 1.2 christos } 585 1.2 christos } 586 1.2 christos if (impl != NULL) 587 1.2 christos ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); 588 1.2 christos else 589 1.2 christos ctx = EVP_PKEY_CTX_new_from_name(libctx, kdfalg, propq); 590 1.2 christos } else { 591 1.2 christos if (pkey == NULL) 592 1.2 christos goto end; 593 1.2 christos 594 1.2 christos *pkeysize = EVP_PKEY_get_size(pkey); 595 1.2 christos if (impl != NULL) 596 1.2 christos ctx = EVP_PKEY_CTX_new(pkey, impl); 597 1.2 christos else 598 1.2 christos ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); 599 1.2 christos if (ppkey != NULL) 600 1.2 christos *ppkey = pkey; 601 1.2 christos EVP_PKEY_free(pkey); 602 1.2 christos } 603 1.2 christos 604 1.2 christos if (ctx == NULL) 605 1.2 christos goto end; 606 1.2 christos 607 1.2 christos if (rawin) { 608 1.2 christos EVP_MD_CTX_set_pkey_ctx(mctx, ctx); 609 1.2 christos 610 1.2 christos switch (pkey_op) { 611 1.2 christos case EVP_PKEY_OP_SIGN: 612 1.2 christos rv = EVP_DigestSignInit_ex(mctx, NULL, digestname, libctx, propq, 613 1.2 christos pkey, NULL); 614 1.2 christos break; 615 1.2 christos 616 1.2 christos case EVP_PKEY_OP_VERIFY: 617 1.2 christos rv = EVP_DigestVerifyInit_ex(mctx, NULL, digestname, libctx, propq, 618 1.2 christos pkey, NULL); 619 1.2 christos break; 620 1.2 christos } 621 1.2 christos 622 1.2 christos } else { 623 1.2 christos switch (pkey_op) { 624 1.2 christos case EVP_PKEY_OP_SIGN: 625 1.2 christos rv = EVP_PKEY_sign_init(ctx); 626 1.2 christos break; 627 1.2 christos 628 1.2 christos case EVP_PKEY_OP_VERIFY: 629 1.2 christos rv = EVP_PKEY_verify_init(ctx); 630 1.2 christos break; 631 1.2 christos 632 1.2 christos case EVP_PKEY_OP_VERIFYRECOVER: 633 1.2 christos rv = EVP_PKEY_verify_recover_init(ctx); 634 1.2 christos break; 635 1.2 christos 636 1.2 christos case EVP_PKEY_OP_ENCRYPT: 637 1.2 christos rv = EVP_PKEY_encrypt_init(ctx); 638 1.2 christos break; 639 1.2 christos 640 1.2 christos case EVP_PKEY_OP_DECRYPT: 641 1.2 christos rv = EVP_PKEY_decrypt_init(ctx); 642 1.2 christos break; 643 1.2 christos 644 1.2 christos case EVP_PKEY_OP_DERIVE: 645 1.2 christos rv = EVP_PKEY_derive_init(ctx); 646 1.2 christos break; 647 1.2 christos } 648 1.2 christos } 649 1.2 christos 650 1.2 christos if (rv <= 0) { 651 1.2 christos EVP_PKEY_CTX_free(ctx); 652 1.2 christos ctx = NULL; 653 1.2 christos } 654 1.2 christos 655 1.2 christos end: 656 1.2 christos OPENSSL_free(passin); 657 1.2 christos return ctx; 658 1.2 christos 659 1.2 christos } 660 1.2 christos 661 1.2 christos static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, 662 1.2 christos ENGINE *e) 663 1.2 christos { 664 1.2 christos EVP_PKEY *peer = NULL; 665 1.2 christos ENGINE *engine = NULL; 666 1.2 christos int ret; 667 1.2 christos 668 1.2 christos if (peerform == FORMAT_ENGINE) 669 1.2 christos engine = e; 670 1.2 christos peer = load_pubkey(file, peerform, 0, NULL, engine, "peer key"); 671 1.2 christos if (peer == NULL) { 672 1.2 christos BIO_printf(bio_err, "Error reading peer key %s\n", file); 673 1.2 christos return 0; 674 1.2 christos } 675 1.2 christos 676 1.2 christos ret = EVP_PKEY_derive_set_peer(ctx, peer) > 0; 677 1.2 christos 678 1.2 christos EVP_PKEY_free(peer); 679 1.2 christos return ret; 680 1.1 christos } 681 1.1 christos 682 1.2 christos static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op, 683 1.2 christos unsigned char *out, size_t *poutlen, 684 1.2 christos const unsigned char *in, size_t inlen) 685 1.1 christos { 686 1.2 christos int rv = 0; 687 1.2 christos switch (pkey_op) { 688 1.2 christos case EVP_PKEY_OP_VERIFYRECOVER: 689 1.2 christos rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen); 690 1.2 christos break; 691 1.2 christos 692 1.2 christos case EVP_PKEY_OP_SIGN: 693 1.2 christos rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen); 694 1.2 christos break; 695 1.2 christos 696 1.2 christos case EVP_PKEY_OP_ENCRYPT: 697 1.2 christos rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen); 698 1.2 christos break; 699 1.2 christos 700 1.2 christos case EVP_PKEY_OP_DECRYPT: 701 1.2 christos rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen); 702 1.2 christos break; 703 1.2 christos 704 1.2 christos case EVP_PKEY_OP_DERIVE: 705 1.2 christos rv = EVP_PKEY_derive(ctx, out, poutlen); 706 1.2 christos break; 707 1.1 christos 708 1.2 christos } 709 1.2 christos return rv; 710 1.1 christos } 711 1.1 christos 712 1.2 christos #define TBUF_MAXSIZE 2048 713 1.1 christos 714 1.2 christos static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx, 715 1.2 christos EVP_PKEY *pkey, BIO *in, 716 1.2 christos int filesize, unsigned char *sig, int siglen, 717 1.2 christos unsigned char **out, size_t *poutlen) 718 1.2 christos { 719 1.2 christos int rv = 0; 720 1.2 christos unsigned char tbuf[TBUF_MAXSIZE]; 721 1.2 christos unsigned char *mbuf = NULL; 722 1.2 christos int buf_len = 0; 723 1.2 christos 724 1.2 christos /* Some algorithms only support oneshot digests */ 725 1.2 christos if (EVP_PKEY_get_id(pkey) == EVP_PKEY_ED25519 726 1.2 christos || EVP_PKEY_get_id(pkey) == EVP_PKEY_ED448) { 727 1.2 christos if (filesize < 0) { 728 1.2 christos BIO_printf(bio_err, 729 1.2 christos "Error: unable to determine file size for oneshot operation\n"); 730 1.2 christos goto end; 731 1.2 christos } 732 1.2 christos mbuf = app_malloc(filesize, "oneshot sign/verify buffer"); 733 1.2 christos switch(pkey_op) { 734 1.2 christos case EVP_PKEY_OP_VERIFY: 735 1.2 christos buf_len = BIO_read(in, mbuf, filesize); 736 1.2 christos if (buf_len != filesize) { 737 1.2 christos BIO_printf(bio_err, "Error reading raw input data\n"); 738 1.2 christos goto end; 739 1.2 christos } 740 1.2 christos rv = EVP_DigestVerify(mctx, sig, (size_t)siglen, mbuf, buf_len); 741 1.2 christos break; 742 1.2 christos case EVP_PKEY_OP_SIGN: 743 1.2 christos buf_len = BIO_read(in, mbuf, filesize); 744 1.2 christos if (buf_len != filesize) { 745 1.2 christos BIO_printf(bio_err, "Error reading raw input data\n"); 746 1.2 christos goto end; 747 1.2 christos } 748 1.2 christos rv = EVP_DigestSign(mctx, NULL, poutlen, mbuf, buf_len); 749 1.2 christos if (rv == 1 && out != NULL) { 750 1.2 christos *out = app_malloc(*poutlen, "buffer output"); 751 1.2 christos rv = EVP_DigestSign(mctx, *out, poutlen, mbuf, buf_len); 752 1.2 christos } 753 1.2 christos break; 754 1.2 christos } 755 1.2 christos goto end; 756 1.2 christos } 757 1.2 christos 758 1.2 christos switch(pkey_op) { 759 1.2 christos case EVP_PKEY_OP_VERIFY: 760 1.2 christos for (;;) { 761 1.2 christos buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); 762 1.2 christos if (buf_len == 0) 763 1.2 christos break; 764 1.2 christos if (buf_len < 0) { 765 1.2 christos BIO_printf(bio_err, "Error reading raw input data\n"); 766 1.2 christos goto end; 767 1.2 christos } 768 1.2 christos rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)buf_len); 769 1.2 christos if (rv != 1) { 770 1.2 christos BIO_printf(bio_err, "Error verifying raw input data\n"); 771 1.2 christos goto end; 772 1.2 christos } 773 1.2 christos } 774 1.2 christos rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen); 775 1.2 christos break; 776 1.2 christos case EVP_PKEY_OP_SIGN: 777 1.2 christos for (;;) { 778 1.2 christos buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE); 779 1.2 christos if (buf_len == 0) 780 1.2 christos break; 781 1.2 christos if (buf_len < 0) { 782 1.2 christos BIO_printf(bio_err, "Error reading raw input data\n"); 783 1.2 christos goto end; 784 1.2 christos } 785 1.2 christos rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)buf_len); 786 1.2 christos if (rv != 1) { 787 1.2 christos BIO_printf(bio_err, "Error signing raw input data\n"); 788 1.2 christos goto end; 789 1.2 christos } 790 1.2 christos } 791 1.2 christos rv = EVP_DigestSignFinal(mctx, NULL, poutlen); 792 1.2 christos if (rv == 1 && out != NULL) { 793 1.2 christos *out = app_malloc(*poutlen, "buffer output"); 794 1.2 christos rv = EVP_DigestSignFinal(mctx, *out, poutlen); 795 1.2 christos } 796 1.2 christos break; 797 1.2 christos } 798 1.2 christos 799 1.2 christos end: 800 1.2 christos OPENSSL_free(mbuf); 801 1.2 christos return rv; 802 1.2 christos } 803