Index: openssl/apps/dgst.c |
=================================================================== |
--- openssl/apps/dgst.c (revision 105093) |
+++ openssl/apps/dgst.c (working copy) |
@@ -75,9 +75,30 @@ |
#define PROG dgst_main |
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, int non_fips_allow); |
+ EVP_PKEY *key, unsigned char *sigin, int siglen, |
+ const char *sig_name, const char *md_name, |
+ const char *file,BIO *bmd); |
+static void list_md_fn(const EVP_MD *m, |
+ const char *from, const char *to, void *arg) |
+ { |
+ const char *mname; |
+ /* Skip aliases */ |
+ if (!m) |
+ return; |
+ mname = OBJ_nid2ln(EVP_MD_type(m)); |
+ /* Skip shortnames */ |
+ if (strcmp(from, mname)) |
+ return; |
+ /* Skip clones */ |
+ if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) |
+ return; |
+ if (strchr(mname, ' ')) |
+ mname= EVP_MD_name(m); |
+ BIO_printf(arg, "-%-14s to use the %s message digest algorithm\n", |
+ mname, mname); |
+ } |
+ |
int MAIN(int, char **); |
int MAIN(int argc, char **argv) |
@@ -89,7 +110,6 @@ |
BIO *in=NULL,*inp; |
BIO *bmd=NULL; |
BIO *out = NULL; |
- const char *name; |
#define PROG_NAME_SIZE 39 |
char pname[PROG_NAME_SIZE+1]; |
int separator=0; |
@@ -101,16 +121,16 @@ |
EVP_PKEY *sigkey = NULL; |
unsigned char *sigbuf = NULL; |
int siglen = 0; |
- unsigned int sig_flags = 0; |
char *passargin = NULL, *passin = NULL; |
#ifndef OPENSSL_NO_ENGINE |
char *engine=NULL; |
#endif |
char *hmac_key=NULL; |
- int non_fips_allow = 0; |
+ char *mac_name=NULL; |
+ STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; |
apps_startup(); |
-ERR_load_crypto_strings(); |
+ |
if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) |
{ |
BIO_printf(bio_err,"out of memory\n"); |
@@ -135,6 +155,8 @@ |
if ((*argv)[0] != '-') break; |
if (strcmp(*argv,"-c") == 0) |
separator=1; |
+ else if (strcmp(*argv,"-r") == 0) |
+ separator=2; |
else if (strcmp(*argv,"-rand") == 0) |
{ |
if (--argc < 1) break; |
@@ -169,27 +191,6 @@ |
keyfile=*(++argv); |
do_verify = 1; |
} |
- else if (strcmp(*argv,"-x931") == 0) |
- sig_flags = EVP_MD_CTX_FLAG_PAD_X931; |
- else if (strcmp(*argv,"-pss_saltlen") == 0) |
- { |
- int saltlen; |
- if (--argc < 1) break; |
- saltlen=atoi(*(++argv)); |
- if (saltlen == -1) |
- sig_flags = EVP_MD_CTX_FLAG_PSS_MREC; |
- else if (saltlen == -2) |
- sig_flags = EVP_MD_CTX_FLAG_PSS_MDLEN; |
- else if (saltlen < -2 || saltlen >= 0xFFFE) |
- { |
- BIO_printf(bio_err, "Invalid PSS salt length %d\n", saltlen); |
- goto end; |
- } |
- else |
- sig_flags = saltlen; |
- sig_flags <<= 16; |
- sig_flags |= EVP_MD_CTX_FLAG_PAD_PSS; |
- } |
else if (strcmp(*argv,"-signature") == 0) |
{ |
if (--argc < 1) break; |
@@ -205,6 +206,7 @@ |
{ |
if (--argc < 1) break; |
engine= *(++argv); |
+ e = setup_engine(bio_err, engine, 0); |
} |
#endif |
else if (strcmp(*argv,"-hex") == 0) |
@@ -213,16 +215,36 @@ |
out_bin = 1; |
else if (strcmp(*argv,"-d") == 0) |
debug=1; |
- else if (strcmp(*argv,"-non-fips-allow") == 0) |
- non_fips_allow=1; |
- else if (!strcmp(*argv,"-fips-fingerprint")) |
- hmac_key = "etaonrishdlcupfm"; |
else if (!strcmp(*argv,"-hmac")) |
{ |
if (--argc < 1) |
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) |
+ break; |
+ if (!sigopts) |
+ sigopts = sk_OPENSSL_STRING_new_null(); |
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) |
+ break; |
+ } |
+ else if (strcmp(*argv,"-macopt") == 0) |
+ { |
+ if (--argc < 1) |
+ break; |
+ if (!macopts) |
+ macopts = sk_OPENSSL_STRING_new_null(); |
+ if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) |
+ break; |
+ } |
else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) |
md=m; |
else |
@@ -231,12 +253,9 @@ |
argv++; |
} |
- if (md == NULL) |
- md=EVP_md5(); |
if(do_verify && !sigfile) { |
BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); |
- err = 1; |
goto end; |
} |
@@ -245,6 +264,7 @@ |
BIO_printf(bio_err,"unknown option '%s'\n",*argv); |
BIO_printf(bio_err,"options are\n"); |
BIO_printf(bio_err,"-c to output the digest with separating colons\n"); |
+ BIO_printf(bio_err,"-r to output the digest in coreutils format\n"); |
BIO_printf(bio_err,"-d to output debug info\n"); |
BIO_printf(bio_err,"-hex output as hex dump\n"); |
BIO_printf(bio_err,"-binary output in binary form\n"); |
@@ -252,49 +272,20 @@ |
BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); |
BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); |
BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n"); |
+ BIO_printf(bio_err,"-out filename output to filename rather than stdout\n"); |
BIO_printf(bio_err,"-signature file signature to verify\n"); |
- BIO_printf(bio_err,"-binary output in binary form\n"); |
+ BIO_printf(bio_err,"-sigopt nm:v signature parameter\n"); |
BIO_printf(bio_err,"-hmac key create hashed MAC with key\n"); |
+ BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n"); |
+ BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n"); |
#ifndef OPENSSL_NO_ENGINE |
BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n"); |
#endif |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm (default)\n", |
- LN_md5,LN_md5); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_md4,LN_md4); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_md2,LN_md2); |
-#ifndef OPENSSL_NO_SHA |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha1,LN_sha1); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha,LN_sha); |
-#ifndef OPENSSL_NO_SHA256 |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha224,LN_sha224); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha256,LN_sha256); |
-#endif |
-#ifndef OPENSSL_NO_SHA512 |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha384,LN_sha384); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_sha512,LN_sha512); |
-#endif |
-#endif |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_mdc2,LN_mdc2); |
- BIO_printf(bio_err,"-%-14s to use the %s message digest algorithm\n", |
- LN_ripemd160,LN_ripemd160); |
- err=1; |
+ EVP_MD_do_all_sorted(list_md_fn, bio_err); |
goto end; |
} |
-#ifndef OPENSSL_NO_ENGINE |
- e = setup_engine(bio_err, engine, 0); |
-#endif |
- |
in=BIO_new(BIO_s_file()); |
bmd=BIO_new(BIO_f_md()); |
if (debug) |
@@ -317,8 +308,10 @@ |
} |
if(out_bin == -1) { |
- if(keyfile) out_bin = 1; |
- else out_bin = 0; |
+ if(keyfile) |
+ out_bin = 1; |
+ else |
+ out_bin = 0; |
} |
if(randfile) |
@@ -344,6 +337,11 @@ |
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) |
{ |
@@ -361,6 +359,101 @@ |
} |
} |
+ 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_OPENSSL_STRING_num(macopts); i++) |
+ { |
+ macopt = sk_OPENSSL_STRING_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; |
+ EVP_PKEY_CTX *pctx = NULL; |
+ int r; |
+ if (!BIO_get_md_ctx(bmd, &mctx)) |
+ { |
+ BIO_printf(bio_err, "Error getting context\n"); |
+ ERR_print_errors(bio_err); |
+ goto end; |
+ } |
+ if (do_verify) |
+ r = EVP_DigestVerifyInit(mctx, &pctx, md, e, sigkey); |
+ else |
+ r = EVP_DigestSignInit(mctx, &pctx, md, e, sigkey); |
+ if (!r) |
+ { |
+ BIO_printf(bio_err, "Error setting context\n"); |
+ ERR_print_errors(bio_err); |
+ goto end; |
+ } |
+ if (sigopts) |
+ { |
+ char *sigopt; |
+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) |
+ { |
+ sigopt = sk_OPENSSL_STRING_value(sigopts, i); |
+ if (pkey_ctrl_string(pctx, sigopt) <= 0) |
+ { |
+ BIO_printf(bio_err, |
+ "parameter error \"%s\"\n", |
+ sigopt); |
+ ERR_print_errors(bio_err); |
+ goto end; |
+ } |
+ } |
+ } |
+ } |
+ /* we use md as a filter, reading from 'in' */ |
+ else |
+ { |
+ if (md == NULL) |
+ md = EVP_md5(); |
+ if (!BIO_set_md(bmd,md)) |
+ { |
+ BIO_printf(bio_err, "Error setting digest %s\n", pname); |
+ ERR_print_errors(bio_err); |
+ goto end; |
+ } |
+ } |
+ |
if(sigfile && sigkey) { |
BIO *sigbio; |
sigbio = BIO_new_file(sigfile, "rb"); |
@@ -381,67 +474,51 @@ |
goto end; |
} |
} |
+ inp=BIO_push(bmd,in); |
- if (non_fips_allow) |
+ if (md == NULL) |
{ |
- EVP_MD_CTX *md_ctx; |
- BIO_get_md_ctx(bmd,&md_ctx); |
- EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); |
+ EVP_MD_CTX *tctx; |
+ BIO_get_md_ctx(bmd, &tctx); |
+ md = EVP_MD_CTX_md(tctx); |
} |
- if (sig_flags) |
- { |
- EVP_MD_CTX *md_ctx; |
- BIO_get_md_ctx(bmd,&md_ctx); |
- EVP_MD_CTX_set_flags(md_ctx, sig_flags); |
- } |
- |
- /* we use md as a filter, reading from 'in' */ |
- if (!BIO_set_md(bmd,md)) |
- { |
- BIO_printf(bio_err, "Error setting digest %s\n", pname); |
- ERR_print_errors(bio_err); |
- goto end; |
- } |
- |
- inp=BIO_push(bmd,in); |
- |
if (argc == 0) |
{ |
BIO_set_fp(in,stdin,BIO_NOCLOSE); |
err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf, |
- siglen,"","(stdin)",bmd,hmac_key,non_fips_allow); |
+ siglen,NULL,NULL,"stdin",bmd); |
} |
else |
{ |
- name=OBJ_nid2sn(md->type); |
+ const char *md_name = NULL, *sig_name = NULL; |
+ if(!out_bin) |
+ { |
+ if (sigkey) |
+ { |
+ const EVP_PKEY_ASN1_METHOD *ameth; |
+ ameth = EVP_PKEY_get0_asn1(sigkey); |
+ if (ameth) |
+ EVP_PKEY_asn1_get0_info(NULL, NULL, |
+ NULL, NULL, &sig_name, ameth); |
+ } |
+ md_name = EVP_MD_name(md); |
+ } |
err = 0; |
for (i=0; i<argc; i++) |
{ |
- char *tmp,*tofree=NULL; |
int r; |
- |
if (BIO_read_filename(in,argv[i]) <= 0) |
{ |
perror(argv[i]); |
err++; |
continue; |
} |
- if(!out_bin) |
- { |
- size_t len = strlen(name)+strlen(argv[i])+(hmac_key ? 5 : 0)+5; |
- tmp=tofree=OPENSSL_malloc(len); |
- BIO_snprintf(tmp,len,"%s%s(%s)= ", |
- hmac_key ? "HMAC-" : "",name,argv[i]); |
- } |
else |
- tmp=""; |
r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, |
- siglen,tmp,argv[i],bmd,hmac_key,non_fips_allow); |
+ siglen,sig_name,md_name, argv[i],bmd); |
if(r) |
err=r; |
- if(tofree) |
- OPENSSL_free(tofree); |
(void)BIO_reset(bmd); |
} |
} |
@@ -456,6 +533,10 @@ |
OPENSSL_free(passin); |
BIO_free_all(out); |
EVP_PKEY_free(sigkey); |
+ if (sigopts) |
+ sk_OPENSSL_STRING_free(sigopts); |
+ if (macopts) |
+ sk_OPENSSL_STRING_free(macopts); |
if(sigbuf) OPENSSL_free(sigbuf); |
if (bmd != NULL) BIO_free(bmd); |
apps_shutdown(); |
@@ -463,24 +544,13 @@ |
} |
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,int non_fips_allow) |
+ EVP_PKEY *key, unsigned char *sigin, int siglen, |
+ const char *sig_name, const char *md_name, |
+ const char *file,BIO *bmd) |
{ |
- unsigned int len; |
+ size_t 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); |
@@ -496,7 +566,7 @@ |
{ |
EVP_MD_CTX *ctx; |
BIO_get_md_ctx(bp, &ctx); |
- i = EVP_VerifyFinal(ctx, sigin, (unsigned int)siglen, key); |
+ i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen); |
if(i > 0) |
BIO_printf(out, "Verified OK\n"); |
else if(i == 0) |
@@ -516,25 +586,39 @@ |
{ |
EVP_MD_CTX *ctx; |
BIO_get_md_ctx(bp, &ctx); |
- if(!EVP_SignFinal(ctx, buf, (unsigned int *)&len, key)) |
+ len = BUFSIZE; |
+ if(!EVP_DigestSignFinal(ctx, buf, &len)) |
{ |
BIO_printf(bio_err, "Error Signing Data\n"); |
ERR_print_errors(bio_err); |
return 1; |
} |
} |
- else if(hmac_key) |
+ else |
{ |
- HMAC_Final(&hmac_ctx,buf,&len); |
- HMAC_CTX_cleanup(&hmac_ctx); |
+ len=BIO_gets(bp,(char *)buf,BUFSIZE); |
+ if ((int)len <0) |
+ { |
+ ERR_print_errors(bio_err); |
+ return 1; |
+ } |
} |
- else |
- len=BIO_gets(bp,(char *)buf,BUFSIZE); |
if(binout) BIO_write(out, buf, len); |
+ else if (sep == 2) |
+ { |
+ for (i=0; i<(int)len; i++) |
+ BIO_printf(out, "%02x",buf[i]); |
+ BIO_printf(out, " *%s\n", file); |
+ } |
else |
{ |
- BIO_write(out,title,strlen(title)); |
+ if (sig_name) |
+ BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file); |
+ else if (md_name) |
+ BIO_printf(out, "%s(%s)= ", md_name, file); |
+ else |
+ BIO_printf(out, "(%s)= ", file); |
for (i=0; i<(int)len; i++) |
{ |
if (sep && (i != 0)) |
@@ -543,10 +627,6 @@ |
} |
BIO_printf(out, "\n"); |
} |
- if (hmac_key) |
- { |
- BIO_set_md_ctx(bmd,md_ctx); |
- } |
return 0; |
} |