[openssl-commits] [openssl] OpenSSL_1_0_2-stable update

Matt Caswell matt at openssl.org
Thu Mar 15 13:39:07 UTC 2018


The branch OpenSSL_1_0_2-stable has been updated
       via  16a345e5c8b5c1166a5e214a8ee7ebf21d447fbe (commit)
       via  dacdc5fe526d5b838f51711ba602d375159e488a (commit)
       via  50615b3c969d1cc2d4beb09f141c678bfe06382b (commit)
       via  5caf721bbb154c6845c7f2a0fd7f450bfc496444 (commit)
       via  58f858274923a6a2a8aa144ff76492d3159a0710 (commit)
      from  f1e2b8adbd84434a634b62a3dc0c0c7506a96ae2 (commit)


- Log -----------------------------------------------------------------
commit 16a345e5c8b5c1166a5e214a8ee7ebf21d447fbe
Author: Matt Caswell <matt at openssl.org>
Date:   Wed Mar 14 14:40:18 2018 +0000

    Fix a memory leak in the ca application
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5445)

commit dacdc5fe526d5b838f51711ba602d375159e488a
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 23 19:48:11 2018 +0000

    Allow multiple entries without a Subject even if unique_subject == yes
    
    It is quite likely for there to be multiple certificates with empty
    subjects, which are still distinct because of subjectAltName. Therefore
    we allow multiple certificates with an empty Subject even if
    unique_subject is set to yes.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5445)

commit 50615b3c969d1cc2d4beb09f141c678bfe06382b
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Mar 8 15:55:46 2018 +0000

    Report a readable error on a duplicate cert in ca app
    
    Commit 87e8fec (16 years ago!) introduced a bug where if we are
    attempting to insert a cert with a duplicate subject name, and
    duplicate subject names are not allowed (which is the default),
    then we get an unhelpful error message back (error number 2). Prior
    to that commit we got a helpful error message which displayed details
    of the conflicting entry in the database.
    
    That commit was itself attempting to fix a bug with the noemailDN option
    where we were setting the subject field in the database too early
    (before extensions had made any amendments to it).
    
    This PR moves the check for a conflicting Subject name until after all
    changes to the Subject have been made by extensions etc.
    
    This also, co-incidentally Fixes the ca crashing bug described in issue
    5109.
    
    Fixes #5109
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5445)

commit 5caf721bbb154c6845c7f2a0fd7f450bfc496444
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 23 11:05:24 2018 +0000

    Revert "Don't crash on a missing Subject in index.txt"
    
    This reverts commit a3d684ffca282796511cb8f3593a59a80109eed8.
    
    Empty Subjects are permissible
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5445)

commit 58f858274923a6a2a8aa144ff76492d3159a0710
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Feb 23 11:05:01 2018 +0000

    Revert "Don't allow an empty Subject when creating a Certificate"
    
    This reverts commit dd37f6f12cc14cc4710289746b112eb0fed3b0b7.
    
    Empty Subjects are permissible.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5445)

-----------------------------------------------------------------------

Summary of changes:
 apps/ca.c       | 249 ++++++++++++++++++++++++++++----------------------------
 doc/apps/ca.pod |   4 +
 2 files changed, 130 insertions(+), 123 deletions(-)

diff --git a/apps/ca.c b/apps/ca.c
index 06002ad..4f9de54 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -880,10 +880,6 @@ int MAIN(int argc, char **argv)
             }
             p++;
         }
-        if (pp[DB_name][0] == '\0') {
-            BIO_printf(bio_err, "entry %d: bad Subject\n", i + 1);
-            goto err;
-        }
     }
     if (verbose) {
         BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); /* cannot fail */
@@ -1632,8 +1628,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                    CONF *lconf, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign)
 {
-    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
-        NULL;
+    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL;
     ASN1_UTCTIME *tm, *tmptm;
     ASN1_STRING *str, *str2;
     ASN1_OBJECT *obj;
@@ -1676,10 +1671,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                    "The Subject's Distinguished Name is as follows\n");
 
     name = X509_REQ_get_subject_name(req);
-    if (X509_NAME_entry_count(name) == 0) {
-        BIO_printf(bio_err, "Error: The supplied Subject is empty\n");
-        goto err;
-    }
     for (i = 0; i < X509_NAME_entry_count(name); i++) {
         ne = X509_NAME_get_entry(name, i);
         str = X509_NAME_ENTRY_get_data(ne);
@@ -1842,110 +1833,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
             goto err;
     }
 
