From 2022cfe07e331dc4b69829ca4dd45c295190d471 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 11 Apr 2007 17:20:40 +0000 Subject: [PATCH] New -mac and -macopt options to dgst utility. Reimplement -hmac option in terms of new API. --- CHANGES | 3 +- apps/apps.h | 2 + apps/dgst.c | 98 +++++++++++++++++++++++++++++++------------ apps/genpkey.c | 6 +-- crypto/evp/evp.h | 3 ++ crypto/evp/pmeth_gn.c | 21 ++++++++++ 6 files changed, 102 insertions(+), 31 deletions(-) diff --git a/CHANGES b/CHANGES index 060fcd822b..70561f7d05 100644 --- a/CHANGES +++ b/CHANGES @@ -7,7 +7,8 @@ *) Experimental support for use of HMAC via EVP_PKEY interface. This allows HMAC to be handled via the EVP_DigestSign*() interface. The EVP_PKEY "key" in this case is the HMAC key, potentially allowing - ENGINE support for HMAC keys which are unextractable. + ENGINE support for HMAC keys which are unextractable. New -mac and + -macopt options to dgst utility. [Steve Henson] *) New option -sigopt to dgst utility. Update dgst to use diff --git a/apps/apps.h b/apps/apps.h index 3b5febac7d..c7e490a271 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -294,6 +294,8 @@ int args_verify(char ***pargs, int *pargc, void policies_print(BIO *out, X509_STORE_CTX *ctx); int bio_to_mem(unsigned char **out, int maxlen, BIO *in); int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value); +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, + const char *algname, ENGINE *e, int do_param); #define FORMAT_UNDEF 0 #define FORMAT_ASN1 1 diff --git a/apps/dgst.c b/apps/dgst.c index 70db078d36..a20a5cba7c 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -76,7 +76,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title, - const char *file,BIO *bmd,const char *hmac_key); + const char *file,BIO *bmd); int MAIN(int, char **); @@ -106,7 +106,8 @@ int MAIN(int argc, char **argv) char *engine=NULL; #endif char *hmac_key=NULL; - STACK *sigopts = NULL; + char *mac_name=NULL; + STACK *sigopts = NULL, *macopts = NULL; apps_startup(); @@ -198,6 +199,12 @@ int MAIN(int argc, char **argv) break; hmac_key=*++argv; } + else if (!strcmp(*argv,"-mac")) + { + if (--argc < 1) + break; + mac_name=*++argv; + } else if (strcmp(*argv,"-sigopt") == 0) { if (--argc < 1) @@ -207,6 +214,15 @@ int MAIN(int argc, char **argv) if (!sigopts || !sk_push(sigopts, *(++argv))) break; } + else if (strcmp(*argv,"-macopt") == 0) + { + if (--argc < 1) + break; + if (!macopts) + macopts = sk_new_null(); + if (!macopts || !sk_push(macopts, *(++argv))) + break; + } else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) md=m; else @@ -326,6 +342,11 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } + if ((!!mac_name + !!keyfile + !!hmac_key) > 1) + { + BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); + goto end; + } if(keyfile) { @@ -343,6 +364,50 @@ int MAIN(int argc, char **argv) } } + if (mac_name) + { + EVP_PKEY_CTX *mac_ctx = NULL; + int r = 0; + if (!init_gen_str(bio_err, &mac_ctx, mac_name,e, 0)) + goto mac_end; + if (macopts) + { + char *macopt; + for (i = 0; i < sk_num(macopts); i++) + { + macopt = sk_value(macopts, i); + if (pkey_ctrl_string(mac_ctx, macopt) <= 0) + { + BIO_printf(bio_err, + "MAC parameter error \"%s\"\n", + macopt); + ERR_print_errors(bio_err); + goto mac_end; + } + } + } + if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) + { + BIO_puts(bio_err, "Error generating key\n"); + ERR_print_errors(bio_err); + goto mac_end; + } + r = 1; + mac_end: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + if (r == 0) + goto end; + } + + if (hmac_key) + { + sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, e, + (unsigned char *)hmac_key, -1); + if (!sigkey) + goto end; + } + if (sigkey) { EVP_MD_CTX *mctx = NULL; @@ -410,7 +475,7 @@ int MAIN(int argc, char **argv) { BIO_set_fp(in,stdin,BIO_NOCLOSE); err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, - siglen,"","(stdin)",bmd,hmac_key); + siglen,"","(stdin)",bmd); } else { @@ -436,7 +501,7 @@ int MAIN(int argc, char **argv) else tmp=""; r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, - siglen,tmp,argv[i],bmd,hmac_key); + siglen,tmp,argv[i],bmd); if(r) err=r; if(tofree) @@ -457,6 +522,8 @@ end: EVP_PKEY_free(sigkey); if (sigopts) sk_free(sigopts); + if (macopts) + sk_free(macopts); if(sigbuf) OPENSSL_free(sigbuf); if (bmd != NULL) BIO_free(bmd); apps_shutdown(); @@ -465,23 +532,11 @@ end: int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title, - const char *file,BIO *bmd,const char *hmac_key) + const char *file,BIO *bmd) { unsigned int len; int i; - EVP_MD_CTX *md_ctx; - HMAC_CTX hmac_ctx; - if (hmac_key) - { - EVP_MD *md; - - BIO_get_md(bmd,&md); - HMAC_CTX_init(&hmac_ctx); - HMAC_Init_ex(&hmac_ctx,hmac_key,strlen(hmac_key),md, NULL); - BIO_get_md_ctx(bmd,&md_ctx); - BIO_set_md_ctx(bmd,&hmac_ctx.md_ctx); - } for (;;) { i=BIO_read(bp,(char *)buf,BUFSIZE); @@ -524,11 +579,6 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, return 1; } } - else if(hmac_key) - { - HMAC_Final(&hmac_ctx,buf,&len); - HMAC_CTX_cleanup(&hmac_ctx); - } else len=BIO_gets(bp,(char *)buf,BUFSIZE); @@ -544,10 +594,6 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, } BIO_printf(out, "\n"); } - if (hmac_key) - { - BIO_set_md_ctx(bmd,md_ctx); - } return 0; } diff --git a/apps/genpkey.c b/apps/genpkey.c index 1d1a53e84b..722aa3ce67 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -67,8 +67,6 @@ static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, const char *file, ENGINE *e); -static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param); static int genpkey_cb(EVP_PKEY_CTX *ctx); #define PROG genpkey_main @@ -362,8 +360,8 @@ static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx, } -static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param) +int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, + const char *algname, ENGINE *e, int do_param) { EVP_PKEY_CTX *ctx = NULL; const EVP_PKEY_ASN1_METHOD *ameth; diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index b2fb2a6a4b..7b979504e6 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -1027,6 +1027,9 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + unsigned char *key, int keylen); + void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index eb81d52134..17e0d5473a 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -196,3 +196,24 @@ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) return 0; return ctx->keygen_info[idx]; } + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + unsigned char *key, int keylen) + { + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *mac_key = NULL; + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) + return NULL; + if (EVP_PKEY_keygen_init(mac_ctx) <= 0) + goto merr; + if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0) + goto merr; + if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) + goto merr; + merr: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + return mac_key; + } -- 2.34.1