Fix sigsize usage in apps/speed.c
[openssl.git] / apps / cmp.c
index f289943a555a5a1810b6e8cc9d4d651a2382d709..1c97075531d413ff17d42133c2864d1085191148 100644 (file)
@@ -643,10 +643,6 @@ static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc)
     return cert;
 }
 
-/*
- * TODO potentially move this and related functions to apps/lib/
- * or even better extend OSSL_STORE with type OSSL_STORE_INFO_CRL
- */
 static X509_REQ *load_csr_autofmt(const char *infile, const char *desc)
 {
     X509_REQ *csr;
@@ -733,7 +729,7 @@ static OSSL_CMP_MSG *read_PKIMESSAGE(char **filenames)
     file = *filenames;
     *filenames = next_item(file);
 
-    ret = OSSL_CMP_MSG_read(file);
+    ret = OSSL_CMP_MSG_read(file, app_get0_libctx(), app_get0_propq());
     if (ret == NULL)
         CMP_err1("cannot read PKIMessage from file '%s'", file);
     return ret;
@@ -840,11 +836,12 @@ static int set_gennames(OSSL_CMP_CTX *ctx, char *names, const char *desc)
             continue;
         }
 
-        /* try IP address first, then URI or domain name */
+        /* try IP address first, then email/URI/domain name */
         (void)ERR_set_mark();
         n = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_IPADD, names, 0);
         if (n == NULL)
             n = a2i_GENERAL_NAME(NULL, NULL, NULL,
+                                 strchr(names, '@') != NULL ? GEN_EMAIL :
                                  strchr(names, ':') != NULL ? GEN_URI : GEN_DNS,
                                  names, 0);
         (void)ERR_pop_to_mark();
@@ -875,7 +872,7 @@ static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc)
     if (X509_STORE_set1_param(ts, vpm /* may be NULL */)
             && (for_new_cert || truststore_set_host_etc(ts, NULL)))
         return ts;
-    BIO_printf(bio_err, "error setting verification parameters\n");
+    BIO_printf(bio_err, "error setting verification parameters for %s\n", desc);
     OSSL_CMP_CTX_print_errors(cmp_ctx);
     X509_STORE_free(ts);
     return NULL;
@@ -1051,7 +1048,6 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine)
         }
         X509_free(cert);
     }
-    /* TODO find a cleaner solution not requiring type casts */
     if (!setup_certs(opt_rsp_extracerts,
                      "CMP extra certificates for mock server", srv_ctx,
                      (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut))
@@ -1198,13 +1194,10 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host,
         return NULL;
 
     if (opt_tls_trusted != NULL) {
-        trust_store = load_certstore(opt_tls_trusted, opt_otherpass,
-                                     "trusted TLS certificates", vpm);
+        trust_store = load_trusted(opt_tls_trusted, 0, "trusted TLS certs");
         if (trust_store == NULL)
             goto err;
         SSL_CTX_set_cert_store(ssl_ctx, trust_store);
-        /* for improved diagnostics on SSL_CTX_build_cert_chain() errors: */
-        X509_STORE_set_verify_cb(trust_store, X509_STORE_CTX_print_verify_cb);
     }
 
     if (opt_tls_cert != NULL && opt_tls_key != NULL) {
@@ -1318,7 +1311,6 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, const char *host,
         /* enable and parameterize server hostname/IP address check */
         if (!truststore_set_host_etc(trust_store,
                                      opt_tls_host != NULL ? opt_tls_host : host))
-            /* TODO: is the server host name correct for TLS via proxy? */
             goto err;
         SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
     }
@@ -1771,8 +1763,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     int portnum, ssl;
     char server_buf[200] = { '\0' };
     char proxy_buf[200] = { '\0' };
-    char *proxy_host = NULL;
-    char *proxy_port_str = NULL;
+    const char *proxy_host = NULL;
 
     if (opt_server == NULL) {
         CMP_err("missing -server option");
@@ -1801,8 +1792,9 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
                        opt_tls_used ? "s" : "", host, port,
                        *used_path == '/' ? used_path + 1 : used_path);
 
-    if (opt_proxy != NULL)
-        (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", opt_proxy);
+    proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, ssl);
+    if (proxy_host != NULL)
+        (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host);
 
     if (!transform_opts())
         goto err;
@@ -1908,8 +1900,6 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine)
     OPENSSL_free(host);
     OPENSSL_free(port);
     OPENSSL_free(path);
