diff --git a/lib/modules/SSL.pmod/Cipher.pmod b/lib/modules/SSL.pmod/Cipher.pmod
index 31572390049c4091492eaf3309adeaf8ac9328d7..cefce284ab939b7f13d55127a1eb76668dc0e801 100644
--- a/lib/modules/SSL.pmod/Cipher.pmod
+++ b/lib/modules/SSL.pmod/Cipher.pmod
@@ -51,6 +51,10 @@ class CipherSpec {
   //! The Message Authentication Code to use for the packets.
   program(MACAlgorithm) mac_algorithm;
 
+  //! Indication whether the combination uses strong or weak
+  //! (aka exportable) crypto.
+  int is_exportable;
+
   //! The number of bytes in the MAC hashes.
   int hash_size;
 
@@ -455,6 +459,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_rc4_40:
     res->bulk_cipher_algorithm = Nettle.ARCFOUR_State;
     res->cipher_type = CIPHER_stream;
+    res->is_exportable = 1;
     res->key_material = 16;
     res->iv_size = 0;
     res->key_bits = 40;
@@ -462,6 +467,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_des40:
     res->bulk_cipher_algorithm = DES;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 1;
     res->key_material = 8;
     res->iv_size = 8;
     res->key_bits = 40;
@@ -469,13 +475,16 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_null:
     res->bulk_cipher_algorithm = 0;
     res->cipher_type = CIPHER_stream;
+    res->is_exportable = 1;
     res->key_material = 0;
     res->iv_size = 0;
     res->key_bits = 0;
     break;
+#ifndef WEAK_CRYPTO_40BIT
   case CIPHER_rc4:
     res->bulk_cipher_algorithm = Nettle.ARCFOUR_State;
     res->cipher_type = CIPHER_stream;
+    res->is_exportable = 0;
     res->key_material = 16;
     res->iv_size = 0;
     res->key_bits = 128;
@@ -483,6 +492,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_des:
     res->bulk_cipher_algorithm = DES;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 0;
     res->key_material = 8;
     res->iv_size = 8;
     res->key_bits = 56;
@@ -490,6 +500,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_3des:
     res->bulk_cipher_algorithm = DES3;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 0;
     res->key_material = 24;
     res->iv_size = 8;
     res->key_bits = 168;
@@ -497,6 +508,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_idea:
     res->bulk_cipher_algorithm = IDEA;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 0;
     res->key_material = 16;
     res->iv_size = 8;
     res->key_bits = 128;
@@ -504,6 +516,7 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_aes:
     res->bulk_cipher_algorithm = AES;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 0;
     res->key_material = 16;
     res->iv_size = 16;
     res->key_bits = 128;
@@ -511,10 +524,12 @@ array lookup(int suite, ProtocolVersion|int version)
   case CIPHER_aes256:
     res->bulk_cipher_algorithm = AES;
     res->cipher_type = CIPHER_block;
+    res->is_exportable = 0;
     res->key_material = 32;
     res->iv_size = 16;
     res->key_bits = 256;
     break;
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
   default:
     return 0;
   }
diff --git a/lib/modules/SSL.pmod/Constants.pmod b/lib/modules/SSL.pmod/Constants.pmod
index 1f5cfe30c5a14729c5a3d79fb53a276540dd6493..aaf3202dd6b2f7cd985e836b60e0fe84b0fe6e04 100644
--- a/lib/modules/SSL.pmod/Constants.pmod
+++ b/lib/modules/SSL.pmod/Constants.pmod
@@ -61,6 +61,7 @@ constant CIPHER_null     = 0;
 constant CIPHER_rc4_40   = 2;
 constant CIPHER_rc2      = 3;
 constant CIPHER_des40    = 6;
+#ifndef WEAK_CRYPTO_40BIT
 constant CIPHER_rc4      = 1;
 constant CIPHER_des      = 4;
 constant CIPHER_3des     = 5;
