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 */