-    OPENSSL_free(proxy_host);
-    OPENSSL_free(proxy_port_str);
     return ret;
  oom:
     CMP_err("out of memory");
@@ -2000,7 +1990,7 @@ static void print_itavs(STACK_OF(OSSL_CMP_ITAV) *itavs)
 }
 
 static char opt_item[SECTION_NAME_MAX + 1];
-/* get previous name from a comma-separated list of names */
+/* get previous name from a comma or space-separated list of names */
 static const char *prev_item(const char *opt, const char *end)
 {
     const char *beg;
@@ -2009,19 +1999,28 @@ static const char *prev_item(const char *opt, const char *end)
     if (end == opt)
         return NULL;
     beg = end;
-    while (beg != opt && beg[-1] != ',' && !isspace(beg[-1]))
-        beg--;
+    while (beg > opt) {
+        --beg;
+        if (beg[0] == ',' || isspace(beg[0])) {
+            ++beg;
+            break;
+        }
+    }
     len = end - beg;
-    if (len > SECTION_NAME_MAX)
+    if (len > SECTION_NAME_MAX) {
+        CMP_warn3("using only first %d characters of section name starting with \"%.*s\"",
+                  SECTION_NAME_MAX, SECTION_NAME_MAX, beg);
         len = SECTION_NAME_MAX;
-    strncpy(opt_item, beg, len);
-    opt_item[SECTION_NAME_MAX] = '\0'; /* avoid gcc v8 O3 stringop-truncation */
+    }
+    memcpy(opt_item, beg, len);
     opt_item[len] = '\0';
-    if (len > SECTION_NAME_MAX)
-        CMP_warn2("using only first %d characters of section name starting with \"%s\"",
-                  SECTION_NAME_MAX, opt_item);
-    while (beg != opt && (beg[-1] == ',' || isspace(beg[-1])))
-        beg--;
+    while (beg > opt) {
+        --beg;
+        if (beg[0] != ',' && !isspace(beg[0])) {
+            ++beg;
+            break;
+        }
+    }
     return beg;
 }
 
@@ -2552,6 +2551,84 @@ static int get_opts(int argc, char **argv)
     return 1;
 }
 
