Doc fixes
authorRich Salz <rsalz@openssl.org>
Mon, 14 Aug 2017 13:32:07 +0000 (09:32 -0400)
committerRich Salz <rsalz@openssl.org>
Mon, 14 Aug 2017 13:32:07 +0000 (09:32 -0400)
Write missing prime.pod and srp.pod
Implement -c in find-doc-nits (for command options)
Other fixes to some manpages
Use B<-I<digest|cipher>> notation
Split up multiple flags into a single entry in the synopsis.
Add -1 and missing-help to list command.

Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4144)

17 files changed:
apps/openssl.c
doc/man1/cms.pod
doc/man1/dgst.pod
doc/man1/enc.pod
doc/man1/genpkey.pod
doc/man1/list.pod
doc/man1/ocsp.pod
doc/man1/pkey.pod
doc/man1/prime.pod [new file with mode: 0644]
doc/man1/req.pod
doc/man1/s_client.pod
doc/man1/s_time.pod
doc/man1/smime.pod
doc/man1/srp.pod [new file with mode: 0644]
doc/man1/ts.pod
doc/man1/x509.pod
util/find-doc-nits

index 0518ee67875e68b186016ab6ba38b864ea42283c..6f8179df4fdaa008da69e65dd3714d4a46f922a5 100644 (file)
@@ -52,7 +52,7 @@ static LHASH_OF(FUNCTION) *prog_init(void);
 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);
+static void list_type(FUNC_TYPE ft, int one);
 static void list_disabled(void);
 char *default_config_file = NULL;
 
@@ -292,28 +292,57 @@ static void list_missing_help(void)
     const OPTIONS *o;
 
     for (fp = functions; fp->name != NULL; fp++) {
-        if ((o = fp->help) == NULL) {
+        if ((o = fp->help) != NULL) {
+            /* If there is help, list what flags are not documented. */
+            for ( ; o->name != NULL; o++) {
+                if (o->helpstr == NULL)
+                    BIO_printf(bio_out, "%s %s\n", fp->name, o->name);
+            }
+        } else if (fp->func != dgst_main) {
+            /* If not aliased to the dgst command, */
             BIO_printf(bio_out, "%s *\n", fp->name);
-            continue;
-        }
-        for ( ; o->name != NULL; o++) {
-            if (o->helpstr == NULL)
-                BIO_printf(bio_out, "%s %s\n", fp->name, o->name);
         }
     }
 }
 
+static void list_options_for_command(const char *command)
+{
+    const FUNCTION *fp;
+    const OPTIONS *o;
+
+    for (fp = functions; fp->name != NULL; fp++)
+        if (strcmp(fp->name, command) == 0)
+            break;
+    if (fp->name == NULL) {
+        BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
+                command);
+        return;
+    }
+
+    if ((o = fp->help) == NULL)
+        return;
+
+    for ( ; o->name != NULL; o++) {
+        if (o->name == OPT_HELP_STR
+                || o->name == OPT_MORE_STR
+                || o->name[0] == '\0')
+            continue;
+        BIO_printf(bio_out, "%s %c\n", o->name, o->valtype);
+    }
+}
+
 
 /* Unified enum for help and list commands. */
 typedef enum HELPLIST_CHOICE {
-    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_COMMANDS, OPT_DIGEST_COMMANDS,
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE,
+    OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_OPTIONS,
     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, OPT_MISSING_HELP
 } HELPLIST_CHOICE;
 
 const OPTIONS list_options[] = {
     {"help", OPT_HELP, '-', "Display this summary"},
+    {"1", OPT_ONE, '-', "List in one column"},
     {"commands", OPT_COMMANDS, '-', "List of standard commands"},
     {"digest-commands", OPT_DIGEST_COMMANDS, '-',
      "List of message digest commands"},
@@ -330,6 +359,8 @@ const OPTIONS list_options[] = {
      "List of disabled features"},
     {"missing-help", OPT_MISSING_HELP, '-',
      "List missing detailed help strings"},
+    {"options", OPT_OPTIONS, 's',
+     "List options for specified command"},
     {NULL}
 };
 