-    if (X509_NAME_entry_count(subject) == 0) {
-        BIO_printf(bio_err,
-                   "Error: After applying policy the Subject is empty\n");
-        goto err;
-    }
-
-    if (verbose)
-        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)
-        dn_subject = subject;
-    else {
-        X509_NAME_ENTRY *tmpne;
-        /*
-         * Its best to dup the subject DN and then delete any email addresses
-         * because this retains its structure.
-         */
-        if (!(dn_subject = X509_NAME_dup(subject))) {
-            BIO_printf(bio_err, "Memory allocation failure\n");
-            goto err;
-        }
-        while ((i = X509_NAME_get_index_by_NID(dn_subject,
-                                               NID_pkcs9_emailAddress,
-                                               -1)) >= 0) {
-            tmpne = X509_NAME_get_entry(dn_subject, i);
-            X509_NAME_delete_entry(dn_subject, i);
-            X509_NAME_ENTRY_free(tmpne);
-        }
-    }
-
-    if (BN_is_zero(serial))
-        row[DB_serial] = BUF_strdup("00");
-    else
-        row[DB_serial] = BN_bn2hex(serial);
-    if (row[DB_serial] == NULL) {
-        BIO_printf(bio_err, "Memory allocation failure\n");
-        goto err;
-    }
-
-    if (db->attributes.unique_subject) {
-        OPENSSL_STRING *crow = row;
-
-        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
-        if (rrow != NULL) {
-            BIO_printf(bio_err,
-                       "ERROR:There is already a certificate for %s\n",
-                       row[DB_name]);
-        }
-    }
-    if (rrow == NULL) {
-        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
-        if (rrow != NULL) {
-            BIO_printf(bio_err,
-                       "ERROR:Serial number %s has already been issued,\n",
-                       row[DB_serial]);
-            BIO_printf(bio_err,
-                       "      check the database/serial_file for corruption\n");
-        }
-    }
-
-    if (rrow != NULL) {
-        BIO_printf(bio_err, "The matching entry has the following details\n");
-        if (rrow[DB_type][0] == 'E')
-            p = "Expired";
-        else if (rrow[DB_type][0] == 'R')
-            p = "Revoked";
-        else if (rrow[DB_type][0] == 'V')
-            p = "Valid";
-        else
-            p = "\ninvalid type, Data base error\n";
-        BIO_printf(bio_err, "Type          :%s\n", p);;
-        if (rrow[DB_type][0] == 'R') {
-            p = rrow[DB_exp_date];
-            if (p == NULL)
-                p = "undef";
-            BIO_printf(bio_err, "Was revoked on:%s\n", p);
-        }
-        p = rrow[DB_exp_date];
-        if (p == NULL)
-            p = "undef";
-        BIO_printf(bio_err, "Expires on    :%s\n", p);
-        p = rrow[DB_serial];
-        if (p == NULL)
-            p = "undef";
-        BIO_printf(bio_err, "Serial Number :%s\n", p);
-        p = rrow[DB_file];
-        if (p == NULL)
-            p = "undef";
-        BIO_printf(bio_err, "File name     :%s\n", p);
-        p = rrow[DB_name];
-        if (p == NULL)
-            p = "undef";
-        BIO_printf(bio_err, "Subject Name  :%s\n", p);
-        ok = -1;                /* This is now a 'bad' error. */
-        goto err;
-    }
-
     /* We are now totally happy, lets make and sign the certificate */
     if (verbose)
         BIO_printf(bio_err,
@@ -2068,10 +1955,124 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                 goto err;
     }
 
