1 | /*
|
---|
2 | * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <string.h>
|
---|
11 | #include "apps.h"
|
---|
12 |
|
---|
13 | /*
|
---|
14 | * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to
|
---|
15 | * allow the application to process verification options in a manner similar
|
---|
16 | * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),
|
---|
17 | * for uniformity.
|
---|
18 | *
|
---|
19 | * As soon as more stuff is added, the code will need serious rework. For
|
---|
20 | * the moment, it only handles the FIPS 196 / SM2 distinguishing ID.
|
---|
21 | */
|
---|
22 | #ifdef EVP_PKEY_CTRL_SET1_ID
|
---|
23 | static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)
|
---|
24 | {
|
---|
25 | ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();
|
---|
26 |
|
---|
27 | if (v == NULL) {
|
---|
28 | BIO_printf(bio_err, "error: allocation failed\n");
|
---|
29 | } else if (!ASN1_OCTET_STRING_set(v, value, (int)value_n)) {
|
---|
30 | ASN1_OCTET_STRING_free(v);
|
---|
31 | v = NULL;
|
---|
32 | }
|
---|
33 | return v;
|
---|
34 | }
|
---|
35 | #endif
|
---|
36 |
|
---|
37 | static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)
|
---|
38 | {
|
---|
39 | switch (cmd) {
|
---|
40 | #ifdef EVP_PKEY_CTRL_SET1_ID
|
---|
41 | case EVP_PKEY_CTRL_SET1_ID:
|
---|
42 | {
|
---|
43 | ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
|
---|
44 |
|
---|
45 | if (v == NULL) {
|
---|
46 | BIO_printf(bio_err,
|
---|
47 | "error: setting distinguishing ID in certificate failed\n");
|
---|
48 | return 0;
|
---|
49 | }
|
---|
50 |
|
---|
51 | X509_set0_distinguishing_id(object, v);
|
---|
52 | return 1;
|
---|
53 | }
|
---|
54 | #endif
|
---|
55 | default:
|
---|
56 | break;
|
---|
57 | }
|
---|
58 | return -2; /* typical EVP_PKEY return for "unsupported" */
|
---|
59 | }
|
---|
60 |
|
---|
61 | static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)
|
---|
62 | {
|
---|
63 | switch (cmd) {
|
---|
64 | #ifdef EVP_PKEY_CTRL_SET1_ID
|
---|
65 | case EVP_PKEY_CTRL_SET1_ID:
|
---|
66 | {
|
---|
67 | ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
|
---|
68 |
|
---|
69 | if (v == NULL) {
|
---|
70 | BIO_printf(bio_err,
|
---|
71 | "error: setting distinguishing ID in certificate signing request failed\n");
|
---|
72 | return 0;
|
---|
73 | }
|
---|
74 |
|
---|
75 | X509_REQ_set0_distinguishing_id(object, v);
|
---|
76 | return 1;
|
---|
77 | }
|
---|
78 | #endif
|
---|
79 | default:
|
---|
80 | break;
|
---|
81 | }
|
---|
82 | return -2; /* typical EVP_PKEY return for "unsupported" */
|
---|
83 | }
|
---|
84 |
|
---|
85 | static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,
|
---|
86 | void *value, size_t value_n),
|
---|
87 | void *object, const char *value)
|
---|
88 | {
|
---|
89 | int rv = 0;
|
---|
90 | char *stmp, *vtmp = NULL;
|
---|
91 | size_t vtmp_len = 0;
|
---|
92 | int cmd = 0; /* Will get command values that make sense somehow */
|
---|
93 |
|
---|
94 | stmp = OPENSSL_strdup(value);
|
---|
95 | if (stmp == NULL)
|
---|
96 | return -1;
|
---|
97 | vtmp = strchr(stmp, ':');
|
---|
98 | if (vtmp != NULL) {
|
---|
99 | *vtmp = 0;
|
---|
100 | vtmp++;
|
---|
101 | vtmp_len = strlen(vtmp);
|
---|
102 | }
|
---|
103 |
|
---|
104 | if (strcmp(stmp, "distid") == 0) {
|
---|
105 | #ifdef EVP_PKEY_CTRL_SET1_ID
|
---|
106 | cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
|
---|
107 | #endif
|
---|
108 | } else if (strcmp(stmp, "hexdistid") == 0) {
|
---|
109 | if (vtmp != NULL) {
|
---|
110 | void *hexid;
|
---|
111 | long hexid_len = 0;
|
---|
112 |
|
---|
113 | hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);
|
---|
114 | OPENSSL_free(stmp);
|
---|
115 | stmp = vtmp = hexid;
|
---|
116 | vtmp_len = (size_t)hexid_len;
|
---|
117 | }
|
---|
118 | #ifdef EVP_PKEY_CTRL_SET1_ID
|
---|
119 | cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
|
---|
120 | #endif
|
---|
121 | }
|
---|
122 |
|
---|
123 | rv = ctrl(object, cmd, vtmp, vtmp_len);
|
---|
124 |
|
---|
125 | OPENSSL_free(stmp);
|
---|
126 | return rv;
|
---|
127 | }
|
---|
128 |
|
---|
129 | int x509_ctrl_string(X509 *x, const char *value)
|
---|
130 | {
|
---|
131 | return do_x509_ctrl_string(x509_ctrl, x, value);
|
---|
132 | }
|
---|
133 |
|
---|
134 | int x509_req_ctrl_string(X509_REQ *x, const char *value)
|
---|
135 | {
|
---|
136 | return do_x509_ctrl_string(x509_req_ctrl, x, value);
|
---|
137 | }
|
---|