@@ -337,7 +368,7 @@ int list_main(int argc, char **argv)
 {
     char *prog;
     HELPLIST_CHOICE o;
-    int done = 0;
+    int one = 0, done = 0;
 
     prog = opt_init(argc, argv, list_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -349,17 +380,20 @@ int list_main(int argc, char **argv)
         case OPT_HELP:
             opt_help(list_options);
             break;
+        case OPT_ONE:
+            one = 1;
+            break;
         case OPT_COMMANDS:
-            list_type(FT_general);
+            list_type(FT_general, one);
             break;
         case OPT_DIGEST_COMMANDS:
-            list_type(FT_md);
+            list_type(FT_md, one);
             break;
         case OPT_DIGEST_ALGORITHMS:
             EVP_MD_do_all_sorted(list_md_fn, bio_out);
             break;
         case OPT_CIPHER_COMMANDS:
-            list_type(FT_cipher);
+            list_type(FT_cipher, one);
             break;
         case OPT_CIPHER_ALGORITHMS:
             EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out);
@@ -376,6 +410,9 @@ int list_main(int argc, char **argv)
         case OPT_MISSING_HELP:
             list_missing_help();
             break;
+        case OPT_OPTIONS:
+            list_options_for_command(opt_arg());
+            break;
         }
         done = 1;
     }
@@ -458,18 +495,24 @@ int exit_main(int argc, char **argv)
     return EXIT_THE_PROGRAM;
 }
 
