Blame SOURCES/0073-utils-refactor-ssh-key-extraction-NSS.patch

71e593
From 4e627add38af409ec6a5023212677956babca1e7 Mon Sep 17 00:00:00 2001
71e593
From: Sumit Bose <sbose@redhat.com>
71e593
Date: Fri, 16 Nov 2018 17:31:00 +0100
71e593
Subject: [PATCH 73/74] utils: refactor ssh key extraction (NSS)
71e593
71e593
Prepare the current code to allow adding other key types.
71e593
71e593
Related to https://pagure.io/SSSD/sssd/issue/3887
71e593
71e593
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
71e593
---
71e593
 src/util/cert/nss/cert.c | 110 +++++++++++++++++++++++----------------
71e593
 1 file changed, 65 insertions(+), 45 deletions(-)
71e593
71e593
diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c
71e593
index a8efef818..b5c4769a8 100644
71e593
--- a/src/util/cert/nss/cert.c
71e593
+++ b/src/util/cert/nss/cert.c
71e593
@@ -223,14 +223,10 @@ done:
71e593
 #define SSH_RSA_HEADER "ssh-rsa"
71e593
 #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)
71e593
 
71e593
-errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
71e593
-                              uint8_t *der_blob, size_t der_size,
71e593
-                              uint8_t **key_blob, size_t *key_size)
71e593
+static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx,
71e593
+                                  SECKEYPublicKey *cert_pub_key,
71e593
+                                  uint8_t **key_blob, size_t *key_size)
71e593
 {
71e593
-    CERTCertDBHandle *handle;
71e593
-    CERTCertificate *cert = NULL;
71e593
-    SECItem der_item;
71e593
-    SECKEYPublicKey *cert_pub_key = NULL;
71e593
     int ret;
71e593
     size_t size;
71e593
     uint8_t *buf = NULL;
71e593
@@ -238,44 +234,6 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
71e593
     size_t exponent_prefix_len;
71e593
     size_t modulus_prefix_len;
71e593
 
71e593
-    if (der_blob == NULL || der_size == 0) {
71e593
-        return EINVAL;
71e593
-    }
71e593
-
71e593
-    /* initialize NSS if needed */
71e593
-    ret = nspr_nss_init();
71e593
-    if (ret != EOK) {
71e593
-        ret = EIO;
71e593
-        goto done;
71e593
-    }
71e593
-
71e593
-    handle = CERT_GetDefaultCertDB();
71e593
-
71e593
-    der_item.len = der_size;
71e593
-    der_item.data = discard_const(der_blob);
71e593
-
71e593
-    cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE);
71e593
-    if (cert == NULL) {
71e593
-        DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n");
71e593
-        ret = EINVAL;
71e593
-        goto done;
71e593
-    }
71e593
-
71e593
-    cert_pub_key = CERT_ExtractPublicKey(cert);
71e593
-    if (cert_pub_key == NULL) {
71e593
-        DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n");
71e593
-        ret = EIO;
71e593
-        goto done;
71e593
-    }
71e593
-
71e593
-    if (cert_pub_key->keyType != rsaKey) {
71e593
-        DEBUG(SSSDBG_CRIT_FAILURE,
71e593
-              "Expected RSA public key, found unsupported [%d].\n",
71e593
-              cert_pub_key->keyType);
71e593
-        ret = EINVAL;
71e593
-        goto done;
71e593
-    }
71e593
-
71e593
     /* Looks like nss drops the leading 00 which AFAIK is added to make sure
71e593
      * the bigint is handled as positive number if the leading bit is set. */
71e593
     exponent_prefix_len = 0;
71e593
@@ -330,6 +288,68 @@ done:
71e593
     if (ret != EOK)  {
71e593
         talloc_free(buf);
71e593
     }
71e593
+
71e593
+    return ret;
71e593
+}
71e593
+
71e593
+errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
71e593
+                              uint8_t *der_blob, size_t der_size,
71e593
+                              uint8_t **key_blob, size_t *key_size)
71e593
+{
71e593
+    CERTCertDBHandle *handle;
71e593
+    CERTCertificate *cert = NULL;
71e593
+    SECItem der_item;
71e593
+    SECKEYPublicKey *cert_pub_key = NULL;
71e593
+    int ret;
71e593
+
71e593
+    if (der_blob == NULL || der_size == 0) {
71e593
+        return EINVAL;
71e593
+    }
71e593
+
71e593
+    /* initialize NSS if needed */
71e593
+    ret = nspr_nss_init();
71e593
+    if (ret != EOK) {
71e593
+        ret = EIO;
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    handle = CERT_GetDefaultCertDB();
71e593
+
71e593
+    der_item.len = der_size;
71e593
+    der_item.data = discard_const(der_blob);
71e593
+
71e593
+    cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE);
71e593
+    if (cert == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n");
71e593
+        ret = EINVAL;
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    cert_pub_key = CERT_ExtractPublicKey(cert);
71e593
+    if (cert_pub_key == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n");
71e593
+        ret = EIO;
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    switch (cert_pub_key->keyType) {
71e593
+    case rsaKey:
71e593
+        ret = rsa_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size);
71e593
+        if (ret != EOK) {
71e593
+            DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n");
71e593
+            goto done;
71e593
+        }
71e593
+        break;
71e593
+    default:
71e593
+        DEBUG(SSSDBG_CRIT_FAILURE,
71e593
+              "Expected RSA public key, found unsupported [%d].\n",
71e593
+              cert_pub_key->keyType);
71e593
+        ret = EINVAL;
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+done:
71e593
+
71e593
     SECKEY_DestroyPublicKey(cert_pub_key);
71e593
     CERT_DestroyCertificate(cert);
71e593
 
71e593
-- 
71e593
2.19.1
71e593