-    /* Set the right value for the noemailDN option */
-    if (email_dn == 0) {
-        if (!X509_set_subject_name(ret, dn_subject))
+    if (verbose)
+        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 */
+
+    if (!email_dn) {
+        X509_NAME_ENTRY *tmpne;
+        X509_NAME *dn_subject;
+
+        /*
+         * Its best to dup the subject DN and then delete any email addresses
+         * because this retains its structure.
+         */
+        if (!(dn_subject = X509_NAME_dup(subject))) {
+            BIO_printf(bio_err, "Memory allocation failure\n");
+            goto err;
+        }
+        while ((i = X509_NAME_get_index_by_NID(dn_subject,
+                                               NID_pkcs9_emailAddress,
+                                               -1)) >= 0) {
+            tmpne = X509_NAME_get_entry(dn_subject, i);
+            X509_NAME_delete_entry(dn_subject, i);
+            X509_NAME_ENTRY_free(tmpne);
+        }
+
+        if (!X509_set_subject_name(ret, dn_subject)) {
+            X509_NAME_free(dn_subject);
+            goto err;
+        }
+        X509_NAME_free(dn_subject);
+    }
+
+    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
+    if (row[DB_name] == NULL) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto err;
+    }
+
+    if (BN_is_zero(serial))
+        row[DB_serial] = BUF_strdup("00");
+    else
+        row[DB_serial] = BN_bn2hex(serial);
+    if (row[DB_serial] == NULL) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto err;
+    }
+
+    if (row[DB_name][0] == '\0') {
+        /*
+         * An empty subject! We'll use the serial number instead. If
+         * unique_subject is in use then we don't want different entries with
+         * empty subjects matching each other.
+         */
+        OPENSSL_free(row[DB_name]);
+        row[DB_name] = OPENSSL_strdup(row[DB_serial]);
+        if (row[DB_name] == NULL) {
+            BIO_printf(bio_err, "Memory allocation failure\n");
             goto err;
+        }
+    }
+
+    if (db->attributes.unique_subject) {
+        OPENSSL_STRING *crow = row;
+
+        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
+        if (rrow != NULL) {
+            BIO_printf(bio_err,
+                       "ERROR:There is already a certificate for %s\n",
+                       row[DB_name]);
+        }
+    }
+    if (rrow == NULL) {
+        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
+        if (rrow != NULL) {
+            BIO_printf(bio_err,
+                       "ERROR:Serial number %s has already been issued,\n",
+                       row[DB_serial]);
+            BIO_printf(bio_err,
+                       "      check the database/serial_file for corruption\n");
+        }
+    }
+
+    if (rrow != NULL) {
+        BIO_printf(bio_err, "The matching entry has the following details\n");
+        if (rrow[DB_type][0] == 'E')
+            p = "Expired";
+        else if (rrow[DB_type][0] == 'R')
+            p = "Revoked";
+        else if (rrow[DB_type][0] == 'V')
+            p = "Valid";
+        else
+            p = "\ninvalid type, Data base error\n";
+        BIO_printf(bio_err, "Type          :%s\n", p);;
+        if (rrow[DB_type][0] == 'R') {
+            p = rrow[DB_exp_date];
+            if (p == NULL)
+                p = "undef";
+            BIO_printf(bio_err, "Was revoked on:%s\n", p);
+        }
+        p = rrow[DB_exp_date];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Expires on    :%s\n", p);
+        p = rrow[DB_serial];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Serial Number :%s\n", p);
+        p = rrow[DB_file];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "File name     :%s\n", p);
+        p = rrow[DB_name];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Subject Name  :%s\n", p);
+        ok = -1;                /* This is now a 'bad' error. */
+        goto err;
     }
 
     if (!default_op) {
@@ -2122,10 +2123,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     row[DB_exp_date] = OPENSSL_malloc(tm->length + 1);
     row[DB_rev_date] = OPENSSL_malloc(1);
     row[DB_file] = OPENSSL_malloc(8);
-    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
     if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
         (row[DB_rev_date] == NULL) ||
-        (row[DB_file] == NULL) || (row[DB_name] == NULL)) {
+        (row[DB_file] == NULL)) {
         BIO_printf(bio_err, "Memory allocation failure\n");
         goto err;
     }
@@ -2155,18 +2155,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
     irow = NULL;
     ok = 1;
  err:
-    if (irow != NULL) {
+    if (ok != 1) {
         for (i = 0; i < DB_NUMBER; i++)
             OPENSSL_free(row[i]);
-        OPENSSL_free(irow);
     }
+    OPENSSL_free(irow);
 
     if (CAname != NULL)
         X509_NAME_free(CAname);
     if (subject != NULL)
         X509_NAME_free(subject);
-    if ((dn_subject != NULL) && !email_dn)
-        X509_NAME_free(dn_subject);
     if (tmptm != NULL)
         ASN1_UTCTIME_free(tmptm);
     if (ok <= 0) {
@@ -2369,6 +2367,11 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
     else
         row[DB_serial] = BN_bn2hex(bn);
     BN_free(bn);
+    if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
+        /* Entries with empty Subjects actually use the serial number instead */
+        OPENSSL_free(row[DB_name]);
+        row[DB_name] = OPENSSL_strdup(row[DB_serial]);
+    }
     if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
         BIO_printf(bio_err, "Memory allocation failure\n");
         goto err;
diff --git a/doc/apps/ca.pod b/doc/apps/ca.pod
index cc26bf4..8d94ecb 100644
--- a/doc/apps/ca.pod
+++ b/doc/apps/ca.pod
@@ -424,6 +424,10 @@ versions of OpenSSL.  However, to make CA certificate roll-over easier,
 it's recommended to use the value B<no>, especially if combined with
 the B<-selfsign> command line option.
 
+Note that it is valid in some circumstances for certificates to be created
+without any subject. In the case where there are multiple certificates without
+subjects this does not count as a duplicate.
+
 =item B<serial>
 
 a text file containing the next serial number to use in hex. Mandatory.


More information about the openssl-commits mailing list