-static void list_type(FUNC_TYPE ft)
+static void list_type(FUNC_TYPE ft, int one)
 {
     FUNCTION *fp;
     int i = 0;
 
-    for (fp = functions; fp->name != NULL; fp++)
-        if (fp->type == ft) {
-            if ((i++ % COLUMNS) == 0)
+    for (fp = functions; fp->name != NULL; fp++) {
+        if (fp->type != ft)
+            continue;
+        if (one) {
+            BIO_printf(bio_out, "%s\n", fp->name);
+        } else {
+            if ((i++ % COLUMNS) == 0 && fp != functions)
                 BIO_printf(bio_out, "\n");
             BIO_printf(bio_out, FORMAT, fp->name);
         }
-    BIO_printf(bio_out, "\n");
+    }
+    if (!one)
+        BIO_printf(bio_out, "\n");
 }
 
 static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
index 33549d4859c52f6c851bdf574f13e7b0cf242cab..01e93acf1be44e8dff289958fa2fde4efb2edd2a 100644 (file)
@@ -67,9 +67,9 @@ B<openssl> B<cms>
 [B<-verify_name name>]
 [B<-x509_strict>]
 [B<-md digest>]
-[B<-[cipher]>]
+[B<-I<cipher>>]
 [B<-nointern>]
-[B<-no_signer_cert_verify>]
+[B<-noverify>]
 [B<-nocerts>]
 [B<-noattr>]
 [B<-nosmimecap>]
@@ -298,7 +298,7 @@ Do not load the trusted CA certificates from the default directory location
 Digest algorithm to use when signing or resigning. If not present then the
 default digest algorithm for the signing key will be used (usually SHA1).
 
-=item B<-[cipher]>
+=item B<-I<cipher>>
 
 The encryption algorithm to use. For example triple DES (168 bits) - B<-des3>
 or 256 bit AES - B<-aes256>. Any standard algorithm name (as used by the
@@ -316,7 +316,7 @@ the message are searched for the signing certificate. With this option
 only the certificates specified in the B<-certfile> option are used.
 The supplied certificates can still be used as untrusted CAs however.
 
-=item B<-no_signer_cert_verify>
+=item B<-noverify>
 
 Do not verify the signers certificate of a signed message.
 
index 0cbcf850f5d722b82255227279462f3bded90e0e..cde3bb17d37e345d6eb17092dc6c70949e90599e 100644 (file)
@@ -2,13 +2,14 @@
 
 =head1 NAME
 
-dgst, sha, sha1, mdc2, ripemd160, sha224, sha256, sha384, sha512, md4, md5, blake2b, blake2s - message digests
+dgst
+- perform digest operations
 
 =head1 SYNOPSIS
 
-B<openssl> B<dgst>
-[B<-help>]
+B<openssl dgst>
 [B<-I<digest>>]
+[B<-help>]
 [B<-c>]
 [B<-d>]
 [B<-hex>]
@@ -28,9 +29,7 @@ B<openssl> B<dgst>
 [B<-engine_impl>]
 [B<file...>]
 
-B<openssl>
-[I<digest>]
-[B<...>]
+B<openssl> I<digest> [B<...>]
 
 =head1 DESCRIPTION
 
index ad76be0cb76b95ef89cd43dd20aebbf730dcbdf2..f7d5e36fdb49401452e3122175eab7f9b56cbe87 100644 (file)
@@ -6,7 +6,7 @@ enc - symmetric cipher routines
 
 =head1 SYNOPSIS
 
-B<openssl enc -ciphername>
+B<openssl enc -I<cipher>>
 [B<-help>]
 [B<-ciphers>]
 [B<-in filename>]
@@ -14,7 +14,8 @@ B<openssl enc -ciphername>
 [B<-pass arg>]
 [B<-e>]
 [B<-d>]
-[B<-a/-base64>]
+[B<-a>]
+[B<-base64>]
 [B<-A>]
 [B<-k password>]
 [B<-kfile filename>]
@@ -35,6 +36,8 @@ B<openssl enc -ciphername>
 [B<-writerand file>]
 [B<-engine id>]
 
+B<openssl> I<[cipher]> [B<...>]
+
 =head1 DESCRIPTION
 
 The symmetric cipher commands allow data to be encrypted or decrypted
@@ -184,10 +187,11 @@ This can be used with a subsequent B<-rand> flag.
 
 =head1 NOTES
 
-The program can be called either as B<openssl ciphername> or
-B<openssl enc -ciphername>. The first form doesn't work with
+The program can be called either as B<openssl cipher> or
+B<openssl enc -cipher>. The first form doesn't work with
 engine-provided ciphers, because this form is processed before the
 configuration file is read and any ENGINEs loaded.
+Use the B<list> command to get a list of supported ciphers.
 
 Engines which provide entirely new encryption algorithms (such as the ccgost
 engine which provides gost89 algorithm) should be configured in the
index 8e22ab22eee17c69f97c38201bd0fe016616ef3a..66541d92b0abf4338e2a0ccd5b0680d33cc83183 100644 (file)
@@ -11,7 +11,7 @@ B<openssl> B<genpkey>
 [B<-out filename>]
 [B<-outform PEM|DER>]
 [B<-pass arg>]
-[B<-cipher>]
+[B<-I<cipher>>]
 [B<-engine id>]
 [B<-paramfile file>]
 [B<-algorithm alg>]
@@ -45,7 +45,7 @@ This specifies the output format DER or PEM. The default format is PEM.
 The output file password source. For more information about the format of B<arg>
 see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)>.
 
-=item B<-cipher>
+=item B<-I<cipher>>
 
 This option encrypts the private key with the supplied cipher. Any algorithm
 name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
index 3a40b4d89d2608c2197be944deae53d46b134dff..976be97344ac14d27f44aa413814f36dbc7b29ea 100644 (file)
@@ -8,6 +8,7 @@ list - list algorithms and features
 
 B<openssl list>
 [B<-help>]
+[B<-1>]
 [B<-commands>]
 [B<-digest-commands>]
 [B<-digest-algorithms>]
@@ -30,6 +31,11 @@ features.
 
 Display a usage message.
 
+=item B<-1>
+
+List the commands, digest-commands, or cipher-commands in a single column.
+If used, this option must be given first.
+
 =item B<-commands>
 
 Display a list of standard commands.
index 42621df336754c482d2ebebb9de54439b50525e2..281518bf013087986c369fa838f266e46998f687 100644 (file)
@@ -85,7 +85,7 @@ B<openssl> B<ocsp>
 [B<-ndays n>]
 [B<-resp_key_id>]
 [B<-nrequest n>]
-[B<-md5|-sha1|...>]
+[B<-I<digest>>]
 
 =head1 DESCRIPTION
 
@@ -286,7 +286,7 @@ status information is immediately available. In this case the age of the
 B<notBefore> field is checked to see it is not older than B<age> seconds old.
 By default this additional check is not performed.
 
-=item B<-[digest]>
+=item B<-I<digest>>
 
 This option sets digest algorithm to use for certificate identification in the
 OCSP request. Any digest supported by the OpenSSL B<dgst> command can be used.
index 4d37c92c5b1f5e139afec096a90f14ea09107907..3c277a55a353d4e229f67472f251397cf23ebc19 100644 (file)
@@ -15,7 +15,7 @@ B<openssl> B<pkey>
 [B<-out filename>]
 [B<-passout arg>]
 [B<-traditional>]
-[B<-cipher>]
+[B<-I<cipher>>]
 [B<-text>]
 [B<-text_pub>]
 [B<-noout>]
@@ -74,7 +74,7 @@ Normally a private key is written using standard format: this is PKCS#8 form
 with the appropriate encryption algorithm (if any). If the B<-traditional>
 option is specified then the older "traditional" format is used instead.
 
-=item B<-cipher>
+=item B<-I<cipher>>
 
 These options encrypt the private key with the supplied cipher. Any algorithm
 name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>.
diff --git a/doc/man1/prime.pod b/doc/man1/prime.pod
new file mode 100644 (file)
index 0000000..f6f6158
--- /dev/null
@@ -0,0 +1,67 @@
+=pod
+
+=head1 NAME
+
+prime - compute prime numbers
+
+=head1 SYNOPSIS
+
+B<openssl prime>
+[B<-help>]
+[B<-hex>]
+[B<-generate>]
+[B<-bits>]
+[B<-safe>]
+[B<-checks>]
+[I<number...>]
+
+=head1 DESCRIPTION
+
+The B<prime> command checks if the specified numbers are prime.
+
+If no numbers are given on the command line, the B<-generate> flag should
+be used to generate primes according to the requirements specified by the
+rest of the flags.
+
+=head1 OPTIONS
+
+=over 4
+
+=item [B<-help>]
+
+Display an option summary.
+
+=item [B<-hex>]
+
+Generate hex output.
+
+=item [B<-generate>]
+
+Generate a prime number.
+
+=item [B<-bits num>]
+
+Generate a prime with B<num> bits.
+
+=item [B<-safe>]
+
+When used with B<-generate>, generates a "safe" prime. If the number
+generated is B<n>, then check that B<(n-1)/2> is also prime.
+
+=item [B<-checks num>]
+
+Perform the checks B<num> times to see that the generated number
+is prime.  The default is 20.
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2017 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index aec2ada807975ed8939a82b018347004d8c71947..1930088fe87d4e28e8cedc32f3f69efee22ce3d5 100644 (file)
@@ -29,7 +29,7 @@ B<openssl> B<req>
 [B<-keyform PEM|DER>]
 [B<-keyout filename>]
 [B<-keygen_engine id>]
-[B<-[digest]>]
+[B<-I<digest>>]
 [B<-config filename>]
 [B<-multivalue-rdn>]
 [B<-x509>]
@@ -198,7 +198,7 @@ configuration file is used.
 If this option is specified then if a private key is created it
 will not be encrypted.
 
-=item B<-[digest]>
+=item B<-I<digest>>
 
 This specifies the message digest to sign the request.
 Any digest supported by the OpenSSL B<dgst> command can be used.
index 7f2fd7be272e65b59340d85cfa97210f14f670c2..50f6b9cfd8e07d87538ec1046af7875d9e35e706 100644 (file)
@@ -111,7 +111,8 @@ B<openssl> B<s_client>
 [B<-status>]
 [B<-alpn protocols>]
 [B<-nextprotoneg protocols>]
-[B<-ct|noct>]
+[B<-ct>]
+[B<-noct>]
 [B<-ctlogfile>]
 [B<-keylogfile file>]
 [B<-early_data file>]
@@ -576,7 +577,7 @@ client to advertise support for the TLS extension but disconnect just
 after receiving ServerHello with a list of server supported protocols.
 The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used.
 
-=item B<-ct|noct>
+=item B<-ct>, B<-noct>
 
 Use one of these two options to control whether Certificate Transparency (CT)
 is enabled (B<-ct>) or disabled (B<-noct>).
index 8661a00a950e1b6cd2df879ac496231c8cd57ee9..b926b6e842c7da600955c76afd38a6e20673b365 100644 (file)
@@ -13,14 +13,13 @@ B<openssl> B<s_time>
 [B<-cert filename>]
 [B<-key filename>]
 [B<-CApath directory>]
-[B<-CAfile filename>]
+[B<-cafile filename>]
 [B<-no-CAfile>]
 [B<-no-CApath>]
 [B<-reuse>]
 [B<-new>]
 [B<-verify depth>]
 [B<-nameopt option>]
-[B<-nbio>]
 [B<-time seconds>]
 [B<-ssl3>]
 [B<-bugs>]
@@ -109,10 +108,6 @@ Performs the timing test using the same session ID; this can be used as a test
 that session caching is working. If neither B<-new> nor B<-reuse> are
 specified, they are both on by default and executed in sequence.
 
-=item B<-nbio>
-
-Turns on non-blocking I/O.
-
 =item B<-ssl3>
 
 These options disable the use of certain SSL or TLS protocols. By default
index 5b13fdac124401144c743612511dcb63cb756db6..4d8cf7a1ce621d91bcd4f30ffced52f4999aa117 100644 (file)
@@ -16,7 +16,7 @@ B<openssl> B<smime>
 [B<-pk7out>]
 [B<-binary>]
 [B<-crlfeol>]
-[B<-[cipher]>]
+[B<-I<cipher>>]
 [B<-in file>]
 [B<-CAfile file>]
 [B<-CApath dir>]
@@ -201,7 +201,7 @@ Do not load the trusted CA certificates from the default directory location.
 Digest algorithm to use when signing or resigning. If not present then the
 default digest algorithm for the signing key will be used (usually SHA1).
 
-=item B<-[cipher]>
+=item B<-I<cipher>>
 
 The encryption algorithm to use. For example DES  (56 bits) - B<-des>,
 triple DES (168 bits) - B<-des3>,
diff --git a/doc/man1/srp.pod b/doc/man1/srp.pod
new file mode 100644 (file)
index 0000000..a5dcf2e
--- /dev/null
@@ -0,0 +1,72 @@
+=pod
+
+=head1 NAME
+
+srp - maintain SRP password file
+
+=head1 SYNOPSIS
+
+B<openssl srp>
+[B<-help>]
+[B<-verbose>]
+[B<-add>]
+[B<-modify>]
+[B<-delete>]
+[B<-list>]
+[B<-name section>]
+[B<-config file>]
+[B<-srpvfile file>]
+[B<-gn identifier>]
+[B<-userinfo text...>]
+[B<-passin arg>]
+[B<-passout arg>]
+[I<user...>]
+
+=head1 DESCRIPTION
+
+The B<srp> command is user to maintain an SRP (secure remote password)
+file.
+At most one of the B<-add>, B<-modify>, B<-delete>, and B<-list> options
+can be specified.
+These options take zero or more usernames as parameters and perform the
+appropriate operation on the SRP file.
+For B<-list>, if no B<user> is given then all users are displayed.
+
+The configuration file to use, and the section within the file, can be
+specified with the B<-config> and B<-name> flags, respectively.
+If the config file is not specified, the B<-srpvfile> can be used to
+just specify the file to operate on.
+
+The B<-userinfo> option specifies additional information to add when
+adding or modifying a user.
+
+The B<-gn> flag specifies the B<g> and B<N> values, using one of
+the strengths defined in IETF RFC 5054.
+
+The B<-passin> and B<-passout> arguments are parsed as described in
+the L<openssl(1)> command.
+
+=head1 OPTIONS
+
+=over 4
+
+=item [B<-help>]
+
+Display an option summary.
+
+=item [B<-verbose>]
+
+Generate verbose output while processing.
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2017 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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 56ace24817e0c376fa72baf4a84d2498190522b8..8886cd6bbdae30c8ff6acc7f3f3121d865738269 100644 (file)
@@ -13,7 +13,7 @@ B<-query>
 [B<-config> configfile]
 [B<-data> file_to_hash]
 [B<-digest> digest_bytes]
-[B<-[digest]>]
+[B<-I<digest>>]
 [B<-tspolicy> object_id]
 [B<-no_nonce>]
 [B<-cert>]
@@ -29,7 +29,7 @@ B<-reply>
 [B<-passin> password_src]
 [B<-signer> tsa_cert.pem]
 [B<-inkey> file_or_id]
-[B<-sha1|-sha224|-sha256|-sha384|-sha512>]
+[B<-I<digest>>]
 [B<-chain> certs_file.pem]
 [B<-tspolicy> object_id]
 [B<-in> response.tsr]
@@ -165,7 +165,7 @@ per byte, the bytes optionally separated by colons (e.g. 1A:F6:01:... or
 1AF601...). The number of bytes must match the message digest algorithm
 in use. (Optional)
 
-=item B<-[digest]>
+=item B<-I<digest>>
 
 The message digest to apply to the data file.
 Any digest supported by the OpenSSL B<dgst> command can be used.
@@ -258,7 +258,7 @@ B<signer_key> config file option. (Optional)
 If no engine is used, the argument is taken as a file; if an engine is
 specified, the argument is given to the engine as a key identifier.
 
-=item B<-sha1|-sha224|-sha256|-sha384|-sha512>
+=item B<-I<digest>>
 
 Signing digest to use. Overrides the B<signer_digest> config file
 option. (Optional)
@@ -459,7 +459,7 @@ command line option. (Optional)
 =item B<signer_digest>
 
 Signing digest to use. The same as the
-B<-sha1|-sha224|-sha256|-sha384|-sha512> command line option. (Optional)
+B<-I<digest>> command line option. (Optional)
 
 =item B<default_policy>
 
index d31460b5dc116f0addf023d08f293cf5a157b6ea..a2cbd0dda56e6456c30783beada8d15fca07bf18 100644 (file)
@@ -56,7 +56,7 @@ B<openssl> B<x509>
 [B<-ext extensions>]
 [B<-certopt option>]
 [B<-C>]
-[B<-[digest]>]
+[B<-I<digest>>]
 [B<-clrext>]
 [B<-extfile filename>]
 [B<-extensions section>]
@@ -109,7 +109,7 @@ if this option is not specified.
 This specifies the output filename to write to or standard output by
 default.
 
-=item B<-[digest]>
+=item B<-I<digest>>
 
 The digest to use.
 This affects any signing or display option that uses a message
index 7f5f1eb06f99ec219830f20b37adffc1d3365c97..a5fc62f4743524a81f4be08fab1785fcecfffdf8 100755 (executable)
@@ -26,6 +26,7 @@ our($opt_n);
 our($opt_p);
 our($opt_s);
 our($opt_u);
+our($opt_c);
 
 sub help()
 {
@@ -38,6 +39,7 @@ Find small errors (nits) in documentation.  Options:
     -p Warn if non-public name documented (implies -n)
     -u List undocumented functions
     -h Print this help message
+    -c List undocumented commands and options
 EOF
     exit;
 }
@@ -397,21 +399,123 @@ sub publicize() {
     }
 }
 
