free cleanup 12
[openssl.git] / apps / apps.c
index 462e2b650ce7b35d589793dcc42de8c79d22b26c..904629b2f15340238aeb516fd3e0302d84f1740f 100644 (file)
@@ -180,7 +180,7 @@ int chopup_args(ARGS *arg, char *buf)
     arg->argc = 0;
     if (arg->size == 0) {
         arg->size = 20;
-        arg->argv = (char **)OPENSSL_malloc(sizeof(char *) * arg->size);
+        arg->argv = app_malloc(sizeof(char *) * arg->size, "argv space");
         if (arg->argv == NULL)
             return 0;
     }
@@ -195,8 +195,7 @@ int chopup_args(ARGS *arg, char *buf)
         /* The start of something good :-) */
         if (arg->argc >= arg->size) {
             arg->size += 20;
-            arg->argv = (char **)OPENSSL_realloc(arg->argv,
-                                                 sizeof(char *) * arg->size);
+            arg->argv = OPENSSL_realloc(arg->argv, sizeof(char *) * arg->size);
             if (arg->argv == NULL)
                 return 0;
         }
@@ -368,13 +367,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
             ok = UI_add_input_string(ui, prompt, ui_flags, buf,
                                      PW_MIN_LENGTH, bufsiz - 1);
         if (ok >= 0 && verify) {
-            buff = (char *)OPENSSL_malloc(bufsiz);
-            if (!buff) {
-                BIO_printf(bio_err, "Out of memory\n");
-                UI_free(ui);
-                OPENSSL_free(prompt);
-                return 0;
-            }
+            buff = app_malloc(bufsiz, "password buffer");
             ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
                                       PW_MIN_LENGTH, bufsiz - 1, buf);
         }
@@ -384,10 +377,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
             }
             while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
 
-        if (buff) {
-            OPENSSL_cleanse(buff, (unsigned int)bufsiz);
-            OPENSSL_free(buff);
-        }
+        OPENSSL_clear_free(buff, (unsigned int)bufsiz);
 
         if (ok >= 0)
             res = strlen(buf);
@@ -610,8 +600,7 @@ int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl)
         OPENSSL_free(port);
     if (bio)
         BIO_free_all(bio);
-    if (rctx)
-        OCSP_REQ_CTX_free(rctx);
+    OCSP_REQ_CTX_free(rctx);
     if (rv != 1) {
         BIO_printf(bio_err, "Error loading %s from %s\n",
                    pcert ? "certificate" : "CRL", url);
@@ -972,8 +961,7 @@ static int load_certs_crls(const char *file, int format,
 
  end:
 
-    if (xis)
-        sk_X509_INFO_pop_free(xis, X509_INFO_free);
+    sk_X509_INFO_pop_free(xis, X509_INFO_free);
 
     if (rv == 0) {
         if (pcerts) {
@@ -991,6 +979,21 @@ static int load_certs_crls(const char *file, int format,
     return rv;
 }
 
+void* app_malloc(int sz, const char *what)
+{
+    void *vp = OPENSSL_malloc(sz);
+
+    if (vp == NULL) {
+        BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
+                opt_getprog(), sz, what);
+        ERR_print_errors(bio_err);
+        exit(1);
+    }
+    return vp;
+}
+
+
+
 STACK_OF(X509) *load_certs(const char *file, int format,
                            const char *pass, ENGINE *e, const char *desc)
 {
@@ -1415,8 +1418,7 @@ BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
     }
  err:
     BIO_free(in);
-    if (ai != NULL)
-        ASN1_INTEGER_free(ai);
+    ASN1_INTEGER_free(ai);
     return (ret);
 }
 
@@ -1469,8 +1471,7 @@ int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
     }
  err:
     BIO_free_all(out);
-    if (ai != NULL)
-        ASN1_INTEGER_free(ai);
+    ASN1_INTEGER_free(ai);
     return (ret);
 }
 
@@ -1589,11 +1590,7 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
         }
     }
 
-    if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) {
-        fprintf(stderr, "Out of memory\n");
-        goto err;
-    }
-
+    retdb = app_malloc(sizeof *retdb, "new DB");
     retdb->db = tmpdb;
     tmpdb = NULL;
     if (db_attr)
