Apply by doing: cd /usr/src patch -p0 < 021_ssl.patch And then rebuild and install OpenSSL: rm -fr /usr/obj/lib/libssl cd lib/libssl make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper prereq make -f Makefile.bsd-wrapper includes make -f Makefile.bsd-wrapper depend make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install Index: lib/libssl/src/crypto/mem.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/mem.c,v retrieving revision 1.4 retrieving revision 1.4.6.1 diff -u -r1.4 -r1.4.6.1 --- lib/libssl/src/crypto/mem.c 15 Dec 2000 02:57:02 -0000 1.4 +++ lib/libssl/src/crypto/mem.c 23 Feb 2003 16:16:02 -0000 1.4.6.1 @@ -174,6 +174,8 @@ { void *ret = NULL; + if (num < 0) return NULL; + allow_customize = 0; if (malloc_debug_func != NULL) { @@ -206,6 +208,8 @@ { void *ret = NULL; + if (num < 0) return NULL; + allow_customize = 0; if (malloc_debug_func != NULL) { @@ -225,6 +229,8 @@ void *CRYPTO_realloc(void *str, int num, const char *file, int line) { void *ret = NULL; + + if (num < 0) return NULL; if (realloc_debug_func != NULL) realloc_debug_func(str, NULL, num, file, line, 0); Index: lib/libssl/src/ssl/s3_pkt.c =================================================================== RCS file: /cvs/src/lib/libssl/src/ssl/s3_pkt.c,v retrieving revision 1.5 retrieving revision 1.5.4.1 diff -u -r1.5 -r1.5.4.1 --- lib/libssl/src/ssl/s3_pkt.c 22 Jun 2001 00:03:40 -0000 1.5 +++ lib/libssl/src/ssl/s3_pkt.c 22 Feb 2003 17:46:48 -0000 1.5.4.1 @@ -231,7 +231,7 @@ static int ssl3_get_record(SSL *s) { int ssl_major,ssl_minor,al; - int n,i,ret= -1; + int enc_err,n,i,ret= -1; SSL3_RECORD *rr; SSL_SESSION *sess; unsigned char *p; @@ -239,6 +239,8 @@ short version; unsigned int mac_size; int clear=0,extra; + int decryption_failed_or_bad_record_mac = 0; + unsigned char *mac = NULL; rr= &(s->s3->rrec); sess=s->session; @@ -342,16 +344,26 @@ /* decrypt in place in 'rr->input' */ rr->data=rr->input; - if (!s->method->ssl3_enc->enc(s,0)) + enc_err = s->method->ssl3_enc->enc(s,0); + if (enc_err <= 0) { - al=SSL_AD_DECRYPT_ERROR; - goto f_err; + if (enc_err == 0) + /* SSLerr() and ssl3_send_alert() have been called */ + goto err; + + /* Otherwise enc_err == -1, which indicates bad padding + * (rec->length has not been changed in this case). + * To minimize information leaked via timing, we will perform + * the MAC computation anyway. */ + decryption_failed_or_bad_record_mac = 1; } + #ifdef TLS_DEBUG printf("dec %d\n",rr->length); { unsigned int z; for (z=0; zlength; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); } printf("\n"); #endif + /* r->length is now the compressed data plus mac */ if ( (sess == NULL) || (s->enc_read_ctx == NULL) || @@ -364,26 +376,49 @@ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) { +#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ al=SSL_AD_RECORD_OVERFLOW; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; +#else + decryption_failed_or_bad_record_mac = 1; +#endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length < mac_size) + if (rr->length >= mac_size) { + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + else + { + /* record (minus padding) is too short to contain a MAC */ +#if 0 /* OK only for stream ciphers */ al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; +#else + decryption_failed_or_bad_record_mac = 1; + rr->length = 0; +#endif } - rr->length-=mac_size; i=s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + if (mac == NULL || memcmp(md, mac, mac_size) != 0) { - al=SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_MAC_DECODE); - ret= -1; - goto f_err; + decryption_failed_or_bad_record_mac = 1; } + } + + if (decryption_failed_or_bad_record_mac) + { + /* A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption + * failure is directly visible from the ciphertext anyway, + * we should not reveal which kind of error occured -- this + * might become visible to an attacker (e.g. via a logfile) */ + al=SSL_AD_BAD_RECORD_MAC; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto f_err; } /* r->length is now just compressed */ Index: lib/libssl/src/ssl/ssl.h =================================================================== RCS file: /cvs/src/lib/libssl/src/ssl/ssl.h,v retrieving revision 1.6 retrieving revision 1.6.4.2 diff -u -r1.6 -r1.6.4.2 --- lib/libssl/src/ssl/ssl.h 22 Jun 2001 00:03:40 -0000 1.6 +++ lib/libssl/src/ssl/ssl.h 22 Feb 2003 17:46:48 -0000 1.6.4.2 @@ -1403,6 +1403,7 @@ #define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 #define SSL_R_DATA_LENGTH_TOO_LONG 146 #define SSL_R_DECRYPTION_FAILED 147 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 1109 #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 #define SSL_R_DIGEST_CHECK_FAILED 149 #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 Index: lib/libssl/src/ssl/ssl_err.c =================================================================== RCS file: /cvs/src/lib/libssl/src/ssl/ssl_err.c,v retrieving revision 1.6 retrieving revision 1.6.4.2 diff -u -r1.6 -r1.6.4.2 --- lib/libssl/src/ssl/ssl_err.c 22 Jun 2001 00:03:41 -0000 1.6 +++ lib/libssl/src/ssl/ssl_err.c 22 Feb 2003 17:46:48 -0000 1.6.4.2 @@ -258,6 +258,7 @@ {SSL_R_DATA_BETWEEN_CCS_AND_FINISHED ,"data between ccs and finished"}, {SSL_R_DATA_LENGTH_TOO_LONG ,"data length too long"}, {SSL_R_DECRYPTION_FAILED ,"decryption failed"}, +{SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC,"decryption failed or bad record mac"}, {SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG ,"dh public value length is wrong"}, {SSL_R_DIGEST_CHECK_FAILED ,"digest check failed"}, {SSL_R_ENCRYPTED_LENGTH_TOO_LONG ,"encrypted length too long"},