Update from stable branch.
diff --git a/CHANGES b/CHANGES
index f2e4487..074538c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,7 +2,7 @@
  OpenSSL CHANGES
  _______________
 
- Changes between 0.9.8g and 0.9.9  [xx XXX xxxx]
+ Changes between 0.9.8i and 0.9.9  [xx XXX xxxx]
 
   *) Removed effectively defunct crypto/store from the build.
      [Ben Laurie]
@@ -702,6 +702,9 @@
 
  Changes between 0.9.8h and 0.9.8i  [xx XXX xxxx]
 
+  *) Add support for Local Machine Keyset attribute in PKCS#12 files.
+     [Steve Henson]
+
   *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
      [Huang Ying]
 
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 4b7a995..06f8931 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -101,6 +101,7 @@
     char **args;
     char *name = NULL;
     char *csp_name = NULL;
+    int add_lmk = 0;
     PKCS12 *p12 = NULL;
     char pass[50], macpass[50];
     int export_cert = 0;
@@ -211,7 +212,9 @@
 			args++;	
 			name = *args;
 		    } else badarg = 1;
-		} else if (!strcmp (*args, "-CSP")) {
+		} else if (!strcmp (*args, "-LMK"))
+			add_lmk = 1;
+		else if (!strcmp (*args, "-CSP")) {
 		    if (args[1]) {
 			args++;	
 			csp_name = *args;
@@ -329,6 +332,7 @@
 	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
 	BIO_printf(bio_err,  "              the random number generator\n");
 	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
+	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
     	goto end;
     }
 
@@ -554,7 +558,9 @@
 	if (csp_name && key)
 		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
 				MBSTRING_ASC, (unsigned char *)csp_name, -1);
-		
+
+	if (add_lmk && key)
+		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
 
 #ifdef CRYPTO_MDEBUG
 	CRYPTO_pop_info();
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 9f0a75f..77f4522 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -62,12 +62,12 @@
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 856
-#define NUM_SN 849
-#define NUM_LN 849
-#define NUM_OBJ 803
+#define NUM_NID 857
+#define NUM_SN 850
+#define NUM_LN 850
+#define NUM_OBJ 804
 
-static const unsigned char lvalues[5702]={
+static const unsigned char lvalues[5711]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -871,6 +871,7 @@
 0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5677] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
 0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5685] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
 0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5693] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5701] OBJ_LocalKeySet */
 };
 
 static const ASN1_OBJECT nid_objs[NUM_NID]={
@@ -2253,6 +2254,8 @@
 	"GOST R 3410-2001 Parameter Set Cryptocom",
 	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5693]),0},
 {"HMAC","hmac",NID_hmac,0,NULL,0},
+{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
+	&(lvalues[5701]),0},
 };
 
 static const unsigned int sn_objs[NUM_SN]={
@@ -2347,6 +2350,7 @@
 646,	/* "JOINT-ISO-ITU-T" */
 773,	/* "KISA" */
 15,	/* "L" */
+856,	/* "LocalKeySet" */
  3,	/* "MD2" */
 257,	/* "MD4" */
  4,	/* "MD5" */
@@ -3165,6 +3169,7 @@
 138,	/* "Microsoft Encrypted File System" */
 171,	/* "Microsoft Extension Request" */
 134,	/* "Microsoft Individual Code Signing" */
+856,	/* "Microsoft Local Key set" */
 137,	/* "Microsoft Server Gated Crypto" */
 648,	/* "Microsoft Smartcardlogin" */
 136,	/* "Microsoft Trust List Signing" */
@@ -4550,6 +4555,7 @@
 682,	/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
 683,	/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
 417,	/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+856,	/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
 390,	/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
 91,	/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
 315,	/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
diff --git a/crypto/objects/obj_mac.h b/crypto/objects/obj_mac.h
index 491a118..05fcbe7 100644
--- a/crypto/objects/obj_mac.h
+++ b/crypto/objects/obj_mac.h
@@ -1030,6 +1030,11 @@
 #define NID_ms_csp_name		417
 #define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
 
+#define SN_LocalKeySet		"LocalKeySet"
+#define LN_LocalKeySet		"Microsoft Local Key set"
+#define NID_LocalKeySet		856
+#define OBJ_LocalKeySet		1L,3L,6L,1L,4L,1L,311L,17L,2L
+
 #define OBJ_certTypes		OBJ_pkcs9,22L
 
 #define LN_x509Certificate		"x509Certificate"
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 7ec6dd9..53c9cb0 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -853,3 +853,4 @@
 id_GostR3411_94_with_GostR3410_2001_cc		853
 id_GostR3410_2001_ParamSet_cc		854
 hmac		855
+LocalKeySet		856
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index 5d6b602..e009702 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -319,6 +319,7 @@
 pkcs9 21		:			: localKeyID
 !Cname ms-csp-name
 1 3 6 1 4 1 311 17 1	: CSPName		: Microsoft CSP Name
+1 3 6 1 4 1 311 17 2	: LocalKeySet		: Microsoft Local Key set
 !Alias certTypes pkcs9 22
 certTypes 1		:			: x509Certificate
 certTypes 2		:			: sdsiCertificate
diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index dbafda1..9748256 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -63,6 +63,19 @@
 
 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
 
+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+	{
+	int idx;
+	X509_ATTRIBUTE *attr;
+	idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+	if (idx < 0)
+		return 1;
+	attr = EVP_PKEY_get_attr(pkey, idx);
+	if (!X509at_add1_attr(&bag->attrib, attr))
+		return 0;
+	return 1;
+	}
+
 PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
 	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
 	     int keytype)
@@ -122,20 +135,15 @@
 
 	if (pkey)
 		{
-		int cspidx;
 		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
 
 		if (!bag)
 			goto err;
 
-		cspidx = EVP_PKEY_get_attr_by_NID(pkey, NID_ms_csp_name, -1);
-		if (cspidx >= 0)
-			{
-			X509_ATTRIBUTE *cspattr;
-			cspattr = EVP_PKEY_get_attr(pkey, cspidx);
-			if (!X509at_add1_attr(&bag->attrib, cspattr))
-				goto err;
-			}
+		if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+			goto err;
+		if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+			goto err;
 
 		if(name && !PKCS12_add_friendlyname(bag, name, -1))
 			goto err;
diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c
index 2c9061e..98460e8 100644
--- a/crypto/x509/x509_att.c
+++ b/crypto/x509/x509_att.c
@@ -245,7 +245,7 @@
 		goto err;
 	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
 		goto err;
-	
+
 	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
 	return(ret);
 err:
@@ -302,6 +302,13 @@
 		atype = attrtype;
 	}
 	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
+	attr->single = 0;
+	/* This is a bit naughty because the attribute should really have
+	 * at least one value but some types use and zero length SET and
+	 * require this.
+	 */
+	if (attrtype == 0)
+		return 1;
 	if(!(ttmp = ASN1_TYPE_new())) goto err;
 	if ((len == -1) && !(attrtype & MBSTRING_FLAG))
 		{
@@ -311,7 +318,6 @@
 	else
 		ASN1_TYPE_set(ttmp, atype, stmp);
 	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
-	attr->single = 0;
 	return 1;
 	err:
 	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);