@@ -1616,8 +1613,7 @@ CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
  err:
     if (dbattr_conf)
         NCONF_free(dbattr_conf);
-    if (tmpdb)
-        TXT_DB_free(tmpdb);
+    TXT_DB_free(tmpdb);
     BIO_free_all(in);
     return retdb;
 }
@@ -1795,8 +1791,7 @@ int rotate_index(const char *dbfile, const char *new_suffix,
 void free_index(CA_DB *db)
 {
     if (db) {
-        if (db->db)
-            TXT_DB_free(db->db);
+        TXT_DB_free(db->db);
         OPENSSL_free(db);
     }
 }
@@ -1823,134 +1818,84 @@ int parse_yesno(const char *str, int def)
 }
 
 /*
- * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * name is expected to be in the format /type0=value0/type1=value1/type2=...
  * where characters may be escaped by \
  */
-X509_NAME *parse_name(char *subject, long chtype, int multirdn)
+X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
 {
-    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 *));
-    int *mval = OPENSSL_malloc(max_ne * sizeof(int));
+    int nextismulti = 0;
+    char *work;
+    X509_NAME *n;
 
-    char *sp = subject, *bp = buf;
-    int i, ne_num = 0;
-
-    X509_NAME *n = NULL;
-    int nid;
+    if (*cp++ != '/')
+        return NULL;
 
-    if (!buf || !ne_types || !ne_values || !mval) {
-        BIO_printf(bio_err, "malloc error\n");
-        goto error;
-    }
+    n = X509_NAME_new();
+    if (n == NULL)
+        return NULL;
+    work = OPENSSL_strdup(cp);
+    if (work == NULL)
+        goto err;
 
-    if (*subject != '/') {
-        BIO_printf(bio_err, "Subject does not start with '/'.\n");
-        goto error;
-    }
-    sp++;                       /* skip leading / */
-
-    /* no multivalued RDN by default */
-    mval[ne_num] = 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) {
+    while (*cp) {
+        char *bp = work;
+        char *typestr = bp;
+        unsigned char *valstr;
+        int nid;
+        int ismulti = nextismulti;
+        nextismulti = 0;
+
+        /* Collect the type */
+        while (*cp && *cp != '=')
+            *bp++ = *cp++;
+        if (*cp == '\0') {
             BIO_printf(bio_err,
-                       "end of string encountered while processing type of subject name element #%d\n",
-                       ne_num);
-            goto error;
+                    "%s: Hit end of string before finding the equals.\n",
+                    opt_getprog());
+            goto err;
         }
-        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++;
-                /* no multivalued RDN by default */
-                mval[ne_num + 1] = 0;
-                break;
-            } else if (*sp == '+' && multirdn) {
-                /*
-                 * a not escaped + signals a mutlivalued RDN
-                 */
-                sp++;
-                mval[ne_num + 1] = -1;
+        *bp++ = '\0';
+        ++cp;
+
+        /* Collect the value. */
+        valstr = (unsigned char *)bp;
+        for (; *cp && *cp != '/'; *bp++ = *cp++) {
+            if (canmulti && *cp == '+') {
+                nextismulti = 1;
                 break;
-            } else
-                *bp++ = *sp++;
+            }
+            if (*cp == '\\' && *++cp == '\0') {
+                BIO_printf(bio_err,
+                        "%s: escape character at end of string\n",
+                        opt_getprog());
+                goto err;
+            }
         }
         *bp++ = '\0';
-        ne_num++;
-    }
-
-    if (!(n = X509_NAME_new()))
-        goto error;
 
-    for (i = 0; i < ne_num; i++) {
-        if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
-            BIO_printf(bio_err,
-                       "Subject Attribute %s has no known NID, skipped\n",
-                       ne_types[i]);
-            continue;
-        }
+        /* If not at EOS (must be + or /), move forward. */
+        if (*cp)
+            ++cp;
 
