fix warnings, and harmonize indentation
[openssl.git] / apps / ca.c
index 583977718969447b14de8465f1296dc604dc3311..4867f309c7a0645aa4c24d7083942ad15d52684b 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
 #ifdef OPENSSL_SYS_WINDOWS
 #define strcasecmp _stricmp
 #else
-#include <strings.h>
+#  ifdef NO_STRINGS_H
+    int        strcasecmp();
+#  else
+#    include <strings.h>
+#  endif /* NO_STRINGS_H */
 #endif
 
 #ifndef W_OK
@@ -238,7 +242,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
                int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
        unsigned long certopt, unsigned long nameopt, int default_op,
        int ext_copy);
-static X509_NAME *do_subject(char *subject);
 static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval);
 static int get_certificate_status(const char *ser_status, TXT_DB *db);
 static int do_updatedb(TXT_DB *db);
@@ -696,7 +699,7 @@ bad:
                        goto err;
                        }
                }
-       pkey = load_key(bio_err, keyfile, keyform, key, e, 
+       pkey = load_key(bio_err, keyfile, keyform, 0, key, e, 
                "CA private key");
        if (key) memset(key,0,strlen(key));
        if (pkey == NULL)
@@ -1155,9 +1158,14 @@ bad:
                        }
                if (verbose)
                        {
-                       if ((f=BN_bn2hex(serial)) == NULL) goto err;
-                       BIO_printf(bio_err,"next serial number is %s\n",f);
-                       OPENSSL_free(f);
+                       if (BN_is_zero(serial))
+                               BIO_printf(bio_err,"next serial number is 00\n");
+                       else
+                               {
+                               if ((f=BN_bn2hex(serial)) == NULL) goto err;
+                               BIO_printf(bio_err,"next serial number is %s\n",f);
+                               OPENSSL_free(f);
+                               }
                        }
 
                if ((attribs=NCONF_get_section(conf,policy)) == NULL)
@@ -1451,13 +1459,13 @@ bad:
                        }
                if ((crldays == 0) && (crlhours == 0))
                        {
-                       BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
+                       BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n");
                        goto err;
                        }
 
                if (verbose) BIO_printf(bio_err,"making CRL\n");
                if ((crl=X509_CRL_new()) == NULL) goto err;
-               if (!X509_CRL_set_issuer_name(crl, X509_get_issuer_name(x509))) goto err;
+               if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto err;
 
                tmptm = ASN1_TIME_new();
                if (!tmptm) goto err;
@@ -1512,7 +1520,7 @@ bad:
                        else
 #endif
 #ifndef OPENSSL_NO_ECDSA
-                       if (pkey->type == EVP_PKEY_ECDSA)
+                       if (pkey->type == EVP_PKEY_EC)
                                dgst=EVP_ecdsa();
                        else
 #endif
@@ -1688,7 +1696,7 @@ static BIGNUM *load_serial(char *serialfile)
        ret=ASN1_INTEGER_to_BN(ai,NULL);
        if (ret == NULL)
                {
-               BIO_printf(bio_err,"error converting number from bin to BIGNUM");
+               BIO_printf(bio_err,"error converting number from bin to BIGNUM\n");
                goto err;
                }
 err:
@@ -1879,7 +1887,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
 
        if (subj)
                {
-               X509_NAME *n = do_subject(subj);
+               X509_NAME *n = do_subject(subj, MBSTRING_ASC);
 
                if (!n)
                        {
@@ -2091,9 +2099,11 @@ again2:
                        }
                }
 
-       row[DB_name]=X509_NAME_oneline(dn_subject,NULL,0);
-       row[DB_serial]=BN_bn2hex(serial);
-       if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
+       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;
@@ -2291,7 +2301,7 @@ again2:
        EVP_PKEY_free(pktmp);
 #endif
 #ifndef OPENSSL_NO_ECDSA
-       if (pkey->type == EVP_PKEY_ECDSA)
+       if (pkey->type == EVP_PKEY_EC)
                dgst = EVP_ecdsa();
        pktmp = X509_get_pubkey(ret);
        if (EVP_PKEY_missing_parameters(pktmp) &&
@@ -2316,10 +2326,10 @@ again2:
 
        /* row[DB_serial] done already */
        row[DB_file]=(char *)OPENSSL_malloc(8);
-       /* row[DB_name] done already */
+       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_file] == NULL))
+               (row[DB_file] == NULL) || (row[DB_name] == NULL))
                {
                BIO_printf(bio_err,"Memory allocation failure\n");
                goto err;
@@ -2586,7 +2596,10 @@ static int do_revoke(X509 *x509, TXT_DB *db, int type, char *value)
                row[i]=NULL;
        row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0);
        bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL);
