void policies_print(X509_STORE_CTX *ctx);
int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value);
+int x509_ctrl_string(X509 *x, const char *value);
+int x509_req_ctrl_string(X509_REQ *x, const char *value);
int init_gen_str(EVP_PKEY_CTX **pctx,
const char *algname, ENGINE *e, int do_param);
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *vfyopts);
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
--- /dev/null
+/*
+ * 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);
+}
return 1;
}
+static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
+{
+ int i;
+
+ if (opts == NULL)
+ return 1;
+
+ for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
+ char *opt = sk_OPENSSL_STRING_value(opts, i);
+ if (x509_req_ctrl_string(x, opt) <= 0) {
+ BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
+ ERR_print_errors(bio_err);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
{
return rv;
}
+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
+ STACK_OF(OPENSSL_STRING) *vfyopts)
+{
+ int rv = 0;
+
+ if (do_x509_req_init(x, vfyopts) > 0)
+ rv = (X509_REQ_verify(x, pkey) > 0);
+ return rv;
+}
+
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts)
{