-        if (!*ne_values[i]) {
-            BIO_printf(bio_err,
-                       "No value provided for Subject Attribute %s, skipped\n",
-                       ne_types[i]);
+        /* Parse */
+        nid = OBJ_txt2nid(typestr);
+        if (nid == NID_undef) {
+            BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n",
+                      opt_getprog(), typestr);
             continue;
         }
-
-        if (!X509_NAME_add_entry_by_NID
-            (n, nid, chtype, (unsigned char *)ne_values[i], -1, -1, mval[i]))
-            goto error;
+        if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+                                        valstr, strlen((char *)valstr),
+                                        -1, ismulti ? -1 : 0))
+            goto err;
     }
 
-    OPENSSL_free(ne_values);
-    OPENSSL_free(ne_types);
-    OPENSSL_free(buf);
-    OPENSSL_free(mval);
+    OPENSSL_free(work);
     return n;
 
- error:
+ err:
     X509_NAME_free(n);
-    if (ne_values)
-        OPENSSL_free(ne_values);
-    if (ne_types)
-        OPENSSL_free(ne_types);
-    if (mval)
-        OPENSSL_free(mval);
-    if (buf)
-        OPENSSL_free(buf);
+    OPENSSL_free(work);
     return NULL;
 }
 
@@ -2007,34 +1952,34 @@ int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
     return rv;
 }
 
-static void nodes_print(BIO *out, const char *name,
-                        STACK_OF(X509_POLICY_NODE) *nodes)
+static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
 {
     X509_POLICY_NODE *node;
     int i;
-    BIO_printf(out, "%s Policies:", name);
+
+    BIO_printf(bio_err, "%s Policies:", name);
     if (nodes) {
-        BIO_puts(out, "\n");
+        BIO_puts(bio_err, "\n");
         for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
             node = sk_X509_POLICY_NODE_value(nodes, i);
-            X509_POLICY_NODE_print(out, node, 2);
+            X509_POLICY_NODE_print(bio_err, node, 2);
         }
     } else
-        BIO_puts(out, " <empty>\n");
+        BIO_puts(bio_err, " <empty>\n");
 }
 
-void policies_print(BIO *out, X509_STORE_CTX *ctx)
+void policies_print(X509_STORE_CTX *ctx)
 {
     X509_POLICY_TREE *tree;
     int explicit_policy;
     tree = X509_STORE_CTX_get0_policy_tree(ctx);
     explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
 
-    BIO_printf(out, "Require explicit Policy: %s\n",
+    BIO_printf(bio_err, "Require explicit Policy: %s\n",
                explicit_policy ? "True" : "False");
 
-    nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
-    nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
+    nodes_print("Authority", X509_policy_tree_get0_policies(tree));
+    nodes_print("User", X509_policy_tree_get0_user_policies(tree));
 }
 
 #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
@@ -2284,10 +2229,7 @@ unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
     if (len >= 65535)
         return NULL;
 
-    out = OPENSSL_malloc(strlen(in) + 1);
-    if (!out)
-        return NULL;
-
+    out = app_malloc(strlen(in) + 1, "NPN buffer");
     for (i = 0; i <= len; ++i) {
         if (i == len || in[i] == ',') {
             if (i - start > 255) {
@@ -2674,6 +2616,45 @@ int app_access(const char* name, int flag)
 #endif
 }
 
+int app_hex(char c)
+{
+    switch (c) {
+    default:
+    case '0':
+        return 0;
+    case '1':
+        return 1;
+    case '2':
+        return 2;
+    case '3':
+        return 3;
+    case '4':
+          return 4;
+    case '5':
+          return 5;
+    case '6':
+          return 6;
+    case '7':
+          return 7;
+    case '8':
+          return 8;
+    case '9':
+          return 9;
+    case 'a': case 'A':
+          return 0x0A;
+    case 'b': case 'B':
+          return 0x0B;
+    case 'c': case 'C':
+          return 0x0C;
+    case 'd': case 'D':
+          return 0x0D;
+    case 'e': case 'E':
+          return 0x0E;
+    case 'f': case 'F':
+          return 0x0F;
+    }
+}
+
 /* app_isdir section */
 #ifdef _WIN32
 int app_isdir(const char *name)