]> andersk Git - openssh.git/commitdiff
- (djm) OpenBSD CVS Sync:
authordjm <djm>
Mon, 29 Jan 2001 22:27:26 +0000 (22:27 +0000)
committerdjm <djm>
Mon, 29 Jan 2001 22:27:26 +0000 (22:27 +0000)
   - markus@cvs.openbsd.org  2001/01/29 12:47:32
     [rsa.c rsa.h ssh-agent.c sshconnect1.c sshd.c]
     handle rsa_private_decrypt failures; helps against the Bleichenbacher
     pkcs#1 attack

ChangeLog
rsa.c
rsa.h
ssh-agent.c
sshconnect1.c
sshd.c

index 250ab58af4a7de28315c75f6549ec2aa4d4a5bd1..9c97a128735f8fbd931c80458cf3991720e700d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
    - markus@cvs.openbsd.org  2001/01/29 12:42:35
      [canohost.c canohost.h channels.c clientloop.c]
      add get_peer_ipaddr(socket), x11-fwd in ssh2 requires ipaddr, not DNS
+   - markus@cvs.openbsd.org  2001/01/29 12:47:32
+     [rsa.c rsa.h ssh-agent.c sshconnect1.c sshd.c]
+     handle rsa_private_decrypt failures; helps against the Bleichenbacher
+     pkcs#1 attack
 
 20000129
  - (stevesk) sftp-server.c: use %lld vs. %qd
diff --git a/rsa.c b/rsa.c
index 04bb239e5324796ffe39bfc079ceb17e9e5a46a7..1005246077b320ec2742c7f8d7cc04e480d1a226 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -60,7 +60,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: rsa.c,v 1.19 2001/01/21 19:05:54 markus Exp $");
+RCSID("$OpenBSD: rsa.c,v 1.20 2001/01/29 19:47:30 markus Exp $");
 
 #include "rsa.h"
 #include "log.h"
@@ -94,7 +94,7 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
        xfree(inbuf);
 }
 
-void
+int
 rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
 {
        u_char *inbuf, *outbuf;
@@ -108,13 +108,14 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
        BN_bn2bin(in, inbuf);
 
        if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key,
-           RSA_PKCS1_PADDING)) <= 0)
-               fatal("rsa_private_decrypt() failed");
-
-       BN_bin2bn(outbuf, len, out);
-
+           RSA_PKCS1_PADDING)) <= 0) {
+               error("rsa_private_decrypt() failed");
+       } else {
+               BN_bin2bn(outbuf, len, out);
+       }
        memset(outbuf, 0, olen);
        memset(inbuf, 0, ilen);
        xfree(outbuf);
        xfree(inbuf);
+       return len;
 }
diff --git a/rsa.h b/rsa.h
index 57d72cc789277effa5711baf056ab6230c8be56a..713d3128191da01fe16ceda6f4ce5c8900593c62 100644 (file)
--- a/rsa.h
+++ b/rsa.h
@@ -11,7 +11,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: rsa.h,v 1.9 2000/11/12 19:50:38 markus Exp $"); */
+/* RCSID("$OpenBSD: rsa.h,v 1.10 2001/01/29 19:47:30 markus Exp $"); */
 
 #ifndef RSA_H
 #define RSA_H
@@ -20,6 +20,6 @@
 #include <openssl/rsa.h>
 
 void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
-void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
+int rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
 
 #endif                         /* RSA_H */
