138 lines
3.8 KiB
C
138 lines
3.8 KiB
C
|
/*
|
||
|
* Copyright 2020-2021 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, (int)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) {
|
||
|
if (vtmp != NULL) {
|
||
|
void *hexid;
|
||
|
long hexid_len = 0;
|
||
|
|
||
|
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);
|
||
|
}
|