Skip to content

Commit 2137125

Browse files
committed
x509storeissuer: provide the initial infrstructure for nonce configuration
Signed-off-by: Eugene Syromiatnikov <[email protected]>
1 parent 3c881af commit 2137125

File tree

1 file changed

+144
-24
lines changed

1 file changed

+144
-24
lines changed

source/x509storeissuer.c

Lines changed: 144 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
* https://www.openssl.org/source/license.html
88
*/
99

10-
#include <stdlib.h>
10+
#include <stdbool.h>
1111
#include <stdio.h>
12+
#include <stdlib.h>
1213
#include <string.h>
1314
#ifndef _WIN32
1415
# include <libgen.h>
@@ -24,23 +25,116 @@
2425
#include "perflib/perflib.h"
2526

2627
#define RUN_TIME 5
28+
#define NONCE_CFG "file:servercert.pem"
29+
30+
enum nonce_type {
31+
NONCE_PATH,
32+
};
33+
34+
struct nonce_cfg {
35+
enum nonce_type type;
36+
const char *path;
37+
char **dirs;
38+
size_t num_dirs;
39+
};
2740

2841
static int error = 0;
2942
static X509_STORE *store = NULL;
30-
static X509 *x509 = NULL;
43+
static X509 *x509_nonce = NULL;
3144

3245
static int threadcount;
3346

3447
size_t *counts;
3548
OSSL_TIME max_time;
3649

