Apply Lutz Behnke's 56 bit cipher patch with a few
minor changes.

Docs haven't been added at this stage. They are probably
best included in the 'ciphers' program docs.
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index b8f43c2..7b9d29d 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -155,6 +155,19 @@
 #define DEC32(a)	((a)=((a)-1)&0xffffffffL)
 #define MAX_MAC_SIZE	20 /* up from 16 for SSLv3 */
 
+/*
+ * Define the Bitmasks for SSL_CIPHER.algorithms.
+ * This bits are used packed as dense as possible. If new methods/ciphers
+ * etc will be added, the bits a likely to change, so this information
+ * is for internal library use only, even though SSL_CIPHER.algorithms
+ * can be publicly accessed.
+ * Use the according functions for cipher management instead.
+ *
+ * The bit mask hendling in the selection and sorting scheme in
+ * ssl_create_cipher_list() has only limited capabilities, reflecting
+ * that the different entities within are mutually exclusiv:
+ * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
+ */
 #define SSL_MKEY_MASK		0x0000001FL
 #define SSL_kRSA		0x00000001L /* RSA key exchange */
 #define SSL_kDHr		0x00000002L /* DH cert RSA CA cert */
@@ -191,36 +204,75 @@
 #define SSL_SHA1		0x00040000L
 #define SSL_SHA			(SSL_SHA1)
 
-#define SSL_EXP_MASK		0x00300000L
-#define SSL_EXP40		0x00100000L
-#define SSL_NOT_EXP		0x00200000L
-#define SSL_EXP56		0x00300000L
-#define SSL_IS_EXPORT(a)	((a)&SSL_EXP40)
-#define SSL_IS_EXPORT56(a)	(((a)&SSL_EXP_MASK) == SSL_EXP56)
-#define SSL_IS_EXPORT40(a)	(((a)&SSL_EXP_MASK) == SSL_EXP40)
-#define SSL_C_IS_EXPORT(c)	SSL_IS_EXPORT((c)->algorithms)
-#define SSL_C_IS_EXPORT56(c)	SSL_IS_EXPORT56((c)->algorithms)
-#define SSL_C_IS_EXPORT40(c)	SSL_IS_EXPORT40((c)->algorithms)
-#define SSL_EXPORT_KEYLENGTH(a)	(SSL_IS_EXPORT40(a) ? 5 : \
-				 ((a)&SSL_ENC_MASK) == SSL_DES ? 8 : 7)
-#define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
-#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithms)
-#define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algorithms)
-
-#define SSL_SSL_MASK		0x00c00000L
-#define SSL_SSLV2		0x00400000L
-#define SSL_SSLV3		0x00800000L
+#define SSL_SSL_MASK		0x00180000L
+#define SSL_SSLV2		0x00080000L
+#define SSL_SSLV3		0x00100000L
 #define SSL_TLSV1		SSL_SSLV3	/* for now */
 
-#define SSL_STRONG_MASK		0x07000000L
-#define SSL_LOW			0x01000000L
-#define SSL_MEDIUM		0x02000000L
-#define SSL_HIGH		0x04000000L
+/* we have used 001fffff - 11 bits left to go */
 
-/* we have used 0fffffff - 4 bits left to go */
+/*
+ * Export and cipher strenght information. For each cipher we have to decide
+ * whether it is exportable or not. This information is likely to change
+ * over time, since the export control rules are no static technical issue.
+ *
+ * Independent of the export flag the cipher strength is sorted into classes.
+ * SSL_EXP40 was denoting the 40bit US export limit of past times, which now
+ * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change
+ * againg (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more,
+ * since SSL_EXP64 could be similar to SSL_LOW.
+ * For this reason SSL_MICRO and SSL_MINI macros are included to widen the
+ * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed
+ * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would
+ * be possible.
+ */
+#define SSL_EXP_MASK		0x00000003L
+#define SSL_NOT_EXP		0x00000001L
+#define SSL_EXPORT		0x00000002L
+
+#define SSL_STRONG_MASK		0x0000007cL
+#define SSL_EXP40		0x00000004L
+#define SSL_MICRO		(SSL_EXP40)
+#define SSL_EXP56		0x00000008L
+#define SSL_MINI		(SSL_EXP56)
+#define SSL_LOW			0x00000010L
+#define SSL_MEDIUM		0x00000020L
+#define SSL_HIGH		0x00000040L
+
+/* we have used 0000007f - 25 bits left to go */
+
+/*
+ * Macros to check the export status and cipher strength for export ciphers.
+ * Even though the macros for EXPORT and EXPORT40/56 have similar names,
+ * their meaning is different:
+ * *_EXPORT macros check the 'exportable' status.
+ * *_EXPORT40/56 macros are used to check whether a certain cipher strength
+ *          is given.
+ * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct
+ * algorithm structure element to be passed (algorithms, algo_strength) and no
+ * typechecking can be done as they are all of type unsigned long, their
+ * direct usage is discouraged.
+ * Use the SSL_C_* macros instead.
+ */
+#define SSL_IS_EXPORT(a)	((a)&SSL_EXPORT)
+#define SSL_IS_EXPORT56(a)	((a)&SSL_EXP56)
+#define SSL_IS_EXPORT40(a)	((a)&SSL_EXP40)
+#define SSL_C_IS_EXPORT(c)	SSL_IS_EXPORT((c)->algo_strength)
+#define SSL_C_IS_EXPORT56(c)	SSL_IS_EXPORT56((c)->algo_strength)
+#define SSL_C_IS_EXPORT40(c)	SSL_IS_EXPORT40((c)->algo_strength)
+
+#define SSL_EXPORT_KEYLENGTH(a,s)	(SSL_IS_EXPORT40(s) ? 5 : \
+				 ((a)&SSL_ENC_MASK) == SSL_DES ? 8 : 7)
+#define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
+#define SSL_C_EXPORT_KEYLENGTH(c)	SSL_EXPORT_KEYLENGTH((c)->algorithms, \
+				(c)->algo_strength)
+#define SSL_C_EXPORT_PKEYLENGTH(c)	SSL_EXPORT_PKEYLENGTH((c)->algo_strength)
+
+
 #define SSL_ALL			0xffffffffL
 #define SSL_ALL_CIPHERS		(SSL_MKEY_MASK|SSL_AUTH_MASK|SSL_ENC_MASK|\
-				SSL_MAC_MASK|SSL_EXP_MASK)
+				SSL_MAC_MASK)
+#define SSL_ALL_STRENGTHS	(SSL_EXP_MASK|SSL_STRONG_MASK)
 
 /* Mostly for SSLv3 */
 #define SSL_PKEY_RSA_ENC	0
@@ -256,7 +308,7 @@
 	CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
 					 * Probably it would make more sense to store
 					 * an index, not a pointer. */
-
+ 
 	/* The following masks are for the key and auth
 	 * algorithms that are supported by the certs below */
 	int valid;
@@ -376,10 +428,10 @@
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
 					       STACK_OF(SSL_CIPHER) **skp);
 int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p);
-STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_METHOD *meth,
+STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
 					     STACK_OF(SSL_CIPHER) **pref,
 					     STACK_OF(SSL_CIPHER) **sorted,
-					     char *str);
+					     const char *rule_str);
 void ssl_update_cache(SSL *s, int mode);
 int ssl_cipher_get_evp(SSL_SESSION *s,const EVP_CIPHER **enc,const EVP_MD **md,
 		       SSL_COMP **comp);