summaryrefslogtreecommitdiffstats
path: root/apps/lib
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-03-10 23:05:09 +0100
committerRichard Levitte <levitte@openssl.org>2020-03-15 19:42:05 +0100
commitaba9bca31cc2507671e25f7ca8e642fce5e38671 (patch)
tree1dcd6610e75b63febebb074923b58bd71dbb1c70 /apps/lib
parent123c2fef14b80f26f5a8504ccf7b819c2975a6fa (diff)
APPS: Add ctrl_str()-like functionality for X509 and X509_REQ
This should really be part of libcrypto, but since this looks like added legacy support, it's preferable to keep it in apps for now. This allows to build functions that add user given verification options to X509 and X509_REQ structures. Fixes #11293 Reviewed-by: Paul Yang <kaishen.yy@antfin.com> (Merged from https://github.com/openssl/openssl/pull/11302)
Diffstat (limited to 'apps/lib')
-rw-r--r--apps/lib/app_x509.c134
-rw-r--r--apps/lib/build.info2
2 files changed, 135 insertions, 1 deletions
diff --git a/apps/lib/app_x509.c b/apps/lib/app_x509.c
new file mode 100644
index 0000000000..89c5960fa6
--- /dev/null
+++ b/apps/lib/app_x509.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include "apps.h"
+
+/*
+ * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to
+ * allow the application to process verification options in a manner similar
+ * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),
+ * for uniformity.
+ *
+ * As soon as more stuff is added, the code will need serious rework. For
+ * the moment, it only handles the FIPS 196 / SM2 distinguishing ID.
+ */
+#ifdef EVP_PKEY_CTRL_SET1_ID
+static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)
+{
+ ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();
+
+ if (v == NULL) {
+ BIO_printf(bio_err, "error: allocation failed\n");
+ } else if (!ASN1_OCTET_STRING_set(v, value, value_n)) {
+ ASN1_OCTET_STRING_free(v);
+ v = NULL;
+ }
+ return v;
+}
+#endif
+
+static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)
+{
+ switch (cmd) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+ case EVP_PKEY_CTRL_SET1_ID:
+ {
+ ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
+
+ if (v == NULL) {
+ BIO_printf(bio_err,
+ "error: setting distinguishing ID in certificate failed\n");
+ return 0;
+ }
+
+ X509_set0_distinguishing_id(object, v);
+ return 1;
+ }
+#endif
+ default:
+ break;
+ }
+ return -2; /* typical EVP_PKEY return for "unsupported" */
+}
+
+static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)
+{
+ switch (cmd) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+ case EVP_PKEY_CTRL_SET1_ID:
+ {
+ ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
+
+ if (v == NULL) {
+ BIO_printf(bio_err,
+ "error: setting distinguishing ID in certificate signing request failed\n");
+ return 0;
+ }
+
+ X509_REQ_set0_distinguishing_id(object, v);
+ return 1;
+ }
+#endif
+ default:
+ break;
+ }
+ return -2; /* typical EVP_PKEY return for "unsupported" */
+}
+
+static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,
+ void *value, size_t value_n),
+ void *object, const char *value)
+{
+ int rv = 0;
+ char *stmp, *vtmp = NULL;
+ size_t vtmp_len = 0;
+ int cmd = 0; /* Will get command values that make sense somehow */
+
+ stmp = OPENSSL_strdup(value);
+ if (stmp == NULL)
+ return -1;
+ vtmp = strchr(stmp, ':');
+ if (vtmp != NULL) {
+ *vtmp = 0;
+ vtmp++;
+ vtmp_len = strlen(vtmp);
+ }
+
+ if (strcmp(stmp, "distid") == 0) {
+#ifdef EVP_PKEY_CTRL_SET1_ID
+ cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
+#endif
+ } else if (strcmp(stmp, "hexdistid") == 0) {
+ long hexid_len = 0;
+ void *hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);
+
+ OPENSSL_free(stmp);
+ stmp = vtmp = hexid;
+ vtmp_len = (size_t)hexid_len;
+#ifdef EVP_PKEY_CTRL_SET1_ID
+ cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
+#endif
+ }
+
+ rv = ctrl(object, cmd, vtmp, vtmp_len);
+
+ OPENSSL_free(stmp);
+ return rv;
+}
+
+int x509_ctrl_string(X509 *x, const char *value)
+{
+ return do_x509_ctrl_string(x509_ctrl, x, value);
+}
+
+int x509_req_ctrl_string(X509_REQ *x, const char *value)
+{
+ return do_x509_ctrl_string(x509_req_ctrl, x, value);
+}
diff --git a/apps/lib/build.info b/apps/lib/build.info
index a7be58b101..129ffce933 100644
--- a/apps/lib/build.info
+++ b/apps/lib/build.info
@@ -9,7 +9,7 @@ ENDIF
# Source for libapps
$LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
- columns.c app_params.c names.c app_provider.c
+ columns.c app_params.c names.c app_provider.c app_x509.c
IF[{- !$disabled{apps} -}]
LIBS{noinst}=../libapps.a