Fix crash and latest update.
This commit is contained in:
+13
-1
@@ -48,6 +48,8 @@ static int WIN32_rename(const char *from, const char *to);
|
||||
# define rename(from,to) WIN32_rename((from),(to))
|
||||
#endif
|
||||
|
||||
#define PASS_SOURCE_SIZE_MAX 4
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
unsigned long flag;
|
||||
@@ -205,6 +207,7 @@ static char *app_get_pass(const char *arg, int keepbio)
|
||||
char *tmp, tpass[APP_PASS_LEN];
|
||||
int i;
|
||||
|
||||
/* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */
|
||||
if (strncmp(arg, "pass:", 5) == 0)
|
||||
return OPENSSL_strdup(arg + 5);
|
||||
if (strncmp(arg, "env:", 4) == 0) {
|
||||
@@ -253,7 +256,16 @@ static char *app_get_pass(const char *arg, int keepbio)
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg);
|
||||
/* argument syntax error; do not reveal too much about arg */
|
||||
tmp = strchr(arg, ':');
|
||||
if (tmp == NULL || tmp - arg > PASS_SOURCE_SIZE_MAX)
|
||||
BIO_printf(bio_err,
|
||||
"Invalid password argument, missing ':' within the first %d chars\n",
|
||||
PASS_SOURCE_SIZE_MAX + 1);
|
||||
else
|
||||
BIO_printf(bio_err,
|
||||
"Invalid password argument, starting with \"%.*s\"\n",
|
||||
(int)(tmp - arg + 1), arg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,10 +2,10 @@
|
||||
qw(openssl.c
|
||||
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
|
||||
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
|
||||
genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c
|
||||
pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c
|
||||
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c
|
||||
srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
|
||||
genpkey.c genrsa.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c
|
||||
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c
|
||||
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c
|
||||
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
|
||||
our @apps_lib_src =
|
||||
( qw(apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c
|
||||
bf_prefix.c),
|
||||
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#undef BUFSIZE
|
||||
#define BUFSIZE 1024*8
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_MACOPT, OPT_BIN, OPT_IN, OPT_OUT
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS mac_options[] = {
|
||||
{OPT_HELP_STR, 1, '-', "Usage: %s [options] mac_name\n"},
|
||||
{OPT_HELP_STR, 1, '-', "mac_name\t\t MAC algorithm (See list "
|
||||
"-mac-algorithms)"},
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"macopt", OPT_MACOPT, 's', "MAC algorithm control parameters in n:v form. "
|
||||
"See 'Supported Controls' in the EVP_MAC_ docs"},
|
||||
{"in", OPT_IN, '<', "Input file to MAC (default is stdin)"},
|
||||
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
|
||||
{"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal "
|
||||
"output)"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static int mac_ctrl_string(EVP_MAC_CTX *ctx, const char *value)
|
||||
{
|
||||
int rv;
|
||||
char *stmp, *vtmp = NULL;
|
||||
|
||||
stmp = OPENSSL_strdup(value);
|
||||
if (stmp == NULL)
|
||||
return -1;
|
||||
vtmp = strchr(stmp, ':');
|
||||
if (vtmp != NULL) {
|
||||
*vtmp = 0;
|
||||
vtmp++;
|
||||
}
|
||||
rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp);
|
||||
OPENSSL_free(stmp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int mac_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog;
|
||||
const EVP_MAC *mac = NULL;
|
||||
OPTION_CHOICE o;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *opts = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
size_t len;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
const char *outfile = NULL;
|
||||
const char *infile = NULL;
|
||||
int out_bin = 0;
|
||||
int inform = FORMAT_BINARY;
|
||||
|
||||
prog = opt_init(argc, argv, mac_options);
|
||||
buf = app_malloc(BUFSIZE, "I/O buffer");
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
opthelp:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto err;
|
||||
case OPT_HELP:
|
||||
opt_help(mac_options);
|
||||
ret = 0;
|
||||
goto err;
|
||||
case OPT_BIN:
|
||||
out_bin = 1;
|
||||
break;
|
||||
case OPT_IN:
|
||||
infile = opt_arg();
|
||||
break;
|
||||
case OPT_OUT:
|
||||
outfile = opt_arg();
|
||||
break;
|
||||
case OPT_MACOPT:
|
||||
if (opts == NULL)
|
||||
opts = sk_OPENSSL_STRING_new_null();
|
||||
if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
argv = opt_rest();
|
||||
|
||||
if (argc != 1) {
|
||||
BIO_printf(bio_err, "Invalid number of extra arguments\n");
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
mac = EVP_get_macbyname(argv[0]);
|
||||
if (mac == NULL) {
|
||||
BIO_printf(bio_err, "Invalid MAC name %s\n", argv[0]);
|
||||
goto opthelp;
|
||||
}
|
||||
|
||||
ctx = EVP_MAC_CTX_new(mac);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if (opts != NULL) {
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (mac_ctrl_string(ctx, opt) <= 0) {
|
||||
BIO_printf(bio_err, "MAC parameter error '%s'\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Use text mode for stdin */
|
||||
if (infile == NULL || strcmp(infile, "-") == 0)
|
||||
inform = FORMAT_TEXT;
|
||||
in = bio_open_default(infile, 'r', inform);
|
||||
if (in == NULL)
|
||||
goto err;
|
||||
|
||||
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
|
||||
if (out == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EVP_MAC_init(ctx)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_Init failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
for (;;) {
|
||||
i = BIO_read(in, (char *)buf, BUFSIZE);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Read Error in '%s'\n", infile);
|
||||
goto err;
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
if (!EVP_MAC_update(ctx, buf, i)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_update failed\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EVP_MAC_final(ctx, NULL, &len)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_final failed\n");
|
||||
goto err;
|
||||
}
|
||||
if (len > BUFSIZE) {
|
||||
BIO_printf(bio_err, "output len is too large\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_final(ctx, buf, &len)) {
|
||||
BIO_printf(bio_err, "EVP_MAC_final failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (out_bin) {
|
||||
BIO_write(out, buf, len);
|
||||
} else {
|
||||
if (outfile == NULL)
|
||||
BIO_printf(out,"\n");
|
||||
for (i = 0; i < (int)len; ++i)
|
||||
BIO_printf(out, "%02X", buf[i]);
|
||||
if (outfile == NULL)
|
||||
BIO_printf(out,"\n");
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
OPENSSL_clear_free(buf, BUFSIZE);
|
||||
sk_OPENSSL_STRING_free(opts);
|
||||
BIO_free(in);
|
||||
BIO_free(out);
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
+47
-22
@@ -54,6 +54,7 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
|
||||
static void list_pkey(void);
|
||||
static void list_pkey_meth(void);
|
||||
static void list_type(FUNC_TYPE ft, int one);
|
||||
static void list_engines(void);
|
||||
static void list_disabled(void);
|
||||
char *default_config_file = NULL;
|
||||
|
||||
@@ -125,30 +126,19 @@ typedef struct tracedata_st {
|
||||
static size_t internal_trace_cb(const char *buf, size_t cnt,
|
||||
int category, int cmd, void *vdata)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
tracedata *trace_data = vdata;
|
||||
int set_prefix = 0;
|
||||
union {
|
||||
CRYPTO_THREAD_ID tid;
|
||||
unsigned long ltid;
|
||||
} tid;
|
||||
char buffer[256];
|
||||
|
||||
switch (cmd) {
|
||||
case OSSL_TRACE_CTRL_BEGIN:
|
||||
if (!ossl_assert(!trace_data->ingroup))
|
||||
return 0;
|
||||
trace_data->ingroup = 1;
|
||||
set_prefix = 1;
|
||||
break;
|
||||
case OSSL_TRACE_CTRL_DURING:
|
||||
if (!trace_data->ingroup)
|
||||
set_prefix = 1;
|
||||
break;
|
||||
case OSSL_TRACE_CTRL_END:
|
||||
trace_data->ingroup = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (set_prefix) {
|
||||
union {
|
||||
CRYPTO_THREAD_ID tid;
|
||||
unsigned long ltid;
|
||||
} tid;
|
||||
char buffer[256];
|
||||
|
||||
tid.ltid = 0;
|
||||
tid.tid = CRYPTO_THREAD_get_current_id();
|
||||
@@ -157,8 +147,22 @@ static size_t internal_trace_cb(const char *buf, size_t cnt,
|
||||
OSSL_trace_get_category_name(category));
|
||||
BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX,
|
||||
strlen(buffer), buffer);
|
||||
break;
|
||||
case OSSL_TRACE_CTRL_WRITE:
|
||||
if (!ossl_assert(trace_data->ingroup))
|
||||
return 0;
|
||||
|
||||
ret = BIO_write(trace_data->bio, buf, cnt);
|
||||
break;
|
||||
case OSSL_TRACE_CTRL_END:
|
||||
if (!ossl_assert(trace_data->ingroup))
|
||||
return 0;
|
||||
trace_data->ingroup = 0;
|
||||
|
||||
BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX, 0, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
ret = BIO_write(trace_data->bio, buf, cnt);
|
||||
|
||||
return ret < 0 ? 0 : ret;
|
||||
}
|
||||
@@ -523,8 +527,8 @@ typedef enum HELPLIST_CHOICE {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE,
|
||||
OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
|
||||
OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
|
||||
OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, OPT_MISSING_HELP,
|
||||
OPT_OBJECTS
|
||||
OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_ENGINES, OPT_DISABLED,
|
||||
OPT_MISSING_HELP, OPT_OBJECTS
|
||||
} HELPLIST_CHOICE;
|
||||
|
||||
const OPTIONS list_options[] = {
|
||||
@@ -544,6 +548,8 @@ const OPTIONS list_options[] = {
|
||||
"List of public key algorithms"},
|
||||
{"public-key-methods", OPT_PK_METHOD, '-',
|
||||
"List of public key methods"},
|
||||
{"engines", OPT_ENGINES, '-',
|
||||
"List of loaded engines"},
|
||||
{"disabled", OPT_DISABLED, '-',
|
||||
"List of disabled features"},
|
||||
{"missing-help", OPT_MISSING_HELP, '-',
|
||||
@@ -599,6 +605,9 @@ opthelp:
|
||||
case OPT_PK_METHOD:
|
||||
list_pkey_meth();
|
||||
break;
|
||||
case OPT_ENGINES:
|
||||
list_engines();
|
||||
break;
|
||||
case OPT_DISABLED:
|
||||
list_disabled();
|
||||
break;
|
||||
@@ -837,6 +846,22 @@ static int SortFnByName(const void *_f1, const void *_f2)
|
||||
return strcmp(f1->name, f2->name);
|
||||
}
|
||||
|
||||
static void list_engines(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e;
|
||||
|
||||
BIO_puts(bio_out, "Engines:\n");
|
||||
e = ENGINE_get_first();
|
||||
while (e) {
|
||||
BIO_printf(bio_out, "%s\n", ENGINE_get_id(e));
|
||||
e = ENGINE_get_next(e);
|
||||
}
|
||||
#else
|
||||
BIO_puts(bio_out, "Engine support is disabled.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void list_disabled(void)
|
||||
{
|
||||
BIO_puts(bio_out, "Disabled algorithms:\n");
|
||||
|
||||
+98
-35
@@ -13,6 +13,9 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#define KEY_NONE 0
|
||||
#define KEY_PRIVKEY 1
|
||||
@@ -22,7 +25,7 @@
|
||||
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
|
||||
const char *keyfile, int keyform, int key_type,
|
||||
char *passinarg, int pkey_op, ENGINE *e,
|
||||
const int impl, EVP_PKEY **ppkey);
|
||||
const int impl, int rawin, EVP_PKEY **ppkey);
|
||||
|
||||
static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
|
||||
ENGINE *e);
|
||||
@@ -33,7 +36,7 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
|
||||
|
||||
static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
|
||||
const EVP_MD *md, EVP_PKEY *pkey, BIO *in,
|
||||
unsigned char *sig, int siglen,
|
||||
int filesize, unsigned char *sig, int siglen,
|
||||
unsigned char **out, size_t *poutlen);
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
@@ -109,6 +112,7 @@ int pkeyutl_main(int argc, char **argv)
|
||||
STACK_OF(OPENSSL_STRING) *pkeyopts_passin = NULL;
|
||||
int rawin = 0;
|
||||
const EVP_MD *md = NULL;
|
||||
int filesize = -1;
|
||||
|
||||
prog = opt_init(argc, argv, pkeyutl_options);
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
@@ -264,7 +268,7 @@ int pkeyutl_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
}
|
||||
ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
|
||||
passinarg, pkey_op, e, engine_impl, &pkey);
|
||||
passinarg, pkey_op, e, engine_impl, rawin, &pkey);
|
||||
if (ctx == NULL) {
|
||||
BIO_printf(bio_err, "%s: Error initializing context\n", prog);
|
||||
ERR_print_errors(bio_err);
|
||||
@@ -344,6 +348,15 @@ int pkeyutl_main(int argc, char **argv)
|
||||
|
||||
if (pkey_op != EVP_PKEY_OP_DERIVE) {
|
||||
in = bio_open_default(infile, 'r', FORMAT_BINARY);
|
||||
#ifndef OPENSSL_NO_POSIX_IO
|
||||
if (infile != NULL)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(infile, &st) == 0 && st.st_size <= INT_MAX)
|
||||
filesize = (int)st.st_size;
|
||||
}
|
||||
#endif
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
}
|
||||
@@ -399,7 +412,7 @@ int pkeyutl_main(int argc, char **argv)
|
||||
|
||||
if (pkey_op == EVP_PKEY_OP_VERIFY) {
|
||||
if (rawin) {
|
||||
rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, sig, siglen,
|
||||
rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, filesize, sig, siglen,
|
||||
NULL, 0);
|
||||
} else {
|
||||
rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
|
||||
@@ -419,7 +432,7 @@ int pkeyutl_main(int argc, char **argv)
|
||||
} else {
|
||||
if (rawin) {
|
||||
/* rawin allocates the buffer in do_raw_keyop() */
|
||||
rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, NULL, 0,
|
||||
rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, filesize, NULL, 0,
|
||||
&buf_out, (size_t *)&buf_outlen);
|
||||
} else {
|
||||
rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
|
||||
@@ -468,7 +481,8 @@ int pkeyutl_main(int argc, char **argv)
|
||||
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
|
||||
const char *keyfile, int keyform, int key_type,
|
||||
char *passinarg, int pkey_op, ENGINE *e,
|
||||
const int engine_impl, EVP_PKEY **ppkey)
|
||||
const int engine_impl, int rawin,
|
||||
EVP_PKEY **ppkey)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
@@ -554,30 +568,39 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
|
||||
if (ctx == NULL)
|
||||
goto end;
|
||||
|
||||
switch (pkey_op) {
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign_init(ctx);
|
||||
break;
|
||||
/*
|
||||
* If rawin then we don't need to actually initialise the EVP_PKEY_CTX
|
||||
* itself. That will get initialised during EVP_DigestSignInit or
|
||||
* EVP_DigestVerifyInit.
|
||||
*/
|
||||
if (rawin) {
|
||||
rv = 1;
|
||||
} else {
|
||||
switch (pkey_op) {
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
rv = EVP_PKEY_verify_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
rv = EVP_PKEY_verify_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt_init(ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive_init(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv <= 0) {
|
||||
@@ -649,13 +672,14 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
|
||||
|
||||
static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
|
||||
const EVP_MD *md, EVP_PKEY *pkey, BIO *in,
|
||||
unsigned char *sig, int siglen,
|
||||
int filesize, unsigned char *sig, int siglen,
|
||||
unsigned char **out, size_t *poutlen)
|
||||
{
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
unsigned char tbuf[TBUF_MAXSIZE];
|
||||
int tbuf_len = 0;
|
||||
unsigned char *mbuf = NULL;
|
||||
int buf_len = 0;
|
||||
|
||||
if ((mctx = EVP_MD_CTX_new()) == NULL) {
|
||||
BIO_printf(bio_err, "Error: out of memory\n");
|
||||
@@ -663,19 +687,58 @@ static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
|
||||
}
|
||||
EVP_MD_CTX_set_pkey_ctx(mctx, ctx);
|
||||
|
||||
/* Some algorithms only support oneshot digests */
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519
|
||||
|| EVP_PKEY_id(pkey) == EVP_PKEY_ED448) {
|
||||
if (filesize < 0) {
|
||||
BIO_printf(bio_err,
|
||||
"Error: unable to determine file size for oneshot operation\n");
|
||||
return rv;
|
||||
}
|
||||
mbuf = app_malloc(filesize, "oneshot sign/verify buffer");
|
||||
switch(pkey_op) {
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1)
|
||||
goto end;
|
||||
buf_len = BIO_read(in, mbuf, filesize);
|
||||
if (buf_len != filesize) {
|
||||
BIO_printf(bio_err, "Error reading raw input data\n");
|
||||
goto end;
|
||||
}
|
||||
rv = EVP_DigestVerify(mctx, sig, (size_t)siglen, mbuf, buf_len);
|
||||
break;
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1)
|
||||
goto end;
|
||||
buf_len = BIO_read(in, mbuf, filesize);
|
||||
if (buf_len != filesize) {
|
||||
BIO_printf(bio_err, "Error reading raw input data\n");
|
||||
goto end;
|
||||
}
|
||||
rv = EVP_DigestSign(mctx, NULL, poutlen, mbuf, buf_len);
|
||||
if (rv == 1 && out != NULL) {
|
||||
*out = app_malloc(*poutlen, "buffer output");
|
||||
rv = EVP_DigestSign(mctx, *out, poutlen, mbuf, buf_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
OPENSSL_free(mbuf);
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch(pkey_op) {
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1)
|
||||
goto end;
|
||||
for (;;) {
|
||||
tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
|
||||
if (tbuf_len == 0)
|
||||
buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
|
||||
if (buf_len == 0)
|
||||
break;
|
||||
if (tbuf_len < 0) {
|
||||
if (buf_len < 0) {
|
||||
BIO_printf(bio_err, "Error reading raw input data\n");
|
||||
goto end;
|
||||
}
|
||||
rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)tbuf_len);
|
||||
rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)buf_len);
|
||||
if (rv != 1) {
|
||||
BIO_printf(bio_err, "Error verifying raw input data\n");
|
||||
goto end;
|
||||
@@ -687,14 +750,14 @@ static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
|
||||
if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1)
|
||||
goto end;
|
||||
for (;;) {
|
||||
tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
|
||||
if (tbuf_len == 0)
|
||||
buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
|
||||
if (buf_len == 0)
|
||||
break;
|
||||
if (tbuf_len < 0) {
|
||||
if (buf_len < 0) {
|
||||
BIO_printf(bio_err, "Error reading raw input data\n");
|
||||
goto end;
|
||||
}
|
||||
rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)tbuf_len);
|
||||
rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)buf_len);
|
||||
if (rv != 1) {
|
||||
BIO_printf(bio_err, "Error signing raw input data\n");
|
||||
goto end;
|
||||
|
||||
+40
-5
@@ -21,7 +21,8 @@
|
||||
static int cb(int ok, X509_STORE_CTX *ctx);
|
||||
static int check(X509_STORE *ctx, const char *file,
|
||||
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
|
||||
STACK_OF(X509_CRL) *crls, int show_chain);
|
||||
STACK_OF(X509_CRL) *crls, int show_chain,
|
||||
unsigned char *sm2id, size_t sm2idlen);
|
||||
static int v_verbose = 0, vflags = 0;
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
@@ -29,7 +30,7 @@ typedef enum OPTION_choice {
|
||||
OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
|
||||
OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
|
||||
OPT_V_ENUM, OPT_NAMEOPT,
|
||||
OPT_VERBOSE
|
||||
OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS verify_options[] = {
|
||||
@@ -56,6 +57,12 @@ const OPTIONS verify_options[] = {
|
||||
OPT_V_OPTIONS,
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{"sm2-id", OPT_SM2ID, 's',
|
||||
"Specify an ID string to verify an SM2 certificate"},
|
||||
{"sm2-hex-id", OPT_SM2HEXID, 's',
|
||||
"Specify a hex ID string to verify an SM2 certificate"},
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
@@ -71,6 +78,8 @@ int verify_main(int argc, char **argv)
|
||||
int noCApath = 0, noCAfile = 0;
|
||||
int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
|
||||
OPTION_CHOICE o;
|
||||
unsigned char *sm2_id = NULL;
|
||||
size_t sm2_idlen = 0;
|
||||
|
||||
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
|
||||
goto end;
|
||||
@@ -158,6 +167,19 @@ int verify_main(int argc, char **argv)
|
||||
case OPT_VERBOSE:
|
||||
v_verbose = 1;
|
||||
break;
|
||||
case OPT_SM2ID:
|
||||
/* we assume the input is not a hex string */
|
||||
sm2_id = (unsigned char *)opt_arg();
|
||||
sm2_idlen = strlen((const char *)sm2_id);
|
||||
break;
|
||||
case OPT_SM2HEXID:
|
||||
/* try to parse the input as hex string first */
|
||||
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
|
||||
if (sm2_id == NULL) {
|
||||
BIO_printf(bio_err, "Invalid hex string input\n");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -183,12 +205,13 @@ int verify_main(int argc, char **argv)
|
||||
|
||||
ret = 0;
|
||||
if (argc < 1) {
|
||||
if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1)
|
||||
if (check(store, NULL, untrusted, trusted, crls, show_chain,
|
||||
sm2_id, sm2_idlen) != 1)
|
||||
ret = -1;
|
||||
} else {
|
||||
for (i = 0; i < argc; i++)
|
||||
if (check(store, argv[i], untrusted, trusted, crls,
|
||||
show_chain) != 1)
|
||||
show_chain, sm2_id, sm2_idlen) != 1)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@@ -204,7 +227,8 @@ int verify_main(int argc, char **argv)
|
||||
|
||||
static int check(X509_STORE *ctx, const char *file,
|
||||
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
|
||||
STACK_OF(X509_CRL) *crls, int show_chain)
|
||||
STACK_OF(X509_CRL) *crls, int show_chain,
|
||||
unsigned char *sm2id, size_t sm2idlen)
|
||||
{
|
||||
X509 *x = NULL;
|
||||
int i = 0, ret = 0;
|
||||
@@ -216,6 +240,17 @@ static int check(X509_STORE *ctx, const char *file,
|
||||
if (x == NULL)
|
||||
goto end;
|
||||
|
||||
if (sm2id != NULL) {
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
ASN1_OCTET_STRING v;
|
||||
|
||||
v.data = sm2id;
|
||||
v.length = sm2idlen;
|
||||
|
||||
X509_set_sm2_id(x, &v);
|
||||
#endif
|
||||
}
|
||||
|
||||
csc = X509_STORE_CTX_new();
|
||||
if (csc == NULL) {
|
||||
printf("error %s: X.509 store context allocation failed\n",
|
||||
|
||||
Reference in New Issue
Block a user