diff --git a/include/tlsuv/keychain.h b/include/tlsuv/keychain.h new file mode 100644 index 0000000..992fda5 --- /dev/null +++ b/include/tlsuv/keychain.h @@ -0,0 +1,45 @@ + +#ifndef TLSUV_KEYCHAIN_H +#define TLSUV_KEYCHAIN_H + +#if __cplusplus +#include +#include +#else +#include +#include +#endif + +enum keychain_key_type { + keychain_key_invalid, + keychain_key_ec, + keychain_key_rsa, +}; + +typedef void* keychain_key_t; + +// generic keychain API +typedef struct keychain_s keychain_t; +struct keychain_s { + int (*gen_key)(keychain_key_t *pk, enum keychain_key_type type, const char *name); + int (*load_key)(keychain_key_t*, const char *name); + int (*rem_key)(const char *name); + + enum keychain_key_type (*key_type)(keychain_key_t k); + int (*key_public)(keychain_key_t k, char *buf, size_t *len); + int (*key_sign)(keychain_key_t k, const uint8_t * data, size_t datalen, + uint8_t *sig, size_t *siglen, int p); + + void (*free_key)(keychain_key_t k); +}; + +#if __cplusplus +extern "C" { +#endif +const keychain_t *tlsuv_keychain(); +void tlsuv_set_keychain(keychain_t *); +#if __cplusplus +} +#endif + +#endif //TLSUV_KEYCHAIN_H diff --git a/src/keychain.h b/src/keychain.h index b7f9fa9..d7b8471 100644 --- a/src/keychain.h +++ b/src/keychain.h @@ -12,34 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef TLSUV_KEYCHAIN_H -#define TLSUV_KEYCHAIN_H +#ifndef TLSUV_SRC_KEYCHAIN_H +#define TLSUV_SRC_KEYCHAIN_H -enum keychain_key_type { - keychain_key_invalid, - keychain_key_ec, - keychain_key_rsa, -}; - -typedef void* keychain_key_t; - -// generic keychain API -typedef struct keychain_s keychain_t; -struct keychain_s { - int (*gen_key)(keychain_key_t *pk, enum keychain_key_type type, const char *name); - int (*load_key)(keychain_key_t*, const char *name); - int (*rem_key)(const char *name); - - enum keychain_key_type (*key_type)(keychain_key_t k); - int (*key_public)(keychain_key_t k, char *buf, size_t *len); - int (*key_sign)(keychain_key_t k, const uint8_t * data, size_t datalen, - uint8_t *sig, size_t *siglen, int p); - - void (*free_key)(keychain_key_t k); -}; - -const keychain_t* tlsuv_keychain(); -void tlsuv_set_keychain(keychain_t *); +#include int keychain_gen_key(keychain_key_t *pk, enum keychain_key_type type, const char *name); int keychain_load_key(keychain_key_t*, const char *name); @@ -52,4 +28,4 @@ int keychain_key_sign(keychain_key_t k, const uint8_t * data, size_t datalen, void keychain_free_key(keychain_key_t k); -#endif //TLSUV_KEYCHAIN_H +#endif //TLSUV_SRC_KEYCHAIN_H diff --git a/src/openssl/keys.c b/src/openssl/keys.c index 8b5b316..7807b9e 100644 --- a/src/openssl/keys.c +++ b/src/openssl/keys.c @@ -511,6 +511,32 @@ int load_kc_key(EVP_PKEY **pkey, keychain_key_t k) { goto error; } + // check if pub key is ASN.1 SubjectPublicKeyInfo format + // https://docs.openssl.org/3.3/man3/X509_PUBKEY_new/#synopsis + const uint8_t *p = pub; + X509_PUBKEY *x509_pub = d2i_X509_PUBKEY(NULL, &p, (long)publen); + if (x509_pub != NULL) { + EVP_PKEY *pk1 = X509_PUBKEY_get(x509_pub); + X509_PUBKEY_free(x509_pub); + int key_type = EVP_PKEY_get_base_id(pk1); + if (key_type == EVP_PKEY_EC) { + EC_KEY *key = EVP_PKEY_get1_EC_KEY(pk1); + EC_KEY_set_ex_data(key, kc_ec_idx, k); + EC_KEY_set_method(key, ext_ec_method); + EVP_PKEY_set1_EC_KEY(pk1, key); + EC_KEY_free(key); // decrease refcount + } else if (key_type == EVP_PKEY_RSA) { + RSA *rsa = EVP_PKEY_get0_RSA(pk1); + RSA_set_ex_data(rsa, kc_rsa_idx, k); + RSA_set_method(rsa, ext_rsa_method); + } else { + EVP_PKEY_free(pk1); + return -1; + } + *pkey = pk1; + return 0; + } + if (keychain_key_type(k) == keychain_key_ec) { const char *group = NULL;