Various PKCS#7 fixes to properly (maybe!) handle PKCS#7 enveloped data.
Containts elements of code by Sebastian Akerman <sak@parallelconsulting.com>
and made a bit less "naughty" by Steve.
diff --git a/CHANGES b/CHANGES
index 6ddc9cc..86cf1fa 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,10 @@
 
  Changes between 0.9.2b and 0.9.3
 
+  *) Various fixes to the EVP and PKCS#7 code. It may now be able to
+     handle PKCS#7 enveloped data properly.
+     [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
+
   *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
      copying pointers.  The cert_st handling is changed by this in
      various ways (and thus what used to be known as ctx->default_cert
diff --git a/STATUS b/STATUS
index b0561e2..ccc8b25 100644
--- a/STATUS
+++ b/STATUS
@@ -1,11 +1,11 @@
 
   OpenSSL STATUS                           Last modified at
-  ______________                           $Date: 1999/04/29 21:56:13 $
+  ______________                           $Date: 1999/05/10 00:47:37 $
 
   DEVELOPMENT STATE
 
     o  OpenSSL 0.9.3:  Under development...
-                       Proposed freeze  date: Mon May  8th, 1999
+                       Proposed freeze  date: Mon May 10th, 1999
                        Proposed release date: Mon May 17th, 1999
     o  OpenSSL 0.9.2b: Released on March    22th, 1999
     o  OpenSSL 0.9.1c: Released on December 23th, 1998
diff --git a/crypto/evp/e_cbc_r2.c b/crypto/evp/e_cbc_r2.c
index d6a568f..e7aa44d 100644
--- a/crypto/evp/e_cbc_r2.c
+++ b/crypto/evp/e_cbc_r2.c
@@ -155,9 +155,9 @@
 	int i;
 
 	i=EVP_CIPHER_key_length(e);
-	if 	(i == 128) return(RC2_128_MAGIC);
-	else if (i == 64)  return(RC2_64_MAGIC);
-	else if (i == 40)  return(RC2_40_MAGIC);
+	if 	(i == 16) return(RC2_128_MAGIC);
+	else if (i == 8)  return(RC2_64_MAGIC);
+	else if (i == 5)  return(RC2_40_MAGIC);
 	else return(0);
 	}
 
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index ccb7d51..ac21717 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -433,6 +433,7 @@
 #define EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
 #define EVP_CIPHER_CTX_get_app_data(e)	((e)->app_data)
 #define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
 
 #define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
 #define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
@@ -623,6 +624,8 @@
 int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
 int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b);
 
+int EVP_CIPHER_type(EVP_CIPHER *ctx);
+
 /* calls methods */
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
 int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 6b677fd..d49ae90 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -110,3 +110,29 @@
 		}
 	return(i);
 	}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int EVP_CIPHER_type(EVP_CIPHER *ctx)
+{
+	int nid;
+	nid = EVP_CIPHER_nid(ctx);
+
+	switch(nid) {
+
+		case NID_rc2_cbc:
+		case NID_rc2_64_cbc:
+		case NID_rc2_40_cbc:
+
+		return NID_rc2_cbc;
+
+		case NID_rc4:
+		case NID_rc4_40:
+
+		return NID_rc4;
+
+		default:
+
+		return nid;
+	}
+}
+
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 10a6304..05def89 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -61,9 +61,9 @@
  * perl obj_dat.pl < objects.h > obj_dat.h
  */
 
-#define NUM_NID 166
-#define NUM_SN 117
-#define NUM_LN 162
+#define NUM_NID 167
+#define NUM_SN 118
+#define NUM_LN 163
 #define NUM_OBJ 138
 
 static unsigned char lvalues[956]={
@@ -439,6 +439,7 @@
 {"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[939]),0},
 {"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8,
 	&(lvalues[947]),0},
+{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -489,6 +490,7 @@
 &(nid_objs[18]),/* "OU" */
 &(nid_objs[127]),/* "PKIX" */
 &(nid_objs[98]),/* "RC2-40-CBC" */
+&(nid_objs[166]),/* "RC2-64-CBC" */
 &(nid_objs[37]),/* "RC2-CBC" */
 &(nid_objs[39]),/* "RC2-CFB" */
 &(nid_objs[38]),/* "RC2-ECB" */
@@ -688,6 +690,7 @@
 &(nid_objs[151]),/* "pkcs8ShroudedKeyBag" */
 &(nid_objs[47]),/* "pkcs9" */
 &(nid_objs[98]),/* "rc2-40-cbc" */
+&(nid_objs[166]),/* "rc2-64-cbc" */
 &(nid_objs[37]),/* "rc2-cbc" */
 &(nid_objs[39]),/* "rc2-cfb" */
 &(nid_objs[38]),/* "rc2-ecb" */
diff --git a/crypto/objects/objects.h b/crypto/objects/objects.h
index 3632363..9bb035b 100644
--- a/crypto/objects/objects.h
+++ b/crypto/objects/objects.h
@@ -866,6 +866,10 @@
 #define NID_id_qt_unotice	165
 #define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
 
+#define SN_rc2_64_cbc			"RC2-64-CBC"
+#define LN_rc2_64_cbc			"rc2-64-cbc"
+#define NID_rc2_64_cbc			166
+
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 1536aa8..d19ee41 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -156,19 +156,14 @@
 		keylen=EVP_CIPHER_key_length(evp_cipher);
 		ivlen=EVP_CIPHER_iv_length(evp_cipher);
 
-		if (ivlen > 0)
-			{
-			ASN1_OCTET_STRING *os;
-
-			RAND_bytes(iv,ivlen);
-			os=ASN1_OCTET_STRING_new();
-			ASN1_OCTET_STRING_set(os,iv,ivlen);
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX this needs to change */
-			if (xalg->parameter == NULL)
-				xalg->parameter=ASN1_TYPE_new();
-			ASN1_TYPE_set(xalg->parameter,V_ASN1_OCTET_STRING,
-				(char *)os);
-			}
+		if (ivlen > 0) {
+			EVP_CIPHER_CTX *ctx;
+			BIO_get_cipher_ctx(btmp, &ctx);
+			if (xalg->parameter == NULL) 
+						xalg->parameter=ASN1_TYPE_new();
+			if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+								       goto err;
+		}
 		RAND_bytes(key,keylen);
 
 		/* Lets do the pub key stuff :-) */
diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c
index 7bba23e..43d9915 100644
--- a/crypto/pkcs7/pk7_lib.c
+++ b/crypto/pkcs7/pk7_lib.c
@@ -435,7 +435,7 @@
 		return(0);
 		}
 
-	ec->algorithm->algorithm=OBJ_nid2obj(EVP_CIPHER_nid(cipher));
+	ec->algorithm->algorithm=OBJ_nid2obj(EVP_CIPHER_type(cipher));
 	return(ec->algorithm->algorithm != NULL);
 	}