Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/lib/engine.c
34878 views
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
* Here is a set of wrappers for the ENGINE API, which are no-ops when the
12
* ENGINE API is disabled / removed.
13
* We need to suppress deprecation warnings to make this work.
14
*/
15
#define OPENSSL_SUPPRESS_DEPRECATED
16
17
#include <string.h> /* strcmp */
18
19
#include <openssl/types.h> /* Ensure we have the ENGINE type, regardless */
20
#include <openssl/err.h>
21
#ifndef OPENSSL_NO_ENGINE
22
# include <openssl/engine.h>
23
#endif
24
#include "apps.h"
25
26
#ifndef OPENSSL_NO_ENGINE
27
/* Try to load an engine in a shareable library */
28
static ENGINE *try_load_engine(const char *engine)
29
{
30
ENGINE *e = NULL;
31
32
if ((e = ENGINE_by_id("dynamic")) != NULL) {
33
if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
34
|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
35
ENGINE_free(e);
36
e = NULL;
37
}
38
}
39
return e;
40
}
41
#endif
42
43
ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug)
44
{
45
ENGINE *e = NULL;
46
47
#ifndef OPENSSL_NO_ENGINE
48
if (id != NULL) {
49
if (strcmp(id, "auto") == 0) {
50
BIO_printf(bio_err, "Enabling auto ENGINE support\n");
51
ENGINE_register_all_complete();
52
return NULL;
53
}
54
if ((e = ENGINE_by_id(id)) == NULL
55
&& (e = try_load_engine(id)) == NULL) {
56
BIO_printf(bio_err, "Invalid engine \"%s\"\n", id);
57
ERR_print_errors(bio_err);
58
return NULL;
59
}
60
if (debug)
61
(void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
62
if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0,
63
(void *)get_ui_method(), 0, 1)
64
|| !ENGINE_set_default(e, methods)) {
65
BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e));
66
ERR_print_errors(bio_err);
67
ENGINE_free(e);
68
return NULL;
69
}
70
71
BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e));
72
}
73
#endif
74
return e;
75
}
76
77
void release_engine(ENGINE *e)
78
{
79
#ifndef OPENSSL_NO_ENGINE
80
/* Free our "structural" reference. */
81
ENGINE_free(e);
82
#endif
83
}
84
85
int init_engine(ENGINE *e)
86
{
87
int rv = 1;
88
89
#ifndef OPENSSL_NO_ENGINE
90
rv = ENGINE_init(e);
91
#endif
92
return rv;
93
}
94
95
int finish_engine(ENGINE *e)
96
{
97
int rv = 1;
98
99
#ifndef OPENSSL_NO_ENGINE
100
rv = ENGINE_finish(e);
101
#endif
102
return rv;
103
}
104
105
char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc)
106
{
107
char *new_uri = NULL;
108
109
#ifndef OPENSSL_NO_ENGINE
110
if (e == NULL) {
111
BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
112
} else if (key_id == NULL) {
113
BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc);
114
} else {
115
const char *engineid = ENGINE_get_id(e);
116
size_t uri_sz =
117
sizeof(ENGINE_SCHEME_COLON) - 1
118
+ strlen(engineid)
119
+ 1 /* : */
120
+ strlen(key_id)
121
+ 1 /* \0 */
122
;
123
124
new_uri = OPENSSL_malloc(uri_sz);
125
if (new_uri != NULL) {
126
OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz);
127
OPENSSL_strlcat(new_uri, engineid, uri_sz);
128
OPENSSL_strlcat(new_uri, ":", uri_sz);
129
OPENSSL_strlcat(new_uri, key_id, uri_sz);
130
}
131
}
132
#else
133
BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
134
#endif
135
return new_uri;
136
}
137
138
int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e)
139
{
140
const EVP_PKEY_ASN1_METHOD *ameth;
141
ENGINE *tmpeng = NULL;
142
int pkey_id = NID_undef;
143
144
ERR_set_mark();
145
ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
146
147
#if !defined(OPENSSL_NO_ENGINE)
148
ENGINE_finish(tmpeng);
149
150
if (ameth == NULL && e != NULL)
151
ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
152
else
153
#endif
154
/* We're only interested if it comes from an ENGINE */
155
if (tmpeng == NULL)
156
ameth = NULL;
157
158
ERR_pop_to_mark();
159
if (ameth == NULL)
160
return NID_undef;
161
162
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
163
164
return pkey_id;
165
}
166
167
const EVP_MD *get_digest_from_engine(const char *name)
168
{
169
#ifndef OPENSSL_NO_ENGINE
170
ENGINE *eng;
171
172
eng = ENGINE_get_digest_engine(OBJ_sn2nid(name));
173
if (eng != NULL) {
174
ENGINE_finish(eng);
175
return EVP_get_digestbyname(name);
176
}
177
#endif
178
return NULL;
179
}
180
181
const EVP_CIPHER *get_cipher_from_engine(const char *name)
182
{
183
#ifndef OPENSSL_NO_ENGINE
184
ENGINE *eng;
185
186
eng = ENGINE_get_cipher_engine(OBJ_sn2nid(name));
187
if (eng != NULL) {
188
ENGINE_finish(eng);
189
return EVP_get_cipherbyname(name);
190
}
191
#endif
192
return NULL;
193
}
194
195