From ad3356d105835718f57edb7844e1fed911770610 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
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 <jhrozek@redhat.com>
---
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