2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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
13 #include <openssl/crypto.h>
14 #include <openssl/err.h>
15 #include <openssl/store.h>
16 #include "internal/thread_once.h"
17 #include "store_locl.h"
19 struct ossl_store_ctx_st {
20 const OSSL_STORE_LOADER *loader;
21 OSSL_STORE_LOADER_CTX *loader_ctx;
22 const UI_METHOD *ui_method;
24 OSSL_STORE_post_process_info_fn post_process;
25 void *post_process_data;
28 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
30 OSSL_STORE_post_process_info_fn post_process,
31 void *post_process_data)
33 const OSSL_STORE_LOADER *loader;
34 OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
35 OSSL_STORE_CTX *ctx = NULL;
36 char scheme_copy[256], *p;
38 OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
39 if ((p = strchr(scheme_copy, ':')) != NULL) {
46 if ((loader = ossl_store_get0_loader_int(p)) == NULL
47 || (loader_ctx = loader->open(loader, uri, ui_method, ui_data)) == NULL)
49 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
50 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
55 ctx->loader_ctx = loader_ctx;
57 ctx->ui_method = ui_method;
58 ctx->ui_data = ui_data;
59 ctx->post_process = post_process;
60 ctx->post_process_data = post_process_data;
63 if (loader_ctx != NULL) {
65 * We ignore a returned error because we will return NULL anyway in
66 * this case, so if something goes wrong when closing, that'll simply
67 * just add another entry on the error stack.
69 (void)loader->close(loader_ctx);
74 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
80 if (ctx->loader->ctrl != NULL)
81 ret = ctx->loader->ctrl(ctx->loader_ctx, cmd, args);
87 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
89 OSSL_STORE_INFO *v = NULL;
92 v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data);
94 if (ctx->post_process != NULL && v != NULL) {
95 v = ctx->post_process(v, ctx->post_process_data);
98 * By returning NULL, the callback decides that this object should
108 int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
110 return ctx->loader->error(ctx->loader_ctx);
113 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
115 return ctx->loader->eof(ctx->loader_ctx);
118 int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
120 int loader_ret = ctx->loader->close(ctx->loader_ctx);
127 * Functions to generate OSSL_STORE_INFOs, one function for each type we
128 * support having in them. Along with each of them, one macro that
129 * can be used to determine what types are supported.
131 * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
132 * and will therefore be freed when the OSSL_STORE_INFO is freed.
134 static OSSL_STORE_INFO *store_info_new(int type, void *data)
136 OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));
146 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
148 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL);
151 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME,
152 ERR_R_MALLOC_FAILURE);
156 info->_.name.name = name;
157 info->_.name.desc = NULL;
162 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
164 if (info->type != OSSL_STORE_INFO_NAME) {
165 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION,
166 ERR_R_PASSED_INVALID_ARGUMENT);
170 info->_.name.desc = desc;
174 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
176 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params);
179 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS,
180 ERR_R_MALLOC_FAILURE);
184 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
186 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey);
189 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY,
190 ERR_R_MALLOC_FAILURE);
194 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
196 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509);
199 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT,
200 ERR_R_MALLOC_FAILURE);
204 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
206 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl);
209 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL,
210 ERR_R_MALLOC_FAILURE);
215 * Functions to try to extract data from a OSSL_STORE_INFO.
217 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
222 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
224 if (info->type == OSSL_STORE_INFO_NAME)
225 return info->_.name.name;
229 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info)
231 if (info->type == OSSL_STORE_INFO_NAME) {
232 char *ret = OPENSSL_strdup(info->_.name.name);
235 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
236 ERR_R_MALLOC_FAILURE);
239 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
240 OSSL_STORE_R_NOT_A_NAME);
244 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info)
246 if (info->type == OSSL_STORE_INFO_NAME)
247 return info->_.name.desc;
251 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info)
253 if (info->type == OSSL_STORE_INFO_NAME) {
254 char *ret = OPENSSL_strdup(info->_.name.desc
255 ? info->_.name.desc : "");
258 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
259 ERR_R_MALLOC_FAILURE);
262 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
263 OSSL_STORE_R_NOT_A_NAME);
267 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
269 if (info->type == OSSL_STORE_INFO_PARAMS)
270 return info->_.params;
274 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
276 if (info->type == OSSL_STORE_INFO_PARAMS) {
277 EVP_PKEY_up_ref(info->_.params);
278 return info->_.params;
280 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS,
281 OSSL_STORE_R_NOT_PARAMETERS);
285 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
287 if (info->type == OSSL_STORE_INFO_PKEY)
292 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
294 if (info->type == OSSL_STORE_INFO_PKEY) {
295 EVP_PKEY_up_ref(info->_.pkey);
298 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY,
299 OSSL_STORE_R_NOT_A_KEY);
303 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
305 if (info->type == OSSL_STORE_INFO_CERT)
310 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
312 if (info->type == OSSL_STORE_INFO_CERT) {
313 X509_up_ref(info->_.x509);
316 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT,
317 OSSL_STORE_R_NOT_A_CERTIFICATE);
321 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
323 if (info->type == OSSL_STORE_INFO_CRL)
328 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
330 if (info->type == OSSL_STORE_INFO_CRL) {
331 X509_CRL_up_ref(info->_.crl);
334 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL,
335 OSSL_STORE_R_NOT_A_CRL);
340 * Free the OSSL_STORE_INFO
342 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
345 switch (info->type) {
346 case OSSL_STORE_INFO_EMBEDDED:
347 BUF_MEM_free(info->_.embedded.blob);
348 OPENSSL_free(info->_.embedded.pem_name);
350 case OSSL_STORE_INFO_NAME:
351 OPENSSL_free(info->_.name.name);
352 OPENSSL_free(info->_.name.desc);
354 case OSSL_STORE_INFO_PARAMS:
355 EVP_PKEY_free(info->_.params);
357 case OSSL_STORE_INFO_PKEY:
358 EVP_PKEY_free(info->_.pkey);
360 case OSSL_STORE_INFO_CERT:
361 X509_free(info->_.x509);
363 case OSSL_STORE_INFO_CRL:
364 X509_CRL_free(info->_.crl);
371 /* Internal functions */
372 OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
375 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
378 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
379 ERR_R_MALLOC_FAILURE);
383 info->_.embedded.blob = embedded;
384 info->_.embedded.pem_name =
385 new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
387 if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
388 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
389 ERR_R_MALLOC_FAILURE);
390 OSSL_STORE_INFO_free(info);
397 BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
399 if (info->type == OSSL_STORE_INFO_EMBEDDED)
400 return info->_.embedded.blob;
404 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
406 if (info->type == OSSL_STORE_INFO_EMBEDDED)
407 return info->_.embedded.pem_name;