index 539f8ce7d58fbaaf5a6e08ad4086dfc0670a7129..deed3ecae881944b1c5edb02612341231fb74a9a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-agent.c,v 1.48 2001/01/25 08:06:33 deraadt Exp $  */
+/*     $OpenBSD: ssh-agent.c,v 1.49 2001/01/29 19:47:31 markus Exp $   */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.48 2001/01/25 08:06:33 deraadt Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.49 2001/01/29 19:47:31 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -198,7 +198,8 @@ process_authentication_challenge1(SocketEntry *e)
        private = lookup_private_key(key, NULL, 1);
        if (private != NULL) {
                /* Decrypt the challenge using the private key. */
-               rsa_private_decrypt(challenge, challenge, private->rsa);
+               if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
+                       goto failure;
 
                /* The response is MD5 of decrypted challenge plus session id. */
                len = BN_num_bytes(challenge);
index 5a5a22227528a2cf37fe1205a4a9e0672e690e4e..e732806f3ffcd439b16eb3a055ca304c4b4def88 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.20 2001/01/22 23:06:40 markus Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.21 2001/01/29 19:47:31 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/evp.h>
@@ -163,14 +163,17 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
        int i, len;
 
        /* Decrypt the challenge using the private key. */
-       rsa_private_decrypt(challenge, challenge, prv);
+       /* XXX think about Bleichenbacher, too */
+       if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
+               packet_disconnect(
+                   "respond_to_rsa_challenge: rsa_private_decrypt failed");
 
        /* Compute the response. */
        /* The response is MD5 of decrypted challenge plus session id. */
        len = BN_num_bytes(challenge);
        if (len <= 0 || len > sizeof(buf))
-               packet_disconnect("respond_to_rsa_challenge: bad challenge length %d",
-                                 len);
+               packet_disconnect(
+                   "respond_to_rsa_challenge: bad challenge length %d", len);
 
        memset(buf, 0, sizeof(buf));
        BN_bn2bin(challenge, buf + sizeof(buf) - len);
diff --git a/sshd.c b/sshd.c
index d46e4aa8b051de98e06c430653b7fa997dded4f0..02fe2ec426885165c1b0eae6e51e637def373214 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.158 2001/01/28 10:37:26 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.159 2001/01/29 19:47:31 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -1186,6 +1186,7 @@ do_ssh1_kex(void)
 {
        int i, len;
        int plen, slen;
+       int rsafail = 0;
        BIGNUM *session_key_int;
        u_char session_key[SSH_SESSION_KEY_LENGTH];
        u_char cookie[8];
@@ -1296,7 +1297,7 @@ do_ssh1_kex(void)
         * with larger modulus first).
         */
        if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
-               /* Private key has bigger modulus. */
+               /* Server key has bigger modulus. */
                if (BN_num_bits(sensitive_data.server_key->rsa->n) <
                    BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
                        fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
@@ -1305,10 +1306,12 @@ do_ssh1_kex(void)
                            BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
                            SSH_KEY_BITS_RESERVED);
                }
-               rsa_private_decrypt(session_key_int, session_key_int,
-                   sensitive_data.server_key->rsa);
-               rsa_private_decrypt(session_key_int, session_key_int,
-                   sensitive_data.ssh1_host_key->rsa);
+               if (rsa_private_decrypt(session_key_int, session_key_int,
+                   sensitive_data.server_key->rsa) <= 0)
+                       rsafail++;
+               if (rsa_private_decrypt(session_key_int, session_key_int,
+                   sensitive_data.ssh1_host_key->rsa) <= 0)
+                       rsafail++;
        } else {
                /* Host key has bigger modulus (or they are equal). */
                if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
@@ -1319,10 +1322,12 @@ do_ssh1_kex(void)
                            BN_num_bits(sensitive_data.server_key->rsa->n),
                            SSH_KEY_BITS_RESERVED);
                }
-               rsa_private_decrypt(session_key_int, session_key_int,
-                   sensitive_data.ssh1_host_key->rsa);
-               rsa_private_decrypt(session_key_int, session_key_int,
-                   sensitive_data.server_key->rsa);
+               if (rsa_private_decrypt(session_key_int, session_key_int,
+                   sensitive_data.ssh1_host_key->rsa) < 0)
+                       rsafail++;
+               if (rsa_private_decrypt(session_key_int, session_key_int,
+                   sensitive_data.server_key->rsa) < 0)
+                       rsafail++;
        }
 
        compute_session_id(session_id, cookie,
@@ -1337,15 +1342,29 @@ do_ssh1_kex(void)
         * least significant 256 bits of the integer; the first byte of the
         * key is in the highest bits.
         */
-       BN_mask_bits(session_key_int, sizeof(session_key) * 8);
-       len = BN_num_bytes(session_key_int);
-       if (len < 0 || len > sizeof(session_key))
-               fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d",
-                   get_remote_ipaddr(),
-                   len, sizeof(session_key));
-       memset(session_key, 0, sizeof(session_key));
-       BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
-
+       if (!rsafail) {
+               BN_mask_bits(session_key_int, sizeof(session_key) * 8);
+               len = BN_num_bytes(session_key_int);
+               if (len < 0 || len > sizeof(session_key)) {
+                       error("do_connection: bad session key len from %s: "
+                           "session_key_int %d > sizeof(session_key) %d",
+                           get_remote_ipaddr(), len, sizeof(session_key));
+                       rsafail++;
+               } else {
+                       memset(session_key, 0, sizeof(session_key));
+                       BN_bn2bin(session_key_int,
+                           session_key + sizeof(session_key) - len);
+               }
+       }
+       if (rsafail) {
+               log("do_connection: generating a fake encryption key");
+               for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
+                       if (i % 4 == 0)
+                               rand = arc4random();
+                       session_key[i] = rand & 0xff;
+                       rand >>= 8;
+               }
+       }
        /* Destroy the decrypted integer.  It is no longer needed. */
        BN_clear_free(session_key_int);
 
This page took 0.169442 seconds and 5 git commands to generate.