Remove hacks which are not anymore needed since we now require Libgcrypt 1.4
[gnupg.git] / g10 / gpg.c
index 599b7df..9dd1790 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,6 +1,6 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2007, 2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -26,9 +26,6 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <assert.h>
-#ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
-#endif
 #ifdef HAVE_STAT
 #include <sys/stat.h> /* for stat() */
 #endif
@@ -122,6 +119,7 @@ enum cmd_and_opt_values
     aListSigs,
     aSendKeys,
     aRecvKeys,
+    aLocateKeys,
     aSearchKeys,
     aRefreshKeys,
     aFetchKeys,
@@ -194,6 +192,7 @@ enum cmd_and_opt_values
     oGnuPG,
     oRFC1991,
     oRFC2440,
+    oRFC4880,
     oOpenPGP,
     oPGP2,
     oPGP6,
@@ -231,6 +230,8 @@ enum cmd_and_opt_values
     oHomedir,
     oWithColons,
     oWithKeyData,
+    oWithSigList,
+    oWithSigCheck,
     oSkipVerify,
     oCompressKeys,
     oCompressSigs,
@@ -337,6 +338,7 @@ enum cmd_and_opt_values
     oTTYtype,
     oLCctype,
     oLCmessages,
+    oXauthority,
     oGroup,
     oUnGroup,
     oNoGroups,
@@ -400,6 +402,7 @@ static ARGPARSE_OPTS opts[] = {
                                     N_("search for keys on a key server") },
     { aRefreshKeys, "refresh-keys", 256,
                                     N_("update all keys from a keyserver")},
