Blob Blame History Raw
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