@@ -68,6 +69,7 @@ constant CIPHER_fortezza = 7;
 constant CIPHER_idea	 = 8;
 constant CIPHER_aes	 = 9;
 constant CIPHER_aes256	 = 10;
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
 
 //! Mapping from cipher algorithm to effective key length.
 constant CIPHER_algorithms = ([
@@ -75,6 +77,7 @@ constant CIPHER_algorithms = ([
   CIPHER_rc4_40:	40,
   CIPHER_rc2:		40,
   CIPHER_des40:		40,
+#ifndef WEAK_CRYPTO_40BIT
   CIPHER_rc4:		128,
   CIPHER_des:		56,
   CIPHER_3des:		168,
@@ -82,6 +85,7 @@ constant CIPHER_algorithms = ([
   CIPHER_idea:		128,
   CIPHER_aes:		128,
   CIPHER_aes256:	256,
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
 ]);
 
 /* Hash algorithms as per RFC 5246 7.4.1.4.1. */
@@ -205,6 +209,7 @@ constant TLS_krb5_with_rc4_40_sha               = 0x0028;
 constant TLS_krb5_with_des_cbc_40_md5           = 0x0029;
 constant TLS_krb5_with_rc2_cbc_40_md5           = 0x002a;
 constant TLS_krb5_with_rc4_40_md5               = 0x002b;
+#ifndef WEAK_CRYPTO_40BIT
 constant SSL_rsa_with_rc4_128_md5		= 0x0004;
 constant SSL_rsa_with_rc4_128_sha		= 0x0005;
 constant SSL_rsa_with_idea_cbc_sha		= 0x0007;
@@ -384,6 +389,7 @@ constant TLS_ecdhe_psk_with_aes_256_cbc_sha384  = 0xc038;
 constant TLS_ecdhe_psk_with_null_sha            = 0xc039;
 constant TLS_ecdhe_psk_with_null_sha256         = 0xc03a;
 constant TLS_ecdhe_psk_with_null_sha384         = 0xc03b;
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
 
 #if 0
 /* Methods for signing any server_key_exchange message (RFC 5246 7.4.1.4.1) */
@@ -402,6 +408,7 @@ constant CIPHER_SUITES =
    SSL_rsa_export_with_rc4_40_md5 :	({ KE_rsa, CIPHER_rc4_40, HASH_md5 }),
    SSL_dhe_dss_export_with_des40_cbc_sha :
       ({ KE_dhe_dss, CIPHER_des40, HASH_sha }),
+#ifndef WEAK_CRYPTO_40BIT
    SSL_rsa_with_rc4_128_sha :		({ KE_rsa, CIPHER_rc4, HASH_sha }),
    SSL_rsa_with_rc4_128_md5 :		({ KE_rsa, CIPHER_rc4, HASH_md5 }),
    SSL_rsa_with_idea_cbc_sha :		({ KE_rsa, CIPHER_idea, HASH_sha }),
@@ -413,9 +420,11 @@ constant CIPHER_SUITES =
    TLS_dhe_dss_with_aes_128_cbc_sha :	({ KE_dhe_dss, CIPHER_aes, HASH_sha }),
    TLS_rsa_with_aes_256_cbc_sha :	({ KE_rsa, CIPHER_aes256, HASH_sha }),
    TLS_dhe_dss_with_aes_256_cbc_sha :	({ KE_dhe_dss, CIPHER_aes256, HASH_sha }),
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
 ]);
 
 constant preferred_rsa_suites = ({
+#ifndef WEAK_CRYPTO_40BIT
   TLS_rsa_with_aes_256_cbc_sha,
   TLS_rsa_with_aes_128_cbc_sha,		// Mandatory in RFC 5246 (TLS 1.2).
   SSL_rsa_with_idea_cbc_sha,
@@ -423,16 +432,19 @@ constant preferred_rsa_suites = ({
   SSL_rsa_with_rc4_128_md5,
   SSL_rsa_with_3des_ede_cbc_sha,	// Mandatory in RFC 2246 (TLS 1.0).
   SSL_rsa_with_des_cbc_sha,
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
   SSL_rsa_export_with_rc4_40_md5,
   SSL_rsa_with_null_sha,
   SSL_rsa_with_null_md5,
 });
 
 constant preferred_dhe_dss_suites = ({
+#ifndef WEAK_CRYPTO_40BIT
   TLS_dhe_dss_with_aes_256_cbc_sha,
   TLS_dhe_dss_with_aes_128_cbc_sha,
   SSL_dhe_dss_with_3des_ede_cbc_sha,	// Mandatory in RFC 2246 (TLS 1.0).
   SSL_dhe_dss_with_des_cbc_sha,
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
   SSL_dhe_dss_export_with_des40_cbc_sha,
 });
 
diff --git a/lib/modules/SSL.pmod/context.pike b/lib/modules/SSL.pmod/context.pike
index f61c4ef0e50c7ab9be2e9a61ac5501dc11f6240c..39108f39572d8a7f5862c932fb0dd0a6703757fc 100644
--- a/lib/modules/SSL.pmod/context.pike
+++ b/lib/modules/SSL.pmod/context.pike
@@ -152,9 +152,15 @@ int verify_certificates = 0;
 //! Temporary, non-certified, private keys, used with a
 //! server_key_exchange message. The rules are as follows:
 //!
-//! If the long_rsa is not zero its public part will be sent. If it is
-//! zero and short_rsa is set, its public part will be sent instead.
-//! If they are both zero, no server_key_exchange message is sent.
+//! If the negotiated cipher_suite has the "exportable" property, and
+//! short_rsa is not zero, send a server_key_exchange message with the
+//! (public part of) the short_rsa key.
+//!
+//! If the negotiated cipher_suite does not have the exportable
+//! property, and long_rsa is not zero, send a server_key_exchange
+//! message with the (public part of) the long_rsa key.
+//!
+//! Otherwise, dont send any server_key_exchange message.
 Crypto.RSA long_rsa;
 Crypto.RSA short_rsa;
 
diff --git a/lib/modules/SSL.pmod/handshake.pike b/lib/modules/SSL.pmod/handshake.pike
index 96c20311eb8749d7242687125388eab42b5e443e..47b590cb811dd0e33c3a2e8324e7ae70991e1c71 100644
--- a/lib/modules/SSL.pmod/handshake.pike
+++ b/lib/modules/SSL.pmod/handshake.pike
@@ -291,8 +291,14 @@ Packet server_key_exchange_packet()
   switch (session->ke_method)
   {
   case KE_rsa:
-    temp_key = context->long_rsa || context->short_rsa;
-
+#ifdef WEAK_CRYPTO_40BIT
+    temp_key = context->short_rsa;
+#endif /* WEAK_CRYPTO_40BIT (magic comment) */
+#ifndef WEAK_CRYPTO_40BIT
+    temp_key = (session->cipher_spec->is_exportable
+		? context->short_rsa
+		: context->long_rsa);
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
     if (temp_key)
     {
       /* Send a ServerKeyExchange message. */
diff --git a/lib/modules/SSL.pmod/session.pike b/lib/modules/SSL.pmod/session.pike
index 1d2be7de72da9266763da5a1637d94b2d956ef74..74c80225707402862e09c17a617330d650aa35b2 100644
--- a/lib/modules/SSL.pmod/session.pike
+++ b/lib/modules/SSL.pmod/session.pike
@@ -81,9 +81,17 @@ void set_compression_method(int compr)
 protected string generate_key_block(string client_random, string server_random,
 			  array(int) version)
 {
-  int required = 2 * ( cipher_spec->key_material +
-                       cipher_spec->hash_size +
-                       cipher_spec->iv_size );
+  int required = 2 * (
+#ifndef WEAK_CRYPTO_40BIT
+    cipher_spec->is_exportable ?
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
+    (5 + cipher_spec->hash_size)
+#ifndef WEAK_CRYPTO_40BIT
+    : ( cipher_spec->key_material +
+	cipher_spec->hash_size +
+	cipher_spec->iv_size)
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
+  );
   string key = "";
 
   if(version[1] == PROTOCOL_SSL_3_0) {
@@ -163,13 +171,66 @@ array(string) generate_keys(string client_random, string server_random,
   // server_write_MAC_secret
   keys[1] = key_data->get_fix_string(cipher_spec->hash_size);
 
-  keys[2] = key_data->get_fix_string(cipher_spec->key_material);
-  keys[3] = key_data->get_fix_string(cipher_spec->key_material);
-  if (cipher_spec->iv_size)
+#ifndef WEAK_CRYPTO_40BIT
+  if (cipher_spec->is_exportable)
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
   {
-    keys[4] = key_data->get_fix_string(cipher_spec->iv_size);
-    keys[5] = key_data->get_fix_string(cipher_spec->iv_size);
+    // Exportable (ie weak) crypto.
+    if(version[1] == PROTOCOL_SSL_3_0) {
+      // SSL 3.0
+      function(string:string) md5 = .Cipher.MACmd5()->hash_raw;
+      
+      keys[2] = md5(key_data->get_fix_string(5) +
+		    client_random + server_random)
+	[..cipher_spec->key_material-1];
+      keys[3] = md5(key_data->get_fix_string(5) +
+		    server_random + client_random)
+	[..cipher_spec->key_material-1];
+      if (cipher_spec->iv_size)
+	{
+	  keys[4] = md5(client_random +
+			server_random)[..cipher_spec->iv_size-1];
+	  keys[5] = md5(server_random +
+			client_random)[..cipher_spec->iv_size-1];
+	}
+
+    } else if(version[1] >= PROTOCOL_TLS_1_0) {
+      // TLS 1.0 or later.
+      string client_wkey = key_data->get_fix_string(5);
+      string server_wkey = key_data->get_fix_string(5);
+      keys[2] = .Cipher.prf(client_wkey, "client write key",
+			    client_random+server_random,
+			    cipher_spec->key_material);
+      keys[3] = .Cipher.prf(server_wkey, "server write key",
+			    client_random+server_random,
+			    cipher_spec->key_material);
+      if(cipher_spec->iv_size) {
+	string iv_block = .Cipher.prf("", "IV block",
+				      client_random+server_random,
+				      2*cipher_spec->iv_size);
+	keys[4]=iv_block[..cipher_spec->iv_size-1];
+	keys[5]=iv_block[cipher_spec->iv_size..];
+#ifdef SSL3_DEBUG
+	werror("sizeof(keys[4]):%d  sizeof(keys[5]):%d\n",
+	       sizeof([string]keys[4]), sizeof([string]keys[4]));
+#endif
+      }
+
+    }
+    
+  }
+  
+#ifndef WEAK_CRYPTO_40BIT
+  else {
+    keys[2] = key_data->get_fix_string(cipher_spec->key_material);
+    keys[3] = key_data->get_fix_string(cipher_spec->key_material);
+    if (cipher_spec->iv_size)
+      {
+	keys[4] = key_data->get_fix_string(cipher_spec->iv_size);
+	keys[5] = key_data->get_fix_string(cipher_spec->iv_size);
+      }
   }
+#endif /* !WEAK_CRYPTO_40BIT (magic comment) */
 
 #ifdef SSL3_DEBUG
   printKey( "client_write_MAC_secret",keys[0]);