50+
static X509 *
51+
load_nonce_from_file(const char *path)
52+
{
53+
BIO *bio = BIO_new_file(path, "rb");
54+
X509 *x509_nonce = NULL;
55+
56+
if (bio == NULL) {
57+
warnx("Unable to create BIO for reading \"%s\"", path);
58+
return NULL;
59+
}
60+
61+
x509_nonce = PEM_read_bio_X509(bio, NULL, NULL, NULL);
62+
if (x509_nonce == NULL)
63+
warnx("Failed to read certificate \"%s\"", path);
64+
65+
BIO_free(bio);
66+
67+
return x509_nonce;
68+
}
69+
70+
static bool
71+
is_abs_path(const char *path)
72+
{
73+
if (path == NULL)
74+
return false;
75+
76+
#if defined(_WIN32)
77+
/*
78+
* So, we don't try to concatenate the provided path with the directory
79+
* paths if the path start with the following:
80+
* - volume character and a colon ("C:"): it is either absolute path
81+
* (if followed by a backslash), or a relative path to a current
82+
* directory of that volume (and we don't want to implement any logic
83+
* that handles that);
84+
* - backslash ("\"): it is an "absolute path" on the "current" drive,
85+
* or (if there are two backslashes in the beginning) an UNC path.
86+
*/
87+
return (isalpha(path[0]) && path[1] == ':') || path[0] == '\\';
88+
#else /* !_WIN32 */
89+
return path[0] == '/';
90+
#endif
91+
}
92+
93+
static X509 *
94+
load_nonce_from_path(struct nonce_cfg *cfg)
95+
{
96+
if (is_abs_path(cfg->path))
97+
return load_nonce_from_file(cfg->path);
98+
99+
for (size_t i = 0; i < cfg->num_dirs; i++) {
100+
char *cert;
101+
X509 *ret;
102+
103+
cert = perflib_mk_file_path(cfg->dirs[i], cfg->path);
104+
if (cert == NULL) {
105+
warnx("Failed to allocate file path for directory \"%s\""
106+
" and path \"%s\"", cfg->dirs[i], cfg->path);
107+
continue;
108+
}
109+
110+
ret = load_nonce_from_file(cert);
111+
OPENSSL_free(cert);
112+
113+
if (ret != NULL)
114+
return ret;
115+
}
116+
117+
return NULL;
118+
}
119+
120+
static X509 *
121+
make_nonce(struct nonce_cfg *cfg)
122+
{
123+
switch (cfg->type) {
124+
case NONCE_PATH:
125+
return load_nonce_from_path(cfg);
126+
default:
127+
errx(EXIT_FAILURE, "Unknown nonce type: %lld", (long long) cfg->type);
128+
}
129+
}
130+
37131
static void do_x509storeissuer(size_t num)
38132
{
39133
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
40134
X509 *issuer = NULL;
41135
OSSL_TIME time;
42136

43-
if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, x509, NULL)) {
137+
if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, x509_nonce, NULL)) {
44138
warnx("Failed to initialise X509_STORE_CTX");
45139
error = 1;
46140
goto err;
@@ -54,7 +148,7 @@ static void do_x509storeissuer(size_t num)
54148
* certificates inside our store. We're just testing calling this
55149
* against an empty store.
56150
*/
57-
if (X509_STORE_CTX_get1_issuer(&issuer, ctx, x509) != 0) {
151+
if (X509_STORE_CTX_get1_issuer(&issuer, ctx, x509_nonce) != 0) {
58152
warnx("Unexpected result from X509_STORE_CTX_get1_issuer");
59153
error = 1;
60154
X509_free(issuer);
@@ -73,9 +167,32 @@ static void
73167
usage(char * const argv[])
74168
{
75169
fprintf(stderr,
76-
"Usage: %s [-t] certsdir threadcount\n"
77-
"-t - terse output\n",
78-
basename(argv[0]));
170+
"Usage: %s [-t] [-n nonce_type:type_args] certsdir threadcount\n"
171+
"\t-t\tTerse output\n"
172+
"\t-n\tNonce configuration, supported options:\n"
173+
"\t\t\tfile:PATH - load nonce certificate from PATH;\n"
174+
"\t\t\tif PATH is relative, the provided certsdir's are searched.\n"
175+
"\t\tDefault: " NONCE_CFG "\n"
176+
, basename(argv[0]));
177+
}
178+
179+
/**
180+
* Parse nonce configuration string. Currently supported formats:
181+
* * "file:PATH" - where PATH is either a relative path (that will be then
182+
* checked against the list of directories provided),
183+
* or an absolute one.
184+
*/
185+
static void
186+
parse_nonce_cfg(const char * const optarg, struct nonce_cfg *cfg)
187+
{
188+
static const char file_pfx[] = "file:";
189+
190+
if (strncmp(optarg, file_pfx, sizeof(file_pfx) - 1) == 0) {
191+
cfg->type = NONCE_PATH;
192+
cfg->path = optarg + sizeof(file_pfx) - 1;
193+
} else {
194+
errx(EXIT_FAILURE, "incorrect nonce configuration: \"%s\"", optarg);
195+
}
79196
}
80197

81198
static long long
@@ -106,12 +223,19 @@ int main(int argc, char *argv[])
106223
int ret = EXIT_FAILURE;
107224
BIO *bio = NULL;
108225
int opt;
226+
int dirs_start;
227+
struct nonce_cfg nonce_cfg;
109228

110-
while ((opt = getopt(argc, argv, "t")) != -1) {
229+
parse_nonce_cfg(NONCE_CFG, &nonce_cfg);
230+
231+
while ((opt = getopt(argc, argv, "tn:")) != -1) {
111232
switch (opt) {
112233
case 't':
113234
terse = 1;
114235
break;
236+
case 'n': /* nonce */
237+
parse_nonce_cfg(optarg, &nonce_cfg);
238+
break;
115239
default:
116240
usage(argv);
117241
return EXIT_FAILURE;
@@ -121,11 +245,14 @@ int main(int argc, char *argv[])
121245
if (argv[optind] == NULL)
122246
errx(EXIT_FAILURE, "certsdir is missing");
123247

124-
cert = perflib_mk_file_path(argv[optind], "servercert.pem");
125-
if (cert == NULL)
126-
errx(EXIT_FAILURE, "Failed to allocate cert path");
248+
dirs_start = optind++;
127249

128-
optind++;
250+
/*
251+
* Store the part of argv containing directories to nonce_cfg so
252+
* load_nonce_from_path can use it later.
253+
*/
254+
nonce_cfg.dirs = argv + dirs_start;
255+
nonce_cfg.num_dirs = 1;
129256

130257
if (argv[optind] == NULL)
131258
errx(EXIT_FAILURE, "threadcount is missing");
@@ -136,21 +263,14 @@ int main(int argc, char *argv[])
136263
if (store == NULL || !X509_STORE_set_default_paths(store))
137264
errx(EXIT_FAILURE, "Failed to create X509_STORE");
138265

139-
bio = BIO_new_file(cert, "rb");
140-
if (bio == NULL)
141-
errx(EXIT_FAILURE, "Unable to load certificate\n");
142-
143-
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
144-
if (x509 == NULL)
145-
errx(EXIT_FAILURE, "Failed to read certificate");
146-
147-
BIO_free(bio);
148-
bio = NULL;
149-
150266
counts = OPENSSL_malloc(sizeof(size_t) * threadcount);
151267
if (counts == NULL)
152268
errx(EXIT_FAILURE, "Failed to create counts array");
153269

270+
x509_nonce = make_nonce(&nonce_cfg);
271+
if (x509_nonce == NULL)
272+
errx(EXIT_FAILURE, "Unable to create the nonce X509 object");
273+
154274
max_time = ossl_time_add(ossl_time_now(), ossl_seconds2time(RUN_TIME));
155275

156276
if (!perflib_run_multi_thread_test(do_x509storeissuer, threadcount, &duration))
@@ -173,8 +293,8 @@ int main(int argc, char *argv[])
173293
ret = EXIT_SUCCESS;
174294

175295
err:
296+
X509_free(x509_nonce);
176297
X509_STORE_free(store);
177-
X509_free(x509);
178298
BIO_free(bio);
179299
OPENSSL_free(cert);
180300
OPENSSL_free(counts);

0 commit comments

Comments
 (0)