18#ifdef HAVE_XKEY_PROVIDER
20#include <openssl/provider.h>
21#include <openssl/params.h>
22#include <openssl/core_dispatch.h>
23#include <openssl/core_object.h>
24#include <openssl/core_names.h>
25#include <openssl/store.h>
26#include <openssl/evp.h>
27#include <openssl/err.h>
31static const char *
const props = XKEY_PROV_PROPS;
33static XKEY_LOGGING_CALLBACK_fn *xkey_log_callback;
36print_openssl_errors(
void)
39 while ((e = ERR_get_error()))
41 msg(
M_WARN,
"OpenSSL error %lu: %s\n", e, ERR_error_string(e, NULL));
51xkey_load_generic_key(OSSL_LIB_CTX *libctx,
void *handle, EVP_PKEY *pubkey,
52 XKEY_EXTERNAL_SIGN_fn *sign_op, XKEY_PRIVKEY_FREE_fn *free_op)
54 EVP_PKEY *pkey = NULL;
55 const char *origin =
"external";
58 OSSL_PARAM params[] = {
59 {
"xkey-origin", OSSL_PARAM_UTF8_STRING, (
char *) origin, 0, 0},
60 {
"pubkey", OSSL_PARAM_OCTET_STRING, &pubkey,
sizeof(pubkey), 0},
61 {
"handle", OSSL_PARAM_OCTET_PTR, &handle,
sizeof(handle), 0},
62 {
"sign_op", OSSL_PARAM_OCTET_PTR, (
void **) &sign_op,
sizeof(sign_op), 0},
63 {
"free_op", OSSL_PARAM_OCTET_PTR, (
void **) &free_op,
sizeof(free_op), 0},
68 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(libctx, EVP_PKEY_get0_type_name(pubkey), props);
70 || EVP_PKEY_fromdata_init(ctx) != 1
71 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1)
73 print_openssl_errors();
74 msg(
M_WARN,
"OpenSSL error: failed to load key into ovpn.xkey provider");
79 EVP_PKEY_CTX_free(ctx);
101xkey_encode_pkcs1(
unsigned char *enc,
size_t *enc_len,
const char *mdname,
102 const unsigned char *tbs,
size_t tbslen)
104 ASSERT(enc_len != NULL);
115 const unsigned char sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
116 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
117 const unsigned char sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
118 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
119 const unsigned char sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
120 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
121 const unsigned char sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
122 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
123 const unsigned char sha224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
124 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c};
125 const unsigned char sha512_224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
126 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1c};
127 const unsigned char sha512_256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
128 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20};
132 const unsigned char *header;
136#define MAKE_DI(x) {NID_ ## x, x, sizeof(x)}
138 DIG_INFO dinfo[] = {MAKE_DI(sha1), MAKE_DI(sha256), MAKE_DI(sha384),
139 MAKE_DI(sha512), MAKE_DI(sha224), MAKE_DI(sha512_224),
140 MAKE_DI(sha512_256), {0,NULL,0}};
145 int nid = OBJ_sn2nid(mdname);
146 if (nid == NID_undef)
149 nid = EVP_MD_type(EVP_get_digestbyname(mdname));
150 if (nid == NID_undef)
152 msg(
M_WARN,
"Error: encode_pkcs11: invalid digest name <%s>", mdname);
157 if (tbslen != EVP_MD_size(EVP_get_digestbyname(mdname)))
159 msg(
M_WARN,
"Error: encode_pkcs11: invalid input length <%zu>", tbslen);
163 if (nid == NID_md5_sha1)
165 if (enc && (*enc_len >= tbslen))
167 memcpy(enc, tbs, tbslen);
175 DIG_INFO *di = dinfo;
176 while ((di->nid != nid) && (di->nid != 0))
182 msg(
M_WARN,
"Error: encode_pkcs11: unsupported hash algorithm <%s>", mdname);
186 out_len = tbslen + di->sz;
188 if (enc && (out_len <= *enc_len))
191 memcpy(enc, di->header, di->sz);
192 memcpy(enc + di->sz, tbs, tbslen);
193 dmsg(
D_XKEY,
"encode_pkcs1: digest length = %zu encoded length = %zu", tbslen, out_len);
203void xkey_set_logging_cb_function(XKEY_LOGGING_CALLBACK_fn logfunc)
205 xkey_log_callback = logfunc;
212 va_start(arglist, format);
214 char msgbuf[4096] = {0};
216 vsnprintf(msgbuf,
sizeof(msgbuf), format, arglist);
220 if (debug && xkey_log_callback != NULL)
222 xkey_log_callback(msgbuf, debug);
void openvpn_msg_xkey_compat(unsigned int flags, const char *format,...)