35#ifdef HAVE_XKEY_PROVIDER
37#include <openssl/provider.h>
38#include <openssl/params.h>
39#include <openssl/core_dispatch.h>
40#include <openssl/core_object.h>
41#include <openssl/core_names.h>
42#include <openssl/store.h>
43#include <openssl/evp.h>
44#include <openssl/err.h>
46static const char *
const props = XKEY_PROV_PROPS;
48XKEY_EXTERNAL_SIGN_fn xkey_management_sign;
51print_openssl_errors(
void)
54 while ((e = ERR_get_error()))
56 msg(
M_WARN,
"OpenSSL error %lu: %s", e, ERR_error_string(e, NULL));
62xkey_digest(
const unsigned char *src,
size_t srclen,
unsigned char *buf,
size_t *buflen,
69 msg(
M_WARN,
"WARN: xkey_digest: MD_fetch failed for <%s>", mdname);
73 unsigned int len = (
unsigned int)*buflen;
74 if (EVP_Digest(src, srclen, buf, &len, md, NULL) != 1)
76 msg(
M_WARN,
"WARN: xkey_digest: EVP_Digest failed");
85#ifdef ENABLE_MANAGEMENT
94xkey_load_management_key(
OSSL_LIB_CTX *libctx, EVP_PKEY *pubkey)
102 void *dummy = &
"dummy";
104 XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_management_sign;
106 return xkey_load_generic_key(libctx, dummy, pubkey, sign_op, NULL);
116xkey_load_generic_key(
OSSL_LIB_CTX *libctx,
void *handle, EVP_PKEY *pubkey,
117 XKEY_EXTERNAL_SIGN_fn *sign_op, XKEY_PRIVKEY_FREE_fn *free_op)
119 EVP_PKEY *pkey = NULL;
120 const char *origin =
"external";
123 OSSL_PARAM params[] = {
124 {
"xkey-origin", OSSL_PARAM_UTF8_STRING, (
char *)origin, 0, 0 },
125 {
"pubkey", OSSL_PARAM_OCTET_STRING, &pubkey,
sizeof(pubkey), 0 },
126 {
"handle", OSSL_PARAM_OCTET_PTR, &handle,
sizeof(handle), 0 },
127 {
"sign_op", OSSL_PARAM_OCTET_PTR, (
void **)&sign_op,
sizeof(sign_op), 0 },
128 {
"free_op", OSSL_PARAM_OCTET_PTR, (
void **)&free_op,
sizeof(free_op), 0 },
129 { NULL, 0, NULL, 0, 0 }
133 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(libctx, EVP_PKEY_get0_type_name(pubkey), props);
134 if (!ctx || EVP_PKEY_fromdata_init(ctx) != 1
135 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) != 1)
137 print_openssl_errors();
138 msg(
M_FATAL,
"OpenSSL error: failed to load key into ovpn.xkey provider");
142 EVP_PKEY_CTX_free(ctx);
148#ifdef ENABLE_MANAGEMENT
163xkey_management_sign(
void *unused,
unsigned char *sig,
size_t *siglen,
const unsigned char *tbs,
164 size_t tbslen, XKEY_SIGALG alg)
166 dmsg(
D_XKEY,
"In xkey_management_sign with keytype = %s, op = %s", alg.keytype, alg.op);
170 unsigned char buf[EVP_MAX_MD_SIZE];
171 size_t buflen =
sizeof(buf);
173 unsigned char enc[EVP_MAX_MD_SIZE + 32];
174 size_t enc_len =
sizeof(enc);
177 bool is_message = !strcmp(alg.op,
"DigestSign");
181 && strcmp(alg.mdname,
"none"))
183 dmsg(
D_XKEY,
"xkey_management_sign: computing digest");
184 if (xkey_digest(tbs, tbslen, buf, &buflen, alg.mdname))
197 if (!strcmp(alg.keytype,
"EC"))
199 if (!strcmp(alg.op,
"Sign"))
201 strncpynt(alg_str,
"ECDSA",
sizeof(alg_str));
205 snprintf(alg_str,
sizeof(alg_str),
"ECDSA,hashalg=%s", alg.mdname);
208 else if (!strcmp(alg.keytype,
"ED448") || !strcmp(alg.keytype,
"ED25519"))
210 strncpynt(alg_str, alg.keytype,
sizeof(alg_str));
216 if (!strcmp(alg.op,
"Sign"))
218 if (!encode_pkcs1(enc, &enc_len, alg.mdname, tbs, tbslen))
224 strncpynt(alg_str,
"RSA_PKCS1_PADDING",
sizeof(alg_str));
229 snprintf(alg_str,
sizeof(alg_str),
"%s,hashalg=%s",
"RSA_PKCS1_PADDING", alg.mdname);
233 && !strcmp(alg.op,
"Sign"))
235 strncpynt(alg_str,
"RSA_NO_PADDING",
sizeof(alg_str));
239 snprintf(alg_str,
sizeof(alg_str),
"%s,hashalg=%s,saltlen=%s",
"RSA_PKCS1_PSS_PADDING",
240 alg.mdname, alg.saltlen);
244 msg(
M_NONFATAL,
"RSA padding mode not supported by management-client <%s>", alg.padmode);
250 strncat(alg_str,
",data=message",
sizeof(alg_str) - strlen(alg_str) - 1);
253 dmsg(
D_LOW,
"xkey management_sign: requesting sig with algorithm <%s>", alg_str);
256 char *out_b64 = NULL;
272 *siglen = (len > 0) ? len : 0;
274 return (*siglen > 0);
294encode_pkcs1(
unsigned char *enc,
size_t *enc_len,
const char *mdname,
const unsigned char *tbs,
308 const unsigned char sha1[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
309 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
310 const unsigned char sha256[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
311 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
312 const unsigned char sha384[] = { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
313 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 };
314 const unsigned char sha512[] = { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
315 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 };
316 const unsigned char sha224[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
317 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c };
318 const unsigned char sha512_224[] = { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
319 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1c };
320 const unsigned char sha512_256[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
321 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20 };
326 const unsigned char *header;
330#define MAKE_DI(x) { NID_##x, x, sizeof(x) }
334 MAKE_DI(sha1), MAKE_DI(sha256), MAKE_DI(sha384), MAKE_DI(sha512),
335 MAKE_DI(sha224), MAKE_DI(sha512_224), MAKE_DI(sha512_256), { 0, NULL, 0 }
342 int nid = OBJ_sn2nid(mdname);
343 if (nid == NID_undef)
346 nid = EVP_MD_type(EVP_get_digestbyname(mdname));
347 if (nid == NID_undef)
349 msg(
M_WARN,
"Error: encode_pkcs11: invalid digest name <%s>", mdname);
354 if (tbslen != EVP_MD_size(EVP_get_digestbyname(mdname)))
356 msg(
M_WARN,
"Error: encode_pkcs11: invalid input length <%zu>", tbslen);
360 if (nid == NID_md5_sha1)
362 if (enc && (*enc_len >= tbslen))
364 memcpy(enc, tbs, tbslen);
372 DIG_INFO *di = dinfo;
373 while ((di->nid != nid) && (di->nid != 0))
379 msg(
M_WARN,
"Error: encode_pkcs11: unsupported hash algorithm <%s>", mdname);
383 out_len = tbslen + di->sz;
385 if (enc && (out_len <= *enc_len))
388 memcpy(enc, di->header, di->sz);
389 memcpy(enc + di->sz, tbs, tbslen);
390 dmsg(
D_XKEY,
"encode_pkcs1: digest length = %zu encoded length = %zu", tbslen, out_len);
407ecdsa_bin2der(
unsigned char *buf,
int len,
size_t capacity)
409 ECDSA_SIG *ecsig = NULL;
411 BIGNUM *r = BN_bin2bn(buf, rlen, NULL);
412 BIGNUM *s = BN_bin2bn(buf + rlen, rlen, NULL);
417 ecsig = ECDSA_SIG_new();
422 if (!ECDSA_SIG_set0(ecsig, r, s))
424 ECDSA_SIG_free(ecsig);
428 int derlen = i2d_ECDSA_SIG(ecsig, NULL);
429 if (derlen > (
int)capacity)
431 ECDSA_SIG_free(ecsig);
432 msg(
M_NONFATAL,
"Error: DER encoded ECDSA signature is too long (%d)", derlen);
435 derlen = i2d_ECDSA_SIG(ecsig, &buf);
436 ECDSA_SIG_free(ecsig);
static void strncpynt(char *dest, const char *src, size_t maxlen)
char * management_query_pk_sig(struct management *man, const char *b64_data, const char *algorithm)
#define MF_EXTERNAL_KEY_PKCS1PAD
#define MF_EXTERNAL_KEY_PSSPAD
#define MF_EXTERNAL_KEY_NOPADDING
#define MF_EXTERNAL_KEY_DIGEST
static void EVP_MD_free(const EVP_MD *md)
static const EVP_MD * EVP_MD_fetch(void *ctx, const char *algorithm, const char *properties)
int openvpn_base64_decode(const char *str, void *data, int size)
int openvpn_base64_encode(const void *data, int size, char **str)
struct man_settings settings