1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2022- OpenVPN Inc.
// Copyright (C) 2021-2022 Selva Nair <selva.nair@gmail.com>
//
// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception OR GPL-2.0-only WITH openvpn-openssl-exception
//
#ifndef XKEY_COMMON_H_
#define XKEY_COMMON_H_
#if defined (__cplusplus)
extern "C" {
#endif
/* Guard to only enable if OpenSSL is used and not trigger an error if mbed
* TLS is compiled without OpenSSL being installed */
#if defined(USE_OPENSSL)
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000010L && !defined(DISABLE_XKEY_PROVIDER)
#define HAVE_XKEY_PROVIDER 1
#include <stdbool.h>
#include <openssl/provider.h>
#include <openssl/core_dispatch.h>
/**
* Initialization function for OpenVPN external key provider for OpenSSL
* Follows the function signature of OSSL_PROVIDER init()
*/
OSSL_provider_init_fn xkey_provider_init;
#define XKEY_PROV_PROPS "provider=ovpn.xkey"
/**
* Struct to encapsulate signature algorithm parameters to pass
* to sign operation.
*/
typedef struct {
const char *padmode; /**< "pkcs1", "pss" or "none" */
const char *mdname; /**< "SHA256" or "SHA2-256" etc. */
const char *saltlen; /**< "digest", "auto" or "max" */
const char *keytype; /**< "EC" or "RSA" */
const char *op; /**< "Sign" or "DigestSign" */
} XKEY_SIGALG;
/**
* Callback for sign operation -- must be implemented for each backend and
* is used in xkey_signature_sign(), or set when loading the key.
* (custom key loading not yet implemented).
*
* @param handle opaque key handle provided by the backend -- could be null
* or unused for management interface.
* @param sig On return caller should fill this with the signature
* @param siglen On entry *siglen has max size of sig and on return must be
* set to the actual size of the signature
* @param tbs buffer to sign
* @param tbslen size of data in tbs buffer
* @sigalg contains the signature algorithm parameters
*
* @returns 1 on success, 0 on error.
*
* If sigalg.op = "Sign", the data in tbs is the digest. If sigalg.op = "DigestSign"
* it is the message that the backend should hash wih appropriate hash algorithm before
* signing. In the former case no DigestInfo header is added to tbs. This is
* unlike the deprecated RSA_sign callback which provides encoded digest.
* For RSA_PKCS1 signatures, the external signing function must encode the digest
* before signing. The digest algorithm used (or to be used) is passed in the sigalg
* structure.
*/
typedef int (XKEY_EXTERNAL_SIGN_fn)(void *handle, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen,
XKEY_SIGALG sigalg);
/**
* Signature of private key free function callback used
* to free the opaque private key handle obtained from the
* backend. Not required for management-external-key.
*/
typedef void (XKEY_PRIVKEY_FREE_fn)(void *handle);
/**
* Load a generic key into the xkey provider.
* Returns an EVP_PKEY object attached to xkey provider.
* Caller must free it when no longer needed.
*/
EVP_PKEY *
xkey_load_generic_key(OSSL_LIB_CTX *libctx, void *handle, EVP_PKEY *pubkey,
XKEY_EXTERNAL_SIGN_fn *sign_op, XKEY_PRIVKEY_FREE_fn *free_op);
/**
* Add PKCS1 DigestInfo to tbs and return the result in *enc.
*
* @param enc pointer to output buffer
* @param enc_len capacity in bytes of output buffer
* @param mdname name of the hash algorithm (SHA256, SHA1 etc.)
* @param tbs pointer to digest to be encoded
* @param tbslen length of data in bytes
*
* @return false on error, true on success
*
* On return enc_len is set to actual size of the result.
* enc is NULL or enc_len is not enough to store the result, it is set
* to the required size and false is returned.
*/
bool
xkey_encode_pkcs1(unsigned char *enc, size_t *enc_len, const char *mdname,
const unsigned char *tbs, size_t tbslen);
/** Prototype for the logging callback is used to provided logging output from
* the xkey provider */
typedef void (XKEY_LOGGING_CALLBACK_fn)(const char *msg, bool debug);
/**
* Sets the function the xkey provider should call when logging. Use NULL
* to disable logging again.
* @param logfunc
*/
void xkey_set_logging_cb_function(XKEY_LOGGING_CALLBACK_fn logfunc);
#endif /* HAVE_XKEY_PROVIDER */
#endif /* USE_OPENSSL */
#if defined (__cplusplus)
}
#endif
#endif /* XKEY_COMMON_H_ */
|