RSAREF can't handle RSA keys longer than 1024 bits (and we're not allowed
to fix it so that it can, by the terms of the RSAREF license). This is a
problem for OpenSSH, because it can't be used to interoperate with
servers (or clients) which use long keys. Currently it gives a very
non-helpful error message:

rsa_private_encrypt() failed.

The attached patch detects when it is failing because it's being used with
RSAREF and a long key, and returns the error:

rsa_private_encrypt() failed: RSAREF cannot handle keys larger than 1024 bits.

It does this by adding a RSA_libversion() function to the librsausa and
librsaintl libraries so libcrypto users can work out which version they
are actually using (I tried to do this with just an "int RSA_libversion",
but I was having problems getting the symbol to be found at link time).

I've tested it through a make world and with sshd servers that have large
and small keys - I haven't tested it for international OpenSSH users. The
patch takes the openssh/rsa.c file off the vendor branch. There's also a
new file added, crypto/openssl/crypto/rsa/rsa_intlstubs.c.

I'd like to get this committed for 4.0 if I have some more positive
feedback from people.

Kris

Index: crypto/openssh/rsa.c
===================================================================
RCS file: /home/ncvs/src/crypto/openssh/rsa.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 rsa.c
--- crypto/openssh/rsa.c        2000/02/24 14:29:45     1.1.1.1
+++ crypto/openssh/rsa.c        2000/03/12 03:19:52
@@ -125,7 +125,10 @@
 
        if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key,
            RSA_PKCS1_PADDING)) <= 0)
-               fatal("rsa_public_encrypt() failed");
+           if (BN_num_bits(key->n) > 1024 && RSA_libversion() == RSALIB_RSAREF)
+               fatal("rsa_private_encrypt() failed: RSAREF cannot handle keys larger 
+than 1024 bits.");
+           else
+               fatal("rsa_private_encrypt() failed.");
 
        BN_bin2bn(outbuf, len, out);
 
@@ -150,7 +153,10 @@
 
        if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key,
            RSA_PKCS1_PADDING)) <= 0)
-               fatal("rsa_private_decrypt() failed");
+           if (BN_num_bits(key->n) > 1024 && RSA_libversion() == RSALIB_RSAREF)
+               fatal("rsa_private_decrypt() failed: RSAREF cannot handle keys larger 
+than 1024 bits.");
+           else
+               fatal("rsa_private_decrypt() failed.");
 
        BN_bin2bn(outbuf, len, out);
 
Index: crypto/openssl/crypto/rsa/rsa.h
===================================================================
RCS file: /home/ncvs/src/crypto/openssl/crypto/rsa/rsa.h,v
retrieving revision 1.2
diff -u -r1.2 rsa.h
--- crypto/openssl/crypto/rsa/rsa.h     2000/02/26 13:13:02     1.2
+++ crypto/openssl/crypto/rsa/rsa.h     2000/03/12 03:02:07
@@ -244,6 +244,8 @@
 int RSA_set_ex_data(RSA *r,int idx,char *arg);
 char *RSA_get_ex_data(RSA *r, int idx);
 
+int RSA_libversion();
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -307,6 +309,9 @@
 #define RSA_R_UNKNOWN_ALGORITHM_TYPE                    117
 #define RSA_R_UNKNOWN_PADDING_TYPE                      118
 #define RSA_R_WRONG_SIGNATURE_LENGTH                    119
+
+#define RSALIB_OPENSSL 1
+#define RSALIB_RSAREF  2
 
 #ifdef  __cplusplus
 }
Index: crypto/openssl/crypto/rsa/rsa_stubs.c
===================================================================
RCS file: /home/ncvs/src/crypto/openssl/crypto/rsa/rsa_stubs.c,v
retrieving revision 1.4
diff -u -r1.4 rsa_stubs.c
--- crypto/openssl/crypto/rsa/rsa_stubs.c       2000/03/02 06:21:02     1.4
+++ crypto/openssl/crypto/rsa/rsa_stubs.c       2000/03/12 03:03:13
@@ -87,6 +87,16 @@
 }
 __weak_reference(ERR_load_RSA_strings_stub, ERR_load_RSA_strings);
 
+int
+RSA_libversion_stub(void)
+{
+    static void (*sym)(void);
+
+    if (sym || (sym = getsym("RSA_libversion")))
+       sym();
+}
+__weak_reference(RSA_libversion_stub, RSA_libversion);
+
 #else  /* !PIC */
 
 /* Sigh, just get your own libs, ld(1) doesn't deal with weaks here */
Index: crypto/openssl/rsaref/rsaref_stubs.c
===================================================================
RCS file: /home/ncvs/src/crypto/openssl/rsaref/rsaref_stubs.c,v
retrieving revision 1.5
diff -u -r1.5 rsaref_stubs.c
--- crypto/openssl/rsaref/rsaref_stubs.c        2000/03/02 06:21:02     1.5
+++ crypto/openssl/rsaref/rsaref_stubs.c        2000/03/12 03:10:46
@@ -40,6 +40,7 @@
 #ifndef NO_RSA
 
 #include <stdio.h>
+#include <openssl/rsa.h>
 
 #define VERBOSE_STUBS  /* undef if you don't want missing rsaref reported */
 
@@ -164,6 +165,12 @@
     return 0;
 }
 __weak_reference(R_RandomUpdate_stub, R_RandomUpdate);
+
+int
+RSA_libversion()
+{
+       return RSALIB_RSAREF;
+}
 
 #else  /* !PIC */
 
Index: secure//lib/librsaintl/Makefile
===================================================================
RCS file: /home/ncvs/src/secure/lib/librsaintl/Makefile,v
retrieving revision 1.1
diff -u -r1.1 Makefile
--- secure//lib/librsaintl/Makefile     2000/02/26 13:12:57     1.1
+++ secure//lib/librsaintl/Makefile     2000/03/12 07:12:31
@@ -11,7 +11,7 @@
 CFLAGS+=       -I${.OBJDIR}
 
 # rsaref
-SRCS+= rsa_err.c rsa_eay.c
+SRCS+= rsa_err.c rsa_eay.c rsa_intlstubs.c
 
 HDRS=  asn1/asn1.h asn1/asn1_mac.h bio/bio.h bf/blowfish.h bn/bn.h \
        buffer/buffer.h cast/cast.h comp/comp.h conf/conf.h crypto.h \

----
In God we Trust -- all others must submit an X.509 certificate.
    -- Charles Forsythe <[EMAIL PROTECTED]>
/*-
 * Copyright (c) 2000 Kris Kennaway <[EMAIL PROTECTED]>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE. SO THERE.
 *
 * $FreeBSD$
 */

#ifndef NO_RSA
#ifdef PIC
#include <openssl/rsa.h>

int RSA_libversion()
{
        return RSALIB_OPENSSL;
}

#endif /* PIC */
#endif /* NO_RSA */

Reply via email to