Path: blob/main/crypto/openssl/apps/lib/app_x509.c
105221 views
/*1* Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include "apps.h"1112/*13* X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to14* allow the application to process verification options in a manner similar15* to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),16* for uniformity.17*18* As soon as more stuff is added, the code will need serious rework. For19* the moment, it only handles the FIPS 196 / SM2 distinguishing ID.20*/21#ifdef EVP_PKEY_CTRL_SET1_ID22static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)23{24ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();2526if (v == NULL) {27BIO_printf(bio_err, "error: allocation failed\n");28} else if (!ASN1_OCTET_STRING_set(v, value, (int)value_n)) {29ASN1_OCTET_STRING_free(v);30v = NULL;31}32return v;33}34#endif3536static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)37{38switch (cmd) {39#ifdef EVP_PKEY_CTRL_SET1_ID40case EVP_PKEY_CTRL_SET1_ID: {41ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);4243if (v == NULL) {44BIO_printf(bio_err,45"error: setting distinguishing ID in certificate failed\n");46return 0;47}4849X509_set0_distinguishing_id(object, v);50return 1;51}52#endif53default:54break;55}56return -2; /* typical EVP_PKEY return for "unsupported" */57}5859static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)60{61switch (cmd) {62#ifdef EVP_PKEY_CTRL_SET1_ID63case EVP_PKEY_CTRL_SET1_ID: {64ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);6566if (v == NULL) {67BIO_printf(bio_err,68"error: setting distinguishing ID in certificate signing request failed\n");69return 0;70}7172X509_REQ_set0_distinguishing_id(object, v);73return 1;74}75#endif76default:77break;78}79return -2; /* typical EVP_PKEY return for "unsupported" */80}8182static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,83void *value, size_t value_n),84void *object, const char *value)85{86int rv = 0;87char *stmp, *vtmp = NULL;88size_t vtmp_len = 0;89int cmd = 0; /* Will get command values that make sense somehow */9091stmp = OPENSSL_strdup(value);92if (stmp == NULL)93return -1;94vtmp = strchr(stmp, ':');95if (vtmp != NULL) {96*vtmp = 0;97vtmp++;98vtmp_len = strlen(vtmp);99}100101if (strcmp(stmp, "distid") == 0) {102#ifdef EVP_PKEY_CTRL_SET1_ID103cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */104#endif105} else if (strcmp(stmp, "hexdistid") == 0) {106if (vtmp != NULL) {107void *hexid;108long hexid_len = 0;109110hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);111OPENSSL_free(stmp);112stmp = vtmp = hexid;113vtmp_len = (size_t)hexid_len;114}115#ifdef EVP_PKEY_CTRL_SET1_ID116cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */117#endif118}119120rv = ctrl(object, cmd, vtmp, vtmp_len);121122OPENSSL_free(stmp);123return rv;124}125126int x509_ctrl_string(X509 *x, const char *value)127{128return do_x509_ctrl_string(x509_ctrl, x, value);129}130131int x509_req_ctrl_string(X509_REQ *x, const char *value)132{133return do_x509_ctrl_string(x509_req_ctrl, x, value);134}135136137