Blame SOURCES/0040-Don-t-set-SpiceLinkReply-pub_key-if-client-advertise.patch

2be4b2
From 3a3ec08f25e2b53e9de256fcb3a4f951c4b1e871 Mon Sep 17 00:00:00 2001
2be4b2
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
2be4b2
Date: Thu, 9 Jul 2015 01:04:31 +0200
2be4b2
Subject: [PATCH 3/3] Don't set SpiceLinkReply::pub_key if client advertises
2be4b2
 SASL cap
2be4b2
2be4b2
If the client advertises the SASL cap, it means it guarantees it will be
2be4b2
able to use SASL if the server supports, and that it does not need a valid
2be4b2
SpiceLinkReply::pub_key field when using SASL.
2be4b2
2be4b2
When the client cap is set, we thus don't need to create a RSA public key
2be4b2
if SASL is enabled server side.
2be4b2
2be4b2
The reason for needing client guarantees about not looking at the pub_key
2be4b2
field is that its presence and size is hardcoded in the protocol, but in
2be4b2
some hardened setups (using fips mode), generating a RSA 1024 bit key as
2be4b2
expected is forbidden and fails. With this new capability, the server
2be4b2
knows the client will be able to handle SASL if needed, and can skip
2be4b2
the generation of the key altogether. This means that on the setups
2be4b2
described above, SASL authentication has to be used.
2be4b2
---
2be4b2
 server/reds.c | 56 +++++++++++++++++++++++++++++++++++++++-----------------
2be4b2
 1 file changed, 39 insertions(+), 17 deletions(-)
2be4b2
2be4b2
diff --git a/server/reds.c b/server/reds.c
2be4b2
index c1edf67..9521416 100644
2be4b2
--- a/server/reds.c
2be4b2
+++ b/server/reds.c
2be4b2
@@ -1469,7 +1469,7 @@ static int reds_send_link_ack(RedLinkInfo *link)
2be4b2
     RedChannel *channel;
2be4b2
     RedChannelCapabilities *channel_caps;
2be4b2
     BUF_MEM *bmBuf;
2be4b2
-    BIO *bio;
2be4b2
+    BIO *bio = NULL;
2be4b2
     int ret = FALSE;
2be4b2
 
2be4b2
     header.magic = SPICE_MAGIC;
2be4b2
@@ -1494,24 +1494,45 @@ static int reds_send_link_ack(RedLinkInfo *link)
2be4b2
     ack.num_channel_caps = channel_caps->num_caps;
2be4b2
     header.size += (ack.num_common_caps + ack.num_channel_caps) * sizeof(uint32_t);
2be4b2
     ack.caps_offset = sizeof(SpiceLinkReply);
2be4b2
+    if (!sasl_enabled
2be4b2
+        || !red_link_info_test_capability(link, SPICE_COMMON_CAP_AUTH_SASL)) {
2be4b2
+        if (!(link->tiTicketing.rsa = RSA_new())) {
2be4b2
+            spice_warning("RSA new failed");
2be4b2
+            return FALSE;
2be4b2
+        }
2be4b2
 
2be4b2
-    if (!(link->tiTicketing.rsa = RSA_new())) {
2be4b2
-        spice_warning("RSA nes failed");
2be4b2
-        return FALSE;
2be4b2
-    }
2be4b2
-
2be4b2
-    if (!(bio = BIO_new(BIO_s_mem()))) {
2be4b2
-        spice_warning("BIO new failed");
2be4b2
-        return FALSE;
2be4b2
-    }
2be4b2
+        if (!(bio = BIO_new(BIO_s_mem()))) {
2be4b2
+            spice_warning("BIO new failed");
2be4b2
+            return FALSE;
2be4b2
+        }
2be4b2
 
2be4b2
-    RSA_generate_key_ex(link->tiTicketing.rsa, SPICE_TICKET_KEY_PAIR_LENGTH, link->tiTicketing.bn,
2be4b2
-                        NULL);
2be4b2
-    link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
2be4b2
+        if (RSA_generate_key_ex(link->tiTicketing.rsa,
2be4b2
+                                SPICE_TICKET_KEY_PAIR_LENGTH,
2be4b2
+                                link->tiTicketing.bn,
2be4b2
+                                NULL) != 1) {
2be4b2
+            spice_warning("Failed to generate %d bits RSA key: %s",
2be4b2
+                          SPICE_TICKET_KEY_PAIR_LENGTH,
2be4b2
+                          ERR_error_string(ERR_get_error(), NULL));
2be4b2
+           goto end;
2be4b2
+        }
2be4b2
+        link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
2be4b2
 
2be4b2
-    i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
2be4b2
-    BIO_get_mem_ptr(bio, &bmBuf);
2be4b2
-    memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
2be4b2
+        i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
2be4b2
+        BIO_get_mem_ptr(bio, &bmBuf);
2be4b2
+        memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
2be4b2
+    } else {
2be4b2
+        /* if the client sets the AUTH_SASL cap, it indicates that it
2be4b2
+         * supports SASL, and will use it if the server supports SASL as
2be4b2
+         * well. Moreover, a client setting the AUTH_SASL cap also
2be4b2
+         * indicates that it will not try using the RSA-related content
2be4b2
+         * in the SpiceLinkReply message, so we don't need to initialize
2be4b2
+         * it. Reason to avoid this is to fix auth in fips mode where
2be4b2
+         * the generation of a 1024 bit RSA key as we are trying to do
2be4b2
+         * will fail.
2be4b2
+         */
2be4b2
+         spice_warning("not initialising RSA key");
2be4b2
+         memset(ack.pub_key, '\0', sizeof(ack.pub_key));
2be4b2
+    }
2be4b2
 
2be4b2
     if (!sync_write(link->stream, &header, sizeof(header)))
2be4b2
         goto end;
2be4b2
@@ -1525,7 +1546,8 @@ static int reds_send_link_ack(RedLinkInfo *link)
2be4b2
     ret = TRUE;
2be4b2
 
2be4b2
 end:
2be4b2
-    BIO_free(bio);
2be4b2
+    if (bio != NULL)
2be4b2
+        BIO_free(bio);
2be4b2
     return ret;
2be4b2
 }
2be4b2
 
2be4b2
-- 
2be4b2
2.4.4
2be4b2