Add internal functions to fetch PEM data from an opened BIO
[oweals/openssl.git] / crypto / store / store_lib.c
1 /*
2  * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include <openssl/crypto.h>
14 #include <openssl/err.h>
15 #include <openssl/store.h>
16 #include "internal/thread_once.h"
17 #include "internal/store_int.h"
18 #include "store_locl.h"
19
20 struct ossl_store_ctx_st {
21     const OSSL_STORE_LOADER *loader;
22     OSSL_STORE_LOADER_CTX *loader_ctx;
23     const UI_METHOD *ui_method;
24     void *ui_data;
25     OSSL_STORE_post_process_info_fn post_process;
26     void *post_process_data;
27 };
28
29 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
30                                 void *ui_data,
31                                 OSSL_STORE_post_process_info_fn post_process,
32                                 void *post_process_data)
33 {
34     const OSSL_STORE_LOADER *loader;
35     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
36     OSSL_STORE_CTX *ctx = NULL;
37     char scheme_copy[256], *p;
38
39     OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
40     if ((p = strchr(scheme_copy, ':')) != NULL) {
41         *p = '\0';
42         p = scheme_copy;
43     } else {
44         p = "file";
45     }
46
47     if ((loader = ossl_store_get0_loader_int(p)) == NULL
48         || (loader_ctx = loader->open(loader, uri, ui_method, ui_data)) == NULL)
49         goto done;
50     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
51         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
52         goto done;
53     }
54
55     ctx->loader = loader;
56     ctx->loader_ctx = loader_ctx;
57     loader_ctx = NULL;
58     ctx->ui_method = ui_method;
59     ctx->ui_data = ui_data;
60     ctx->post_process = post_process;
61     ctx->post_process_data = post_process_data;
62
63  done:
64     if (loader_ctx != NULL) {
65         /*
66          * We ignore a returned error because we will return NULL anyway in
67          * this case, so if something goes wrong when closing, that'll simply
68          * just add another entry on the error stack.
69          */
70         (void)loader->close(loader_ctx);
71     }
72     return ctx;
73 }
74
75 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...)
76 {
77     va_list args;
78     int ret = 0;
79
80     va_start(args, cmd);
81     if (ctx->loader->ctrl != NULL)
82         ret = ctx->loader->ctrl(ctx->loader_ctx, cmd, args);
83     va_end(args);
84
85     return ret;
86 }
87
88 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
89 {
90     OSSL_STORE_INFO *v = NULL;
91
92  again:
93     v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data);
94
95     if (ctx->post_process != NULL && v != NULL) {
96         v = ctx->post_process(v, ctx->post_process_data);
97
98         /*
99          * By returning NULL, the callback decides that this object should
100          * be ignored.
101          */
102         if (v == NULL)
103             goto again;
104     }
105
106     return v;
107 }
108
109 int OSSL_STORE_error(OSSL_STORE_CTX *ctx)
110 {
111     return ctx->loader->error(ctx->loader_ctx);
112 }
113
114 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)
115 {
116     return ctx->loader->eof(ctx->loader_ctx);
117 }
118
119 int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
120 {
121     int loader_ret = ctx->loader->close(ctx->loader_ctx);
122
123     OPENSSL_free(ctx);
124     return loader_ret;
125 }
126
127 /*
128  * Functions to generate OSSL_STORE_INFOs, one function for each type we
129  * support having in them.  Along with each of them, one macro that
130  * can be used to determine what types are supported.
131  *
132  * In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
133  * and will therefore be freed when the OSSL_STORE_INFO is freed.
134  */
135 static OSSL_STORE_INFO *store_info_new(int type, void *data)
136 {
137     OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));
138
139     if (info == NULL)
140         return NULL;
141
142     info->type = type;
143     info->_.data = data;
144     return info;
145 }
146
147 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
148 {
149     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL);
150
151     if (info == NULL) {
152         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME,
153                       ERR_R_MALLOC_FAILURE);
154         return NULL;
155     }
156
157     info->_.name.name = name;
158     info->_.name.desc = NULL;
159
160     return info;
161 }
162
163 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
164 {
165     if (info->type != OSSL_STORE_INFO_NAME) {
166         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION,
167                       ERR_R_PASSED_INVALID_ARGUMENT);
168         return 0;
169     }
170
171     info->_.name.desc = desc;
172
173     return 1;
174 }
175 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
176 {
177     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params);
178
179     if (info == NULL)
180         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS,
181                       ERR_R_MALLOC_FAILURE);
182     return info;
183 }
184
185 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
186 {
187     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey);
188
189     if (info == NULL)
190         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY,
191                       ERR_R_MALLOC_FAILURE);
192     return info;
193 }
194
195 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
196 {
197     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509);
198
199     if (info == NULL)
200         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT,
201                       ERR_R_MALLOC_FAILURE);
202     return info;
203 }
204
205 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
206 {
207     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl);
208
209     if (info == NULL)
210         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL,
211                       ERR_R_MALLOC_FAILURE);
212     return info;
213 }
214
215 /*
216  * Functions to try to extract data from a OSSL_STORE_INFO.
217  */
218 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
219 {
220     return info->type;
221 }
222
223 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
224 {
225     if (info->type == OSSL_STORE_INFO_NAME)
226         return info->_.name.name;
227     return NULL;
228 }
229
230 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info)
231 {
232     if (info->type == OSSL_STORE_INFO_NAME) {
233         char *ret = OPENSSL_strdup(info->_.name.name);
234
235         if (ret == NULL)
236             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
237                           ERR_R_MALLOC_FAILURE);
238         return ret;
239     }
240     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME,
241                   OSSL_STORE_R_NOT_A_NAME);
242     return NULL;
243 }
244
245 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info)
246 {
247     if (info->type == OSSL_STORE_INFO_NAME)
248         return info->_.name.desc;
249     return NULL;
250 }
251
252 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info)
253 {
254     if (info->type == OSSL_STORE_INFO_NAME) {
255         char *ret = OPENSSL_strdup(info->_.name.desc
256                                    ? info->_.name.desc : "");
257
258         if (ret == NULL)
259             OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
260                      ERR_R_MALLOC_FAILURE);
261         return ret;
262     }
263     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION,
264                   OSSL_STORE_R_NOT_A_NAME);
265     return NULL;
266 }
267
268 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
269 {
270     if (info->type == OSSL_STORE_INFO_PARAMS)
271         return info->_.params;
272     return NULL;
273 }
274
275 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
276 {
277     if (info->type == OSSL_STORE_INFO_PARAMS) {
278         EVP_PKEY_up_ref(info->_.params);
279         return info->_.params;
280     }
281     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS,
282                   OSSL_STORE_R_NOT_PARAMETERS);
283     return NULL;
284 }
285
286 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
287 {
288     if (info->type == OSSL_STORE_INFO_PKEY)
289         return info->_.pkey;
290     return NULL;
291 }
292
293 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
294 {
295     if (info->type == OSSL_STORE_INFO_PKEY) {
296         EVP_PKEY_up_ref(info->_.pkey);
297         return info->_.pkey;
298     }
299     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY,
300                   OSSL_STORE_R_NOT_A_KEY);
301     return NULL;
302 }
303
304 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
305 {
306     if (info->type == OSSL_STORE_INFO_CERT)
307         return info->_.x509;
308     return NULL;
309 }
310
311 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
312 {
313     if (info->type == OSSL_STORE_INFO_CERT) {
314         X509_up_ref(info->_.x509);
315         return info->_.x509;
316     }
317     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT,
318                   OSSL_STORE_R_NOT_A_CERTIFICATE);
319     return NULL;
320 }
321
322 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
323 {
324     if (info->type == OSSL_STORE_INFO_CRL)
325         return info->_.crl;
326     return NULL;
327 }
328
329 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
330 {
331     if (info->type == OSSL_STORE_INFO_CRL) {
332         X509_CRL_up_ref(info->_.crl);
333         return info->_.crl;
334     }
335     OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL,
336                   OSSL_STORE_R_NOT_A_CRL);
337     return NULL;
338 }
339
340 /*
341  * Free the OSSL_STORE_INFO
342  */
343 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
344 {
345     if (info != NULL) {
346         switch (info->type) {
347         case OSSL_STORE_INFO_EMBEDDED:
348             BUF_MEM_free(info->_.embedded.blob);
349             OPENSSL_free(info->_.embedded.pem_name);
350             break;
351         case OSSL_STORE_INFO_NAME:
352             OPENSSL_free(info->_.name.name);
353             OPENSSL_free(info->_.name.desc);
354             break;
355         case OSSL_STORE_INFO_PARAMS:
356             EVP_PKEY_free(info->_.params);
357             break;
358         case OSSL_STORE_INFO_PKEY:
359             EVP_PKEY_free(info->_.pkey);
360             break;
361         case OSSL_STORE_INFO_CERT:
362             X509_free(info->_.x509);
363             break;
364         case OSSL_STORE_INFO_CRL:
365             X509_CRL_free(info->_.crl);
366             break;
367         }
368         OPENSSL_free(info);
369     }
370 }
371
372 /* Internal functions */
373 OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
374                                               BUF_MEM *embedded)
375 {
376     OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
377
378     if (info == NULL) {
379         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
380                       ERR_R_MALLOC_FAILURE);
381         return NULL;
382     }
383
384     info->_.embedded.blob = embedded;
385     info->_.embedded.pem_name =
386         new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
387
388     if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
389         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
390                       ERR_R_MALLOC_FAILURE);
391         OSSL_STORE_INFO_free(info);
392         info = NULL;
393     }
394
395     return info;
396 }
397
398 BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
399 {
400     if (info->type == OSSL_STORE_INFO_EMBEDDED)
401         return info->_.embedded.blob;
402     return NULL;
403 }
404
405 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
406 {
407     if (info->type == OSSL_STORE_INFO_EMBEDDED)
408         return info->_.embedded.pem_name;
409     return NULL;
410 }
411
412 OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
413                                           void *ui_data)
414 {
415     OSSL_STORE_CTX *ctx = NULL;
416     const OSSL_STORE_LOADER *loader = NULL;
417     OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
418
419     if ((loader = ossl_store_get0_loader_int("file")) == NULL
420         || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL))
421         goto done;
422     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
423         OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
424                      ERR_R_MALLOC_FAILURE);
425         goto done;
426     }
427
428     ctx->loader = loader;
429     ctx->loader_ctx = loader_ctx;
430     loader_ctx = NULL;
431     ctx->ui_method = ui_method;
432     ctx->ui_data = ui_data;
433     ctx->post_process = NULL;
434     ctx->post_process_data = NULL;
435
436  done:
437     if (loader_ctx != NULL)
438         /*
439          * We ignore a returned error because we will return NULL anyway in
440          * this case, so if something goes wrong when closing, that'll simply
441          * just add another entry on the error stack.
442          */
443         (void)loader->close(loader_ctx);
444     return ctx;
445 }
446
447 int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx)
448 {
449     int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx);
450
451     OPENSSL_free(ctx);
452     return loader_ret;
453 }