]>
Commit | Line | Data |
---|---|---|
63f187cf RL |
1 | /* |
2 | * Copyright 2020 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 | /* | |
11 | * This is a decoder that's completely internal to the 'file:' store | |
12 | * implementation. Only code in file_store.c know about this one. Because | |
13 | * of this close relationship, we can cut certain corners, such as making | |
14 | * assumptions about the "provider context", which is currently simply the | |
15 | * provider context that the file_store.c code operates within. | |
16 | * | |
17 | * All this does is to read DER from the input if it can, and passes it on | |
18 | * to the data callback as an object abstraction, leaving it to the callback | |
19 | * to figure out what it actually is. | |
20 | * | |
21 | * This MUST be made the last decoder in a chain, leaving it to other more | |
22 | * specialized decoders to recognise and process their stuff first. | |
23 | */ | |
24 | ||
25 | #include <openssl/core_dispatch.h> | |
26 | #include <openssl/core_names.h> | |
27 | #include <openssl/core_object.h> | |
28 | #include <openssl/bio.h> | |
29 | #include <openssl/buffer.h> | |
29844ea5 DDO |
30 | #include <openssl/err.h> |
31 | #include <openssl/asn1err.h> | |
63f187cf RL |
32 | #include <openssl/params.h> |
33 | #include "internal/asn1.h" | |
34 | #include "prov/bio.h" | |
35 | #include "file_store_local.h" | |
36 | ||
37 | /* | |
38 | * newctx and freectx are not strictly necessary. However, the method creator, | |
39 | * ossl_decoder_from_dispatch(), demands that they exist, so we make sure to | |
40 | * oblige. | |
41 | */ | |
42 | ||
43 | static OSSL_FUNC_decoder_newctx_fn der2obj_newctx; | |
44 | static OSSL_FUNC_decoder_freectx_fn der2obj_freectx; | |
45 | ||
46 | static void *der2obj_newctx(void *provctx) | |
47 | { | |
48 | return provctx; | |
49 | } | |
50 | ||
51 | static void der2obj_freectx(void *vctx) | |
52 | { | |
53 | } | |
54 | ||
55 | static OSSL_FUNC_decoder_gettable_params_fn der2obj_gettable_params; | |
56 | static OSSL_FUNC_decoder_get_params_fn der2obj_get_params; | |
57 | static OSSL_FUNC_decoder_decode_fn der2obj_decode; | |
58 | ||
59 | static const OSSL_PARAM *der2obj_gettable_params(void *provctx) | |
60 | { | |
61 | static const OSSL_PARAM gettables[] = { | |
62 | { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, | |
63 | OSSL_PARAM_END, | |
64 | }; | |
65 | ||
66 | return gettables; | |
67 | } | |
68 | ||
69 | static int der2obj_get_params(OSSL_PARAM params[]) | |
70 | { | |
71 | OSSL_PARAM *p; | |
72 | ||
73 | p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); | |
74 | if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER")) | |
75 | return 0; | |
76 | ||
77 | return 1; | |
78 | } | |
79 | ||
80 | static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, | |
81 | OSSL_CALLBACK *data_cb, void *data_cbarg, | |
82 | OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | |
83 | { | |
84 | /* | |
85 | * We're called from file_store.c, so we know that OSSL_CORE_BIO is a | |
86 | * BIO in this case. | |
87 | */ | |
88 | BIO *in = (BIO *)cin; | |
89 | BUF_MEM *mem = NULL; | |
29844ea5 | 90 | int err, ok; |
63f187cf | 91 | |
29844ea5 DDO |
92 | ERR_set_mark(); |
93 | ok = (asn1_d2i_read_bio(in, &mem) >= 0); | |
94 | /* | |
95 | * Prune low-level ASN.1 parse errors from error queue, assuming that | |
96 | * this is called by decoder_process() in a loop trying several formats. | |
97 | */ | |
98 | err = ERR_peek_last_error(); | |
99 | if (ERR_GET_LIB(err) == ERR_LIB_ASN1 | |
100 | && (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG | |
101 | || ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)) | |
102 | ERR_pop_to_mark(); | |
103 | else | |
104 | ERR_clear_last_mark(); | |
63f187cf RL |
105 | if (ok) { |
106 | OSSL_PARAM params[3]; | |
107 | int object_type = OSSL_OBJECT_UNKNOWN; | |
108 | ||
109 | params[0] = | |
110 | OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); | |
111 | params[1] = | |
112 | OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, | |
113 | mem->data, mem->length); | |
114 | params[2] = OSSL_PARAM_construct_end(); | |
115 | ||
116 | ok = data_cb(params, data_cbarg); | |
117 | OPENSSL_free(mem->data); | |
118 | OPENSSL_free(mem); | |
119 | } | |
120 | return ok; | |
121 | } | |
122 | ||
123 | static const OSSL_DISPATCH der_to_obj_decoder_functions[] = { | |
124 | { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))der2obj_newctx }, | |
125 | { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))der2obj_freectx }, | |
126 | { OSSL_FUNC_DECODER_GETTABLE_PARAMS, | |
127 | (void (*)(void))der2obj_gettable_params }, | |
128 | { OSSL_FUNC_DECODER_GET_PARAMS, (void (*)(void))der2obj_get_params }, | |
129 | { OSSL_FUNC_DECODER_DECODE, (void (*)(void))der2obj_decode }, | |
130 | { 0, NULL } | |
131 | }; | |
132 | ||
a55b00bd | 133 | const OSSL_ALGORITHM ossl_der_to_obj_algorithm = |
63f187cf | 134 | { "obj", NULL, der_to_obj_decoder_functions }; |