+    { aLocateKeys, "locate-keys", 256, "@"},
     { aFetchKeys, "fetch-keys" , 256, "@" },
     { aExportSecret, "export-secret-keys" , 256, "@" },
     { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
@@ -464,7 +467,7 @@ static ARGPARSE_OPTS opts[] = {
     { oMinCertLevel, "min-cert-level", 1, "@"},
     { oAskCertLevel, "ask-cert-level",   0, "@"},
     { oNoAskCertLevel, "no-ask-cert-level",   0, "@"},
-    { oOutput, "output",    2, N_("use as output file")},
+    { oOutput, "output",    2, N_("|FILE|write output to FILE")},
     { oMaxOutput, "max-output", 16|4, "@" },
     { oVerbose, "verbose",   0, N_("verbose") },
     { oQuiet,  "quiet",   0, "@"},
@@ -520,6 +523,7 @@ static ARGPARSE_OPTS opts[] = {
     { oGnuPG, "no-pgp8", 0, "@"},
     { oRFC1991, "rfc1991",   0, "@"},
     { oRFC2440, "rfc2440", 0, "@" },
+    { oRFC4880, "rfc4880", 0, "@" },
     { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
     { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
     { oPGP6, "pgp6", 0, "@"},
@@ -588,6 +592,8 @@ static ARGPARSE_OPTS opts[] = {
     { oNoBatch, "no-batch", 0, "@" },
     { oWithColons, "with-colons", 0, "@"},
     { oWithKeyData,"with-key-data", 0, "@"},
+    { oWithSigList,"with-sig-list", 0, "@"},
+    { oWithSigCheck,"with-sig-check", 0, "@"},
     { aListKeys, "list-key", 0, "@" }, /* alias */
     { aListSigs, "list-sig", 0, "@" }, /* alias */
     { aCheckKeys, "check-sig",0, "@" }, /* alias */
@@ -623,6 +629,7 @@ static ARGPARSE_OPTS opts[] = {
     { oLockNever, "lock-never", 0, "@" },
     { oLoggerFD, "logger-fd",1, "@" },
     { oLoggerFile, "log-file",2, "@" },
+    { oLoggerFile, "logger-file",2, "@" },  /* For 1.4 compatibility.  */
     { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
     { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" },
     { oUtf8Strings, "utf8-strings", 0, "@" },
@@ -677,6 +684,7 @@ static ARGPARSE_OPTS opts[] = {
     { oTTYtype,    "ttytype",     2, "@" },
     { oLCctype,    "lc-ctype",    2, "@" },
     { oLCmessages, "lc-messages", 2, "@" },
+    { oXauthority, "xauthority",  2, "@" },
     { oGroup,      "group",       2, "@" },
     { oUnGroup,    "ungroup",     2, "@" },
     { oNoGroups,   "no-groups",    0, "@" },
@@ -702,6 +710,7 @@ static ARGPARSE_OPTS opts[] = {
        I'm returning the favor. */
     { oLocalUser, "sign-with", 2, "@" },
     { oRecipient, "user", 2, "@" },
+
     { oRequireCrossCert, "require-backsigs", 0, "@"},
     { oRequireCrossCert, "require-cross-certification", 0, "@"},
     { oNoRequireCrossCert, "no-require-backsigs", 0, "@"},
@@ -790,7 +799,7 @@ my_strusage( int level )
       case 35:
        if( !ciphers )
            ciphers = build_list(_("Cipher: "), 'S', 
-                                 gcry_cipher_algo_name,
+                                 openpgp_cipher_algo_name,
                                  openpgp_cipher_test_algo );
        p = ciphers;
        break;
@@ -1383,6 +1392,24 @@ print_algo_numbers(int (*checker)(int))
 }
 
 
+static void
+print_algo_names(int (*checker)(int),const char *(*mapper)(int))
+{
+  int i,first=1;
+
+  for(i=0;i<=110;i++)
+    {
+      if(!checker(i))
+       {
+         if(first)
+           first=0;
+         else
+           printf(";");
+         printf("%s",mapper(i));
+       }
+    }
+}
+
 /* In the future, we can do all sorts of interesting configuration
    output here.  For now, just give "group" as the Enigmail folks need
    it, and pubkey, cipher, hash, and compress as they may be useful
@@ -1449,6 +1476,14 @@ list_config(char *items)
          any=1;
        }
 
+      if (show_all || !ascii_strcasecmp (name,"ciphername"))
+       {
+         printf ("cfg:ciphername:");
+         print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
+         printf ("\n");
+         any = 1;
+       }
+
       if(show_all
         || ascii_strcasecmp(name,"digest")==0
         || ascii_strcasecmp(name,"hash")==0)
@@ -1459,6 +1494,16 @@ list_config(char *items)
          any=1;
        }
 
+      if (show_all
+          || !ascii_strcasecmp(name,"digestname")
+          || !ascii_strcasecmp(name,"hashname"))
+       {
+         printf ("cfg:digestname:");
+         print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
+         printf("\n");
+         any=1;
+       }
+      
       if(show_all || ascii_strcasecmp(name,"compress")==0)
        {
          printf("cfg:compress:");
@@ -1511,6 +1556,11 @@ gpgconf_list (const char *configfile)
   printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("allow-pka-lookup:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+  printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
 
   xfree (configfile_esc);
 }
@@ -1683,76 +1733,6 @@ parse_trust_model(const char *model)
 }
 
 
-
-/* Make sure that the standard file descriptors are opened. Obviously
-   some folks close them before an exec and the next file we open will
-   get one of them assigned and thus any output (i.e. diagnostics) end
-   up in that file (e.g. the trustdb).  Not actually a gpg problem as
-   this will hapenn with almost all utilities when called in a wrong
-   way.  However we try to minimize the damage here and raise
-   awareness of the problem.
-
-   Must be called before we open any files! */
-static void
-reopen_std(void)
-{  
-#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
-  struct stat statbuf;
-  int did_stdin=0,did_stdout=0,did_stderr=0;
-  FILE *complain;
-
-  if(fstat(STDIN_FILENO,&statbuf)==-1 && errno==EBADF)
-    {
-      if(open("/dev/null",O_RDONLY)==STDIN_FILENO)
-       did_stdin=1;
-      else
-       did_stdin=2;
-    }
-
-  if(fstat(STDOUT_FILENO,&statbuf)==-1 && errno==EBADF)
-    {
-      if(open("/dev/null",O_WRONLY)==STDOUT_FILENO)
-       did_stdout=1;
-      else
-       did_stdout=2;
-    }
-
-  if(fstat(STDERR_FILENO,&statbuf)==-1 && errno==EBADF)
-    {
-      if(open("/dev/null",O_WRONLY)==STDERR_FILENO)
-       did_stderr=1;
-      else
-       did_stderr=2;
-    }
-
-  /* It's hard to log this sort of thing since the filehandle we would
-     complain to may be closed... */
-  if(did_stderr==0)
-    complain=stderr;
-  else if(did_stdout==0)
-    complain=stdout;
-  else
-    complain=NULL;
-
-  if(complain)
-    {
-      if(did_stdin==1)
-       fprintf(complain,"gpg: WARNING: standard input reopened\n");
-      if(did_stdout==1)
-       fprintf(complain,"gpg: WARNING: standard output reopened\n");
-      if(did_stderr==1)
-       fprintf(complain,"gpg: WARNING: standard error reopened\n");
-
-      if(did_stdin==2 || did_stdout==2 || did_stderr==2)
-       fprintf(complain,"gpg: fatal: unable to reopen standard input,"
-               " output, or error\n");
-    }
-
-  if(did_stdin==2 || did_stdout==2 || did_stderr==2)
-    exit(3);
-#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
-}
-
 /* Pack an s2k iteration count into the form specified in 2440.  If
    we're in between valid values, round up. */
 static unsigned char
@@ -1797,9 +1777,65 @@ gpg_deinit_default_ctrl (ctrl_t ctrl)
 }
 
 
+char *
+get_default_configname (void)
+{
+  char *configname = NULL;
+  char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
+  char *ver = &name[strlen ("gpg" EXTSEP_S "conf-")];
+
+  do
+    {
+      if (configname)
+       {
+         char *tok;
+         
+         xfree (configname);
+         configname = NULL;
+
+         if ((tok = strrchr (ver, SAFE_VERSION_DASH)))
+           *tok='\0';
+         else if ((tok = strrchr (ver, SAFE_VERSION_DOT)))
+           *tok='\0';
+         else
+           break;
+       }
+      
+      configname = make_filename (opt.homedir, name, NULL);
+    }
+  while (access (configname, R_OK));
+
+  xfree(name);
+  
+  if (! configname)
+    configname = make_filename (opt.homedir, "gpg" EXTSEP_S "conf", NULL);
+  if (! access (configname, R_OK))
+    {
+      /* Print a warning when both config files are present.  */
+      char *p = make_filename (opt.homedir, "options", NULL);
+      if (! access (p, R_OK))
+       log_info (_("NOTE: old default options file `%s' ignored\n"), p);
+      xfree (p);
+    }
+  else
+    {
+      /* Use the old default only if it exists.  */
+      char *p = make_filename (opt.homedir, "options", NULL);
+      if (!access (p, R_OK))
+       {
+         xfree (configname);
+         configname = p;
+       }
+      else
+       xfree (p);
+    }
+
+  return configname;
+}
+
 
 int
-main (int argc, char **argv )
+main (int argc, char **argv)
 {
     ARGPARSE_ARGS pargs;
     IOBUF a;
@@ -1816,6 +1852,7 @@ main (int argc, char **argv )
     FILE *configfp = NULL;
     char *configname = NULL;
     char *save_configname = NULL;
+    char *default_configname = NULL;
     unsigned configlineno;
     int parse_debug = 0;
     int default_config = 1;
@@ -1851,7 +1888,7 @@ main (int argc, char **argv )
     /* Please note that we may running SUID(ROOT), so be very CAREFUL
        when adding any stuff between here and the call to
        secmem_init() somewhere after the option parsing. */
-    reopen_std ();
+    gnupg_reopen_std ("gpg");
     trap_unaligned ();
     gnupg_rl_initialize ();
     set_strusage (my_strusage);
@@ -1902,8 +1939,8 @@ main (int argc, char **argv )
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
     opt.pgp2_workarounds = 1;
-    opt.force_v3_sigs = 1;
     opt.escape_from = 1;
+    opt.flags.require_cross_cert = 1;
     opt.import_options=IMPORT_SK2PK;
     opt.export_options=EXPORT_ATTRIBUTES;
     opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
@@ -1917,7 +1954,6 @@ main (int argc, char **argv )
     opt.min_cert_level=2;
     set_screen_dimensions();
     opt.keyid_format=KF_SHORT;
-    opt.rfc2440_text=1;
     opt.def_sig_expire="0";
     opt.def_cert_expire="0";
     set_homedir ( default_homedir () );
@@ -1939,8 +1975,11 @@ main (int argc, char **argv )
            default_config = 0;
        }
        else if( pargs.r_opt == oNoOptions )
+          {
            default_config = 0; /* --no-options */
-       else if( pargs.r_opt == oHomedir )
+            opt.no_homedir_creation = 1;
+          }
+        else if( pargs.r_opt == oHomedir )
            set_homedir ( pargs.r.ret_str );
        else if( pargs.r_opt == oNoPermissionWarn )
            opt.no_perm_warn=1;
@@ -1977,8 +2016,8 @@ main (int argc, char **argv )
 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
     /* There should be no way to get to this spot while still carrying
        setuid privs.  Just in case, bomb out if we are. */
-    if(getuid()!=geteuid())
-      BUG();
+    if ( getuid () != geteuid () )
+      BUG ();
 #endif
     maybe_setuid = 0;
 
@@ -1990,49 +2029,10 @@ main (int argc, char **argv )
  
 
     /* Try for a version specific config file first */
-    if( default_config )
-      {
-       char *name=xstrdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
-       char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
-
-       do
-         {
-           if(configname)
-             {
-               char *tok;
-
-               xfree(configname);
-               configname=NULL;
-
-               if((tok=strrchr(ver,SAFE_VERSION_DASH)))
-                 *tok='\0';
-               else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
-                 *tok='\0';
-               else
-                 break;
-             }
+    default_configname = get_default_configname ();
+    if (default_config)
+      configname = xstrdup (default_configname);
 
-           configname = make_filename(opt.homedir,name,NULL);
-         }
-       while(access(configname,R_OK));
-
-       xfree(name);
-
-       if(!configname)
-         configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
-        if (!access (configname, R_OK))
-          { /* Print a warning when both config files are present. */
-            char *p = make_filename(opt.homedir, "options", NULL );
-            if (!access (p, R_OK))
-              log_info (_("NOTE: old default options file `%s' ignored\n"), p);
-            xfree (p);
-          }
-        else
-          { /* Keep on using the old default one. */
-            xfree (configname);
-            configname = make_filename(opt.homedir, "options", NULL );
-          }
-      }
     argc = orig_argc;
     argv = orig_argv;
     pargs.argc = &argc;
@@ -2105,6 +2105,7 @@ main (int argc, char **argv )
           case aChangePIN:
 #endif /* ENABLE_CARD_SUPPORT*/
          case aListKeys: 
+         case aLocateKeys:
          case aListSigs: 
          case aExportSecret: 
          case aExportSecretSub: 
@@ -2270,9 +2271,13 @@ main (int argc, char **argv )
          case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
          case oHomedir: break;
          case oNoBatch: opt.batch = 0; break;
-         case oWithKeyData: opt.with_key_data=1; /* fall thru */
+
+         case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
          case oWithColons: opt.with_colons=':'; break;
 
+          case oWithSigCheck: opt.check_sigs = 1; /*FALLTHRU*/
+          case oWithSigList: opt.list_sigs = 1; break;  
+
          case oSkipVerify: opt.skip_verify=1; break;
          case oCompressKeys: opt.compress_keys = 1; break;
          case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
@@ -2303,11 +2308,34 @@ main (int argc, char **argv )
            opt.escape_from = 1;
            break;
          case oOpenPGP:
+         case oRFC4880:
+           /* This is effectively the same as RFC2440, but with
+              "--enable-dsa2 --no-rfc2440-text --escape-from-lines
+              --require-cross-certification". */
+           opt.compliance = CO_RFC4880;
+           opt.flags.dsa2 = 1;
+           opt.flags.require_cross_cert = 1;
+           opt.rfc2440_text = 0;
+           opt.allow_non_selfsigned_uid = 1;
+           opt.allow_freeform_uid = 1;
+           opt.pgp2_workarounds = 0;
+           opt.escape_from = 1;
+           opt.force_v3_sigs = 0;
+           opt.compress_keys = 0;          /* not mandated, but we do it */
+           opt.compress_sigs = 0;          /* ditto. */
+           opt.not_dash_escaped = 0;
+           opt.def_cipher_algo = 0;
+           opt.def_digest_algo = 0;
+           opt.cert_digest_algo = 0;
+           opt.compress_algo = -1;
+            opt.s2k_mode = 3; /* iterated+salted */
+           opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+           break;
          case oRFC2440:
-           /* TODO: When 2440bis becomes a RFC, set new values for
-              oOpenPGP. */
-           opt.rfc2440_text=1;
            opt.compliance = CO_RFC2440;
+           opt.flags.dsa2 = 0;
+           opt.rfc2440_text = 1;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
@@ -2706,7 +2734,7 @@ main (int argc, char **argv )
                                   "--keyserver-options ","http-proxy");
                break;
          case oFastListMode: opt.fast_list_mode = 1; break;
-         case oFixedListMode: opt.fixed_list_mode = 1; break;
+         case oFixedListMode: /* Dummy */ break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -2776,6 +2804,7 @@ main (int argc, char **argv )
           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
+          case oXauthority: opt.xauthority = pargs.r.ret_str; break;
          case oGroup: add_group(pargs.r.ret_str); break;
          case oUnGroup: rm_group(pargs.r.ret_str); break;
          case oNoGroups:
@@ -2873,10 +2902,11 @@ main (int argc, char **argv )
        directly after the option parsing. */
     if (cmd == aGPGConfList)
       {
-        gpgconf_list (save_configname);
+        gpgconf_list (save_configname ? save_configname : default_configname);
         g10_exit (0);
       }
     xfree (save_configname);
+    xfree (default_configname);
 
     if( nogreeting )
        greeting = 0;
@@ -2910,6 +2940,24 @@ main (int argc, char **argv )
         log_set_prefix (NULL, 1|2|4);
       }
 
+#ifdef USE_CAMELLIA    
+    /* We better also print a runtime warning if people build it with
+       support for Camellia (which is not yet defined by OpenPGP). */
+    log_info ("WARNING: This version has been built with support for the "
+              "Camellia cipher.\n");
+    log_info ("         It is for testing only and is NOT for production "
+              "use!\n");
+#endif
+
+    /* Older Libgcrypts fail with an assertion during DSA key
+       generation.  Better disable DSA2 entirely. */
+    if (opt.flags.dsa2 && !gcry_check_version ("1.4.0") )
+      {
+        log_info ("WARNING: "
+                  "DSA2 is only available with Libgcrypt 1.4 and later\n");
+        opt.flags.dsa2 = 0;
+      }
+
     if (opt.verbose > 2)
         log_info ("using character set `%s'\n", get_native_charset ());
 
@@ -3175,7 +3223,7 @@ main (int argc, char **argv )
        if(opt.def_cipher_algo
           && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
          {
-           badalg = gcry_cipher_algo_name (opt.def_cipher_algo);
+           badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
            badtype = PREFTYPE_SYM;
          }
        else if(opt.def_digest_algo
@@ -3237,15 +3285,6 @@ main (int argc, char **argv )
        set_cmd( &cmd, aListKeys);
     }
 
-    /* kludge to let -sat generate a clear text signature */
-    if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
-      {
-        log_info ("compatibility note:\n");
-        log_info ("\"-sat\" won't generate clear signed messages in "
-                  "future versions\n");
-        log_info ("Use \"--clearsign\" instead of \"-sat\"\n");
-       cmd = aClearsign;
-      }
 
     if( opt.verbose > 1 )
        set_packet_list_mode(1);
@@ -3263,7 +3302,7 @@ main (int argc, char **argv )
       {
         if (ALWAYS_ADD_KEYRINGS
             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
-                && cmd != aVerify && cmd != aSym))
+                && cmd != aVerify && cmd != aSym && cmd != aLocateKeys))
           {
             if (!sec_nrings || default_keyring) /* add default secret rings */
               keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
@@ -3546,7 +3585,7 @@ main (int argc, char **argv )
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       public_key_list( sl );
+       public_key_list( sl, 0 );
        free_strlist(sl);
        break;
       case aListSecretKeys:
@@ -3556,6 +3595,13 @@ main (int argc, char **argv )
        secret_key_list( sl );
        free_strlist(sl);
        break;
+      case aLocateKeys:
+       sl = NULL;
+       for (; argc; argc--, argv++)
+          add_to_strlist2( &sl, *argv, utf8_strings );
+       public_key_list (sl, 1);
+       free_strlist (sl);
+       break;
 
       case aKeygen: /* generate a key */
        if( opt.batch ) {
@@ -4100,8 +4146,8 @@ print_mds( const char *fname, int algo )
        gcry_md_enable (md, GCRY_MD_MD5);
        gcry_md_enable (md, GCRY_MD_SHA1);
        gcry_md_enable (md, GCRY_MD_RMD160);
-        if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224))
-          gcry_md_enable (md, DIGEST_ALGO_SHA224);
+        if (!openpgp_md_test_algo (GCRY_MD_SHA224))
+          gcry_md_enable (md, GCRY_MD_SHA224);
         if (!openpgp_md_test_algo (GCRY_MD_SHA256))
           gcry_md_enable (md, GCRY_MD_SHA256);
         if (!openpgp_md_test_algo (GCRY_MD_SHA384))
@@ -4123,8 +4169,8 @@ print_mds( const char *fname, int algo )
                 print_hashline( md, GCRY_MD_MD5, fname );
                 print_hashline( md, GCRY_MD_SHA1, fname );
                 print_hashline( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (DIGEST_ALGO_SHA224))
-                    print_hashline (md, DIGEST_ALGO_SHA224, fname);
+                if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                    print_hashline (md, GCRY_MD_SHA224, fname);
                 if (!gcry_md_test_algo (GCRY_MD_SHA256))
                     print_hashline( md, GCRY_MD_SHA256, fname );
                 if (!gcry_md_test_algo (GCRY_MD_SHA384))
@@ -4140,8 +4186,8 @@ print_mds( const char *fname, int algo )
                 print_hex( md, GCRY_MD_MD5, fname );
                 print_hex( md, GCRY_MD_SHA1, fname );
                 print_hex( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (DIGEST_ALGO_SHA224))
-                    print_hex (md, DIGEST_ALGO_SHA224, fname);
+                if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                    print_hex (md, GCRY_MD_SHA224, fname);
                 if (!gcry_md_test_algo (GCRY_MD_SHA256))
                     print_hex( md, GCRY_MD_SHA256, fname );
                 if (!gcry_md_test_algo (GCRY_MD_SHA384))