Remove the X_OK define, it is unused.
[openssl.git] / apps / ca.c
index 102ff87d6fe1c712668ba7406f8ddca145dc96de..976f6bb5f00c8416d4a383e00219fb64e72cb2fa 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -38,7 +38,6 @@
 
 #ifndef W_OK
 # define F_OK 0
-# define X_OK 1
 # define W_OK 2
 # define R_OK 4
 #endif
@@ -62,6 +61,7 @@
 #define ENV_NEW_CERTS_DIR       "new_certs_dir"
 #define ENV_CERTIFICATE         "certificate"
 #define ENV_SERIAL              "serial"
+#define ENV_RAND_SERIAL         "rand_serial"
 #define ENV_CRLNUMBER           "crlnumber"
 #define ENV_PRIVATE_KEY         "private_key"
 #define ENV_DEFAULT_DAYS        "default_days"
@@ -153,6 +153,8 @@ typedef enum OPTION_choice {
     OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
     OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
     OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
+    OPT_RAND_SERIAL,
+    OPT_R_ENUM,
     /* Do not change the order here; see related case statements below */
     OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
 } OPTION_CHOICE;
@@ -166,6 +168,8 @@ const OPTIONS ca_options[] = {
     {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
     {"create_serial", OPT_CREATE_SERIAL, '-',
      "If reading serial fails, create a new random serial"},
+    {"rand_serial", OPT_RAND_SERIAL, '-',
+     "Always create a random serial; do not store it"},
     {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
      "Enable support for multivalued RDNs"},
     {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
@@ -217,6 +221,7 @@ const OPTIONS ca_options[] = {
      "sets compromise time to val and the revocation reason to keyCompromise"},
     {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
      "sets compromise time to val and the revocation reason to CACompromise"},
+    OPT_R_OPTIONS,
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
@@ -247,7 +252,7 @@ int ca_main(int argc, char **argv)
     char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
     const char *serialfile = NULL, *subj = NULL;
     char *prog, *startdate = NULL, *enddate = NULL;
-    char *dbfile = NULL, *f, *randfile = NULL;
+    char *dbfile = NULL, *f;
     char new_cert[CERT_MAX + 1];
     char tmp[10 + 1] = "\0";
     char *const *pp;
@@ -256,7 +261,7 @@ int ca_main(int argc, char **argv)
     int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
     int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0;
     int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
-    int i, j, selfsign = 0;
+    int rand_ser = 0, i, j, selfsign = 0;
     long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
     unsigned long chtype = MBSTRING_ASC, certopt = 0;
     X509 *x509 = NULL, *x509p = NULL, *x = NULL;
@@ -301,6 +306,9 @@ opthelp:
         case OPT_UTF8:
             chtype = MBSTRING_UTF8;
             break;
+        case OPT_RAND_SERIAL:
+            rand_ser = 1;
+            break;
         case OPT_CREATE_SERIAL:
             create_ser = 1;
             break;
@@ -332,6 +340,10 @@ opthelp:
         case OPT_PASSIN:
             passinarg = opt_arg();
             break;
+        case OPT_R_CASES:
+            if (!opt_rand(o))
+                goto end;
+            break;
         case OPT_KEY:
             key = opt_arg();
             break;
@@ -465,23 +477,20 @@ end_of_options:
         }
     }
 
-    randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
-    if (randfile == NULL)
-        ERR_clear_error();
-    app_RAND_load_file(randfile, 0);
+    app_RAND_load_conf(conf, BASE_SECTION);
 
     f = NCONF_get_string(conf, section, STRING_MASK);
-    if (!f)
+    if (f == NULL)
         ERR_clear_error();
 
-    if (f && !ASN1_STRING_set_default_mask_asc(f)) {
+    if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
         BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
         goto end;
     }
 
     if (chtype != MBSTRING_UTF8) {
         f = NCONF_get_string(conf, section, UTF8_IN);
-        if (!f)
+        if (f == NULL)
             ERR_clear_error();
         else if (strcmp(f, "yes") == 0)
             chtype = MBSTRING_UTF8;
@@ -489,9 +498,9 @@ end_of_options:
 
     db_attr.unique_subject = 1;
     p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
-    if (p) {
+    if (p != NULL)
         db_attr.unique_subject = parse_yesno(p, 1);
-    else
+    else
         ERR_clear_error();
 
     /*****************************************************************/
@@ -520,7 +529,7 @@ end_of_options:
         && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
         goto end;
 
-    if (!key) {
+    if (key == NULL) {
         free_key = 1;
         if (!app_passwd(passinarg, NULL, &key, NULL)) {
             BIO_printf(bio_err, "Error getting password\n");
@@ -528,12 +537,11 @@ end_of_options:
         }
     }
     pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
-    if (key)
+    if (key != NULL)
         OPENSSL_cleanse(key, strlen(key));
-    if (pkey == NULL) {
+    if (pkey == NULL)
         /* load_key() has already printed an appropriate message */
         goto end;
-    }
 
     /*****************************************************************/
     /* we need a certificate */
@@ -568,7 +576,7 @@ end_of_options:
 
     f = NCONF_get_string(conf, section, ENV_NAMEOPT);
 
-    if (f) {
+    if (f != NULL) {
         if (!set_nameopt(f)) {
             BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
             goto end;
@@ -578,24 +586,26 @@ end_of_options:
 
     f = NCONF_get_string(conf, section, ENV_CERTOPT);
 
-    if (f) {
+    if (f != NULL) {
         if (!set_cert_ex(&certopt, f)) {
             BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
             goto end;
         }
         default_op = 0;
-    } else
+    } else {
         ERR_clear_error();
+    }
 
     f = NCONF_get_string(conf, section, ENV_EXTCOPY);
 
-    if (f) {
+    if (f != NULL) {
         if (!set_ext_copy(&ext_copy, f)) {
             BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
             goto end;
         }
-    } else
+    } else {
         ERR_clear_error();
+    }
 
     /*****************************************************************/
     /* lookup where to write new certificates */
@@ -770,21 +780,25 @@ end_of_options:
         if (verbose)
             BIO_printf(bio_err, "policy is %s\n", policy);
 
-        serialfile = lookup_conf(conf, section, ENV_SERIAL);
-        if (serialfile == NULL)
-            goto end;
+        if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
+            rand_ser = 1;
+        } else {
+            serialfile = lookup_conf(conf, section, ENV_SERIAL);
+            if (serialfile == NULL)
+                goto end;
+        }
 
-        if (!extconf) {
+        if (extconf == NULL) {
             /*
              * no '-extfile' option, so we look for extensions in the main
              * configuration file
              */
-            if (!extensions) {
+            if (extensions == NULL) {
                 extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
-                if (!extensions)
+                if (extensions == NULL)
                     ERR_clear_error();
             }
-            if (extensions) {
+            if (extensions != NULL) {
                 /* Check syntax of file */
                 X509V3_CTX ctx;
                 X509V3_set_ctx_test(&ctx);
@@ -805,7 +819,7 @@ end_of_options:
             if (startdate == NULL)
                 ERR_clear_error();
         }
-        if (startdate && !ASN1_TIME_set_string(NULL, startdate)) {
+        if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) {
             BIO_printf(bio_err,
                        "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
             goto end;
@@ -818,7 +832,7 @@ end_of_options:
             if (enddate == NULL)
                 ERR_clear_error();
         }
-        if (enddate && !ASN1_TIME_set_string(NULL, enddate)) {
+        if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) {
             BIO_printf(bio_err,
                        "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
             goto end;
@@ -828,24 +842,31 @@ end_of_options:
             if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
                 days = 0;
         }
-        if (!enddate && (days == 0)) {
+        if (enddate == NULL && (days == 0)) {
             BIO_printf(bio_err,
                        "cannot lookup how many days to certify for\n");
             goto end;
         }
 
-        if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
-            BIO_printf(bio_err, "error while loading serial number\n");
-            goto end;
-        }
-        if (verbose) {
-            if (BN_is_zero(serial))
-                BIO_printf(bio_err, "next serial number is 00\n");
-            else {
-                if ((f = BN_bn2hex(serial)) == NULL)
-                    goto end;
-                BIO_printf(bio_err, "next serial number is %s\n", f);
-                OPENSSL_free(f);
+        if (rand_ser) {
+            if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
+                BIO_printf(bio_err, "error generating serial number\n");
+                goto end;
+            }
+        } else {
+            if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
+                BIO_printf(bio_err, "error while loading serial number\n");
+                goto end;
+            }
+            if (verbose) {
+                if (BN_is_zero(serial)) {
+                    BIO_printf(bio_err, "next serial number is 00\n");
+                } else {
+                    if ((f = BN_bn2hex(serial)) == NULL)
+                        goto end;
+                    BIO_printf(bio_err, "next serial number is %s\n", f);
+                    OPENSSL_free(f);
+                }
             }
         }
 
@@ -969,7 +990,8 @@ end_of_options:
             BIO_printf(bio_err, "Write out database with %d new entries\n",
                        sk_X509_num(cert_sk));
 
-            if (!save_serial(serialfile, "new", serial, NULL))
+            if (!rand_ser
+                    && !save_serial(serialfile, "new", serial, NULL))
                 goto end;
 
             if (!save_index(dbfile, "new", db))
@@ -1045,12 +1067,12 @@ end_of_options:
     /*****************************************************************/
     if (gencrl) {
         int crl_v2 = 0;
-        if (!crl_ext) {
+        if (crl_ext == NULL) {
             crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
-            if (!crl_ext)
+            if (crl_ext == NULL)
                 ERR_clear_error();
         }
-        if (crl_ext) {
+        if (crl_ext != NULL) {
             /* Check syntax of file */
             X509V3_CTX ctx;
             X509V3_set_ctx_test(&ctx);
@@ -1141,12 +1163,12 @@ end_of_options:
 
         /* Add any extensions asked for */
 
-        if (crl_ext || crlnumberfile != NULL) {
+        if (crl_ext != NULL || crlnumberfile != NULL) {
             X509V3_CTX crlctx;
             X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
             X509V3_set_nconf(&crlctx, conf);
 
-            if (crl_ext)
+            if (crl_ext != NULL)
                 if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
                     goto end;
             if (crlnumberfile != NULL) {
@@ -1160,14 +1182,15 @@ end_of_options:
                     goto end;
             }
         }
-        if (crl_ext || crl_v2) {
+        if (crl_ext != NULL || crl_v2) {
             if (!X509_CRL_set_version(crl, 1))
                 goto end;       /* version 2 CRL */
         }
 
         /* we have a CRL number that need updating */
         if (crlnumberfile != NULL)
-            if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
+            if (!rand_ser
+                    && !save_serial(crlnumberfile, "new", crlnumber, NULL))
                 goto end;
 
         BN_free(crlnumber);
@@ -1209,17 +1232,16 @@ end_of_options:
             BIO_printf(bio_err, "Data Base Updated\n");
         }
     }
-    /*****************************************************************/
     ret = 0;
+
  end:
+    if (ret)
+        ERR_print_errors(bio_err);
     BIO_free_all(Sout);
     BIO_free_all(out);
     BIO_free_all(in);
     sk_X509_pop_free(cert_sk, X509_free);
 
-    if (ret)
-        ERR_print_errors(bio_err);
-    app_RAND_write_file(randfile);
     if (free_key)
         OPENSSL_free(key);
     BN_free(serial);
@@ -1297,8 +1319,9 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
                    "Signature did not match the certificate request\n");
         ERR_print_errors(bio_err);
         goto end;
-    } else
+    } else {
         BIO_printf(bio_err, "Signature ok\n");
+    }
 
     ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
                  chtype, multirdn, email_dn, startdate, enddate, days, batch,
@@ -1346,8 +1369,9 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x
         ok = 0;
         BIO_printf(bio_err, "Signature did not match the certificate\n");
         goto end;
-    } else
+    } else {
         BIO_printf(bio_err, "Signature ok\n");
+    }
 
     if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL)
         goto end;
@@ -1502,8 +1526,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                                "The %s field needed to be supplied and was missing\n",
                                cv->name);
                     goto end;
-                } else
+                } else {
                     push = tne;
+                }
             } else if (strcmp(cv->value, "match") == 0) {
                 int last2;
 
@@ -1573,14 +1598,14 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
         BIO_printf(bio_err,
                    "The subject name appears to be ok, checking data base for clashes\n");
 
-    /* 
+    /*
      * Build the correct Subject if no e-mail is wanted in the subject.
      * And add it later on because of the method extensions are added (altName)
      */
 
-    if (email_dn)
+    if (email_dn) {
         dn_subject = subject;
-    else {
+    else {
         X509_NAME_ENTRY *tmpne;
         /*
          * Its best to dup the subject DN and then delete any email addresses
@@ -1718,7 +1743,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
         else
             X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
 
-        if (extconf) {
+        if (extconf != NULL) {
             if (verbose)
                 BIO_printf(bio_err, "Extra configuration file found\n");
 
@@ -2505,9 +2530,9 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
             goto end;
         }
 
-        if (reason_code == 7)
+        if (reason_code == 7) {
             reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
-        else if (reason_code == 8) { /* Hold instruction */
+        else if (reason_code == 8) { /* Hold instruction */
             if (!arg_str) {
                 BIO_printf(bio_err, "missing hold instruction\n");
                 goto end;