+#ifndef OPENSSL_NO_SOCK
+static int cmp_server(OSSL_CMP_CTX *srv_cmp_ctx) {
+    BIO *acbio;
+    BIO *cbio = NULL;
+    int keep_alive = 0;
+    int msgs = 0;
+    int retry = 1;
+    int ret = 1;
+
+    if ((acbio = http_server_init_bio(prog, opt_port)) == NULL)
+        return 0;
+    while (opt_max_msgs <= 0 || msgs < opt_max_msgs) {
+        char *path = NULL;
+        OSSL_CMP_MSG *req = NULL;
+        OSSL_CMP_MSG *resp = NULL;
+
+        ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG),
+                                       (ASN1_VALUE **)&req, &path,
+                                       &cbio, acbio, &keep_alive,
+                                       prog, opt_port, 0, 0);
+        if (ret == 0) { /* no request yet */
+            if (retry) {
+                ossl_sleep(1000);
+                retry = 0;
+                continue;
+            }
+            ret = 0;
+            goto next;
+        }
+        if (ret++ == -1) /* fatal error */
+            break;
+
+        ret = 0;
+        msgs++;
+        if (req != NULL) {
+            if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) {
+                (void)http_server_send_status(cbio, 404, "Not Found");
+                CMP_err1("expecting empty path or 'pkix/' but got '%s'",
+                         path);
+                OPENSSL_free(path);
+                OSSL_CMP_MSG_free(req);
+                goto next;
+            }
+            OPENSSL_free(path);
+            resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req);
+            OSSL_CMP_MSG_free(req);
+            if (resp == NULL) {
+                (void)http_server_send_status(cbio,
+                                              500, "Internal Server Error");
+                break; /* treated as fatal error */
+            }
+            ret = http_server_send_asn1_resp(cbio, keep_alive,
+                                             "application/pkixcmp",
+                                             ASN1_ITEM_rptr(OSSL_CMP_MSG),
+                                             (const ASN1_VALUE *)resp);
+            OSSL_CMP_MSG_free(resp);
+            if (!ret)
+                break; /* treated as fatal error */
+        }
+    next:
+        if (!ret) { /* on transmission error, cancel CMP transaction */
+            (void)OSSL_CMP_CTX_set1_transactionID(srv_cmp_ctx, NULL);
+            (void)OSSL_CMP_CTX_set1_senderNonce(srv_cmp_ctx, NULL);
+        }
+        if (!ret || !keep_alive
+            || OSSL_CMP_CTX_get_status(srv_cmp_ctx) == -1
+             /* transaction closed by OSSL_CMP_CTX_server_perform() */) {
+            BIO_free_all(cbio);
+            cbio = NULL;
+        }
+    }
+
+    BIO_free_all(cbio);
+    BIO_free_all(acbio);
+    return ret;
+}
+#endif
+
 int cmp_main(int argc, char **argv)
 {
     char *configfile = NULL;
@@ -2682,80 +2759,10 @@ int cmp_main(int argc, char **argv)
 
 
     if (opt_port != NULL) { /* act as very basic CMP HTTP server */
-        /* TODO for readability, convert this block to separate function */
 #ifdef OPENSSL_NO_SOCK
         BIO_printf(bio_err, "Cannot act as server - sockets not supported\n");
 #else
-        BIO *acbio;
-        BIO *cbio = NULL;
-        int keep_alive = 0;
-        int msgs = 0;
-        int retry = 1;
-
-        if ((acbio = http_server_init_bio(prog, opt_port)) == NULL)
-            goto err;
-        while (opt_max_msgs <= 0 || msgs < opt_max_msgs) {
-            char *path = NULL;
-            OSSL_CMP_MSG *req = NULL;
-            OSSL_CMP_MSG *resp = NULL;
-
-            ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG),
-                                           (ASN1_VALUE **)&req, &path,
-                                           &cbio, acbio, &keep_alive,
-                                           prog, opt_port, 0, 0);
-            if (ret == 0) { /* no request yet */
-                if (retry) {
-                    ossl_sleep(1000);
-                    retry = 0;
-                    continue;
-                }
-                ret = 0;
-                goto next;
-            }
-            if (ret++ == -1) /* fatal error */
-                break;
-
-            ret = 0;
-            msgs++;
-            if (req != NULL) {
-                if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) {
-                    (void)http_server_send_status(cbio, 404, "Not Found");
-                    CMP_err1("expecting empty path or 'pkix/' but got '%s'",
-                             path);
-                    OPENSSL_free(path);
-                    OSSL_CMP_MSG_free(req);
-                    goto next;
-                }
-                OPENSSL_free(path);
-                resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req);
-                OSSL_CMP_MSG_free(req);
-                if (resp == NULL) {
-                    (void)http_server_send_status(cbio,
-                                                  500, "Internal Server Error");
-                    break; /* treated as fatal error */
-                }
-                ret = http_server_send_asn1_resp(cbio, keep_alive,
-                                                 "application/pkixcmp",
-                                                 ASN1_ITEM_rptr(OSSL_CMP_MSG),
-                                                 (const ASN1_VALUE *)resp);
-                OSSL_CMP_MSG_free(resp);
-                if (!ret)
-                    break; /* treated as fatal error */
-            }
-        next:
-            if (!ret) { /* on transmission error, cancel CMP transaction */
-                (void)OSSL_CMP_CTX_set1_transactionID(srv_cmp_ctx, NULL);
-                (void)OSSL_CMP_CTX_set1_senderNonce(srv_cmp_ctx, NULL);
-            }
-            if (!ret || !keep_alive
-                || OSSL_CMP_CTX_get_status(srv_cmp_ctx) == -1
-                 /* transaction closed by OSSL_CMP_CTX_server_perform() */) {
-                BIO_free_all(cbio);
-                cbio = NULL;
-            }
-        }
-        BIO_free_all(cbio);
-        BIO_free_all(acbio);
+        ret = cmp_server(srv_cmp_ctx);
 #endif
         goto err;
     }