-       row[DB_serial]=BN_bn2hex(bn);
+       if (BN_is_zero(bn))
+               row[DB_serial]=BUF_strdup("00");
+       else
+               row[DB_serial]=BN_bn2hex(bn);
        BN_free(bn);
        if ((row[DB_name] == NULL) || (row[DB_serial] == NULL))
                {
@@ -3023,65 +3036,128 @@ int make_revoked(X509_REVOKED *rev, char *str)
        return ret;
        }
 
-static X509_NAME *do_subject(char *subject)
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+X509_NAME *do_subject(char *subject, long chtype)
        {
-       X509_NAME *n = NULL;
-
-       int i, nid, ne_num=0;
-
-       char *ne_name = NULL;
-       char *ne_value = NULL;
-
-       char *tmp = NULL;
-       char *p[2];
+       size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
+       char *buf = OPENSSL_malloc(buflen);
+       size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
+       char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
+       char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
 
-       char *str_list[256];
-       
-       p[0] = ",/";
-       p[1] = "=";
+       char *sp = subject, *bp = buf;
+       int i, ne_num = 0;
 
-       n = X509_NAME_new();
+       X509_NAME *n = NULL;
+       int nid;
 
-       tmp = strtok(subject, p[0]);
-       while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list)))
+       if (!buf || !ne_types || !ne_values)
                {
-               char *token = tmp;
+               BIO_printf(bio_err, "malloc error\n");
+               goto error;
+               }       
 
-               while (token[0] == ' ')
-                       token++;
-               str_list[ne_num] = token;
+       if (*subject != '/')
+               {
+               BIO_printf(bio_err, "Subject does not start with '/'.\n");
+               goto error;
+               }
+       sp++; /* skip leading / */
 
-               tmp = strtok(NULL, p[0]);
+       while (*sp)
+               {
+               /* collect type */
+               ne_types[ne_num] = bp;
+               while (*sp)
+                       {
+                       if (*sp == '\\') /* is there anything to escape in the type...? */
+                               {
+                               if (*++sp)
+                                       *bp++ = *sp++;
+                               else    
+                                       {
+                                       BIO_printf(bio_err, "escape character at end of string\n");
+                                       goto error;
+                                       }
+                               }       
+                       else if (*sp == '=')
+                               {
+                               sp++;
+                               *bp++ = '\0';
+                               break;
+                               }
+                       else
+                               *bp++ = *sp++;
+                       }
+               if (!*sp)
+                       {
+                       BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
+                       goto error;
+                       }
+               ne_values[ne_num] = bp;
+               while (*sp)
+                       {
+                       if (*sp == '\\')
+                               {
+                               if (*++sp)
+                                       *bp++ = *sp++;
+                               else
+                                       {
+                                       BIO_printf(bio_err, "escape character at end of string\n");
+                                       goto error;
+                                       }
+                               }
+                       else if (*sp == '/')
+                               {
+                               sp++;
+                               break;
+                               }
+                       else
+                               *bp++ = *sp++;
+                       }
+               *bp++ = '\0';
                ne_num++;
-               }
+               }       
+
+       if (!(n = X509_NAME_new()))
+               goto error;
 
        for (i = 0; i < ne_num; i++)
                {
-               ne_name  = strtok(str_list[i], p[1]);
-               ne_value = strtok(NULL, p[1]);
-
-               if ((nid=OBJ_txt2nid(ne_name)) == NID_undef)
+               if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
                        {
-                       BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name);
+                       BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
                        continue;
                        }
 
-               if (ne_value == NULL)
+               if (!*ne_values[i])
                        {
-                       BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name);
+                       BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
                        continue;
                        }
 
-               if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0))
-                       {
-                       X509_NAME_free(n);
-                       return NULL;
-                       }
+               if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
+                       goto error;
                }
 
+       OPENSSL_free(ne_values);
+       OPENSSL_free(ne_types);
+       OPENSSL_free(buf);
        return n;
-       }
 
+error:
+       X509_NAME_free(n);
+       if (ne_values)
+               OPENSSL_free(ne_values);
+       if (ne_types)
+               OPENSSL_free(ne_types);
+       if (buf)
+               OPENSSL_free(buf);
+       return NULL;
+}
 
 int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
        {