-getopts('dlnsphu');
+my %skips = (
+    'aes128' => 1,
+    'aes192' => 1,
+    'aes256' => 1,
+    'aria128' => 1,
+    'aria192' => 1,
+    'aria256' => 1,
+    'camellia128' => 1,
+    'camellia192' => 1,
+    'camellia256' => 1,
+    'des' => 1,
+    'des3' => 1,
+    'idea' => 1,
+    '[cipher]' => 1,
+    '[digest]' => 1,
+);
+
+sub checkflags() {
+    my $cmd = shift;
+    my %cmdopts;
+    my %docopts;
+    my $ok = 1;
+
+    # Get the list of options in the command.
+    open CFH, "./apps/openssl list --options $cmd|"
+        || die "Can list options for $cmd, $!";
+    while ( <CFH> ) {
+        chop;
+        s/ .$//;
+        $cmdopts{$_} = 1;
+    }
+    close CFH;
+
+    # Get the list of flags from the synopsis
+    open CFH, "<doc/man1/$cmd.pod"
+        || die "Can't open $cmd.pod, $!";
+    while ( <CFH> ) {
+        chop;
+        last if /DESCRIPTION/;
+        next unless /\[B<-([^ >]+)/;
+        $docopts{$1} = 1;
+    }
+    close CFH;
+
+    # See what's in the command not the manpage.
+    my @undocced = ();
+    foreach my $k ( keys %cmdopts ) {
+        push @undocced, $k unless $docopts{$k};
+    }
+    if ( scalar @undocced > 0 ) {
+        $ok = 0;
+        foreach ( @undocced ) {
+            print "doc/man1/$cmd.pod: Missing -$_\n";
+        }
+    }
+
+    # See what's in the command not the manpage.
+    my @unimpl = ();
+    foreach my $k ( keys %docopts ) {
+        push @unimpl, $k unless $cmdopts{$k};
+    }
+    if ( scalar @unimpl > 0 ) {
+        $ok = 0;
+        foreach ( @unimpl ) {
+            next if defined $skips{$_};
+            print "doc/man1/$cmd.pod: Not implemented -$_\n";
+        }
+    }
+
+    return $ok;
+}
+
+getopts('cdlnsphu');
 
 &help() if $opt_h;
 $opt_n = 1 if $opt_s or $opt_p;
 $opt_u = 1 if $opt_d;
 
-die "Need one of -[dlnspu] flags.\n"
-    unless $opt_l or $opt_n or $opt_u;
+die "Need one of -[cdlnspu] flags.\n"
+    unless $opt_c or $opt_l or $opt_n or $opt_u;
 
+if ( $opt_c ) {
+    my $ok = 1;
+    my @commands = ();
 
-if ( $opt_n ) {
-    &publicize() if $opt_p;
-    foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) {
-        &check($_);
+    # Get list of commands.
+    open FH, "./apps/openssl list -1 -commands|"
+        || die "Can't list commands, $!";
+    while ( <FH> ) {
+        chop;
+        push @commands, $_;
+    }
+    close FH;
+
+    # See if each has a manpage.
+    foreach ( @commands ) {
+        next if $_ eq 'help' || $_ eq 'exit';
+        if ( ! -f "doc/man1/$_.pod" ) {
+            print "doc/man1/$_.pod does not exist\n";
+            $ok = 0;
+        } else {
+            $ok = 0 if not &checkflags($_);
+        }
     }
+
+    # See what help is missing.
+    open FH, "./apps/openssl list --missing-help |"
+        || die "Can't list missing help, $!";
+    while ( <FH> ) {
+        chop;
+        my ($cmd, $flag) = split;
+        print "$cmd has no help for -$flag\n";
+        $ok = 0;
+    }
+    close FH;
+
+    exit 1 if not $ok;
 }
 
 if ( $opt_l ) {
@@ -421,6 +525,13 @@ if ( $opt_l ) {
     checklinks();
 }
 
+if ( $opt_n ) {
+    &publicize() if $opt_p;
+    foreach (@ARGV ? @ARGV : glob('doc/*/*.pod')) {
+        &check($_);
+    }
+}
+
 if ( $opt_u ) {
     my %temp = &getdocced('doc/man3');
     foreach ( keys %temp ) {