From ad3356d105835718f57edb7844e1fed911770610 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 14 Nov 2018 15:02:33 +0100 Subject: [PATCH 71/74] utils: refactor ssh key extraction (OpenSSL) Prepare the current code to allow adding other key types. Related to https://pagure.io/SSSD/sssd/issue/3887 Reviewed-by: Jakub Hrozek --- src/util/cert/libcrypto/cert.c | 87 +++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c index c8e07837f..d925c5c5b 100644 --- a/src/util/cert/libcrypto/cert.c +++ b/src/util/cert/libcrypto/cert.c @@ -171,17 +171,13 @@ done: #define SSH_RSA_HEADER "ssh-rsa" #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) -errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, - const uint8_t *der_blob, size_t der_size, - uint8_t **key_blob, size_t *key_size) +static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key, + uint8_t **key_blob, size_t *key_size) { int ret; + size_t c; size_t size; - const unsigned char *d; uint8_t *buf = NULL; - size_t c; - X509 *cert = NULL; - EVP_PKEY *cert_pub_key = NULL; const BIGNUM *n; const BIGNUM *e; int modulus_len; @@ -189,33 +185,6 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, int exponent_len; unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8]; - if (der_blob == NULL || der_size == 0) { - return EINVAL; - } - - d = (const unsigned char *) der_blob; - - cert = d2i_X509(NULL, &d, (int) der_size); - if (cert == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); - return EINVAL; - } - - cert_pub_key = X509_get_pubkey(cert); - if (cert_pub_key == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n"); - ret = EIO; - goto done; - } - - if (EVP_PKEY_base_id(cert_pub_key) != EVP_PKEY_RSA) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Expected RSA public key, found unsupported [%d].\n", - EVP_PKEY_base_id(cert_pub_key)); - ret = EINVAL; - goto done; - } - #if OPENSSL_VERSION_NUMBER >= 0x10100000L RSA *rsa_pub_key = NULL; rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key); @@ -268,6 +237,56 @@ done: if (ret != EOK) { talloc_free(buf); } + + return ret; +} + +errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, + const uint8_t *der_blob, size_t der_size, + uint8_t **key_blob, size_t *key_size) +{ + int ret; + const unsigned char *d; + X509 *cert = NULL; + EVP_PKEY *cert_pub_key = NULL; + + if (der_blob == NULL || der_size == 0) { + return EINVAL; + } + + d = (const unsigned char *) der_blob; + + cert = d2i_X509(NULL, &d, (int) der_size); + if (cert == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); + return EINVAL; + } + + cert_pub_key = X509_get_pubkey(cert); + if (cert_pub_key == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n"); + ret = EIO; + goto done; + } + + switch (EVP_PKEY_base_id(cert_pub_key)) { + case EVP_PKEY_RSA: + ret = rsa_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n"); + goto done; + } + break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, + "Expected RSA public key, found unsupported [%d].\n", + EVP_PKEY_base_id(cert_pub_key)); + ret = EINVAL; + goto done; + } + +done: + EVP_PKEY_free(cert_pub_key); X509_free(cert); -- 2.19.1