]>
Commit | Line | Data |
---|---|---|
8c7c1c84 | 1 | /* |
da1c088f | 2 | * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. |
8c7c1c84 MC |
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 <openssl/asn1t.h> | |
12 | #include <openssl/core_names.h> | |
13 | #include <openssl/core_object.h> | |
14 | #include <openssl/params.h> | |
15 | #include <openssl/x509.h> | |
16 | #include "internal/sizes.h" | |
17 | #include "crypto/x509.h" | |
18 | #include "crypto/ec.h" | |
19 | #include "prov/bio.h" | |
20 | #include "prov/implementations.h" | |
21 | #include "endecoder_local.h" | |
22 | ||
23 | static OSSL_FUNC_decoder_newctx_fn spki2typespki_newctx; | |
24 | static OSSL_FUNC_decoder_freectx_fn spki2typespki_freectx; | |
25 | static OSSL_FUNC_decoder_decode_fn spki2typespki_decode; | |
39ed7636 | 26 | static OSSL_FUNC_decoder_settable_ctx_params_fn spki2typespki_settable_ctx_params; |
27 | static OSSL_FUNC_decoder_set_ctx_params_fn spki2typespki_set_ctx_params; | |
8c7c1c84 MC |
28 | |
29 | /* | |
30 | * Context used for SubjectPublicKeyInfo to Type specific SubjectPublicKeyInfo | |
31 | * decoding. | |
32 | */ | |
33 | struct spki2typespki_ctx_st { | |
34 | PROV_CTX *provctx; | |
39ed7636 | 35 | char propq[OSSL_MAX_PROPQUERY_SIZE]; |
8c7c1c84 MC |
36 | }; |
37 | ||
38 | static void *spki2typespki_newctx(void *provctx) | |
39 | { | |
40 | struct spki2typespki_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
41 | ||
42 | if (ctx != NULL) | |
43 | ctx->provctx = provctx; | |
44 | return ctx; | |
45 | } | |
46 | ||
47 | static void spki2typespki_freectx(void *vctx) | |
48 | { | |
49 | struct spki2typespki_ctx_st *ctx = vctx; | |
50 | ||
51 | OPENSSL_free(ctx); | |
52 | } | |
53 | ||
39ed7636 | 54 | static const OSSL_PARAM *spki2typespki_settable_ctx_params(ossl_unused void *provctx) |
55 | { | |
56 | static const OSSL_PARAM settables[] = { | |
57 | OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), | |
58 | OSSL_PARAM_END | |
59 | }; | |
60 | return settables; | |
61 | } | |
62 | ||
63 | static int spki2typespki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | |
64 | { | |
65 | struct spki2typespki_ctx_st *ctx = vctx; | |
66 | const OSSL_PARAM *p; | |
67 | char *str = ctx->propq; | |
68 | ||
69 | p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); | |
70 | if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) | |
71 | return 0; | |
72 | ||
73 | return 1; | |
74 | } | |
75 | ||
8c7c1c84 MC |
76 | static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, |
77 | OSSL_CALLBACK *data_cb, void *data_cbarg, | |
78 | OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | |
79 | { | |
80 | struct spki2typespki_ctx_st *ctx = vctx; | |
81 | unsigned char *der, *derp; | |
82 | long len; | |
83 | int ok = 0; | |
84 | int objtype = OSSL_OBJECT_PKEY; | |
85 | X509_PUBKEY *xpub = NULL; | |
86 | X509_ALGOR *algor = NULL; | |
87 | const ASN1_OBJECT *oid = NULL; | |
88 | char dataname[OSSL_MAX_NAME_SIZE]; | |
89 | OSSL_PARAM params[5], *p = params; | |
90 | ||
91 | if (!ossl_read_der(ctx->provctx, cin, &der, &len)) | |
92 | return 1; | |
93 | derp = der; | |
94 | xpub = ossl_d2i_X509_PUBKEY_INTERNAL((const unsigned char **)&derp, len, | |
39ed7636 | 95 | PROV_LIBCTX_OF(ctx->provctx), |
96 | ctx->propq); | |
8c7c1c84 MC |
97 | |
98 | if (xpub == NULL) { | |
99 | /* We return "empty handed". This is not an error. */ | |
100 | ok = 1; | |
101 | goto end; | |
102 | } | |
103 | ||
104 | if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algor, xpub)) | |
105 | goto end; | |
106 | X509_ALGOR_get0(&oid, NULL, NULL, algor); | |
107 | ||
108 | #ifndef OPENSSL_NO_EC | |
109 | /* SM2 abuses the EC oid, so this could actually be SM2 */ | |
110 | if (OBJ_obj2nid(oid) == NID_X9_62_id_ecPublicKey | |
111 | && ossl_x509_algor_is_sm2(algor)) | |
112 | strcpy(dataname, "SM2"); | |
113 | else | |
114 | #endif | |
2349d7ba | 115 | if (OBJ_obj2txt(dataname, sizeof(dataname), oid, 0) <= 0) |
8c7c1c84 MC |
116 | goto end; |
117 | ||
118 | ossl_X509_PUBKEY_INTERNAL_free(xpub); | |
119 | xpub = NULL; | |
120 | ||
121 | *p++ = | |
122 | OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, | |
123 | dataname, 0); | |
124 | ||
125 | *p++ = | |
126 | OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, | |
127 | "SubjectPublicKeyInfo", | |
128 | 0); | |
129 | *p++ = | |
130 | OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, der, len); | |
131 | *p++ = | |
132 | OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype); | |
133 | ||
134 | *p = OSSL_PARAM_construct_end(); | |
135 | ||
136 | ok = data_cb(params, data_cbarg); | |
137 | ||
138 | end: | |
139 | ossl_X509_PUBKEY_INTERNAL_free(xpub); | |
140 | OPENSSL_free(der); | |
141 | return ok; | |
142 | } | |
143 | ||
144 | const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_der_decoder_functions[] = { | |
145 | { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))spki2typespki_newctx }, | |
146 | { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))spki2typespki_freectx }, | |
147 | { OSSL_FUNC_DECODER_DECODE, (void (*)(void))spki2typespki_decode }, | |
39ed7636 | 148 | { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, |
149 | (void (*)(void))spki2typespki_settable_ctx_params }, | |
150 | { OSSL_FUNC_DECODER_SET_CTX_PARAMS, | |
151 | (void (*)(void))spki2typespki_set_ctx_params }, | |
1e6bd31e | 152 | OSSL_DISPATCH_END |
8c7c1c84 | 153 | }; |