예제 #1
0
        public static XmlDocument DecryptXml(XmlDocument cipherDoc)
        {
            SecConvObj = null;
            if (DecObj == null)
            {
                return(cipherDoc);                //no keys to decrypt with
            }
            XmlElement envelope = cipherDoc.DocumentElement;

            //add namespace
            //XmlAttribute xenc = xd.CreateAttribute(Pre.xmlns, Pre.xenc, Ns.xmlns);
            //xenc.Value = Ns.xenc;
            //envelope.Attributes.Append(xenc);

            XmlElement headerOrBody = (XmlElement)envelope.ChildNodes[0];
            XmlElement header       = null;
            XmlElement body         = null;

            if (headerOrBody.LocalName == Elem.Header)
            {
                header = (XmlElement)envelope.ChildNodes[0];
                body   = (XmlElement)envelope.ChildNodes[1];
            }
            else             //no header
            {
                body = (XmlElement)envelope.ChildNodes[0];
            }

            string encKeyMethod = null;

            byte [] baEncKey = null;
            string  encKeyId = null;
            //UsernameToken encryption
            XmlElement nonce   = null;
            XmlElement created = null;

            //search for Security in Header, remove MustUnderstand
            if (header != null)
            {
                XmlElement securityElem = LameXpath.SelectSingleNode(header, Elem.Security);
                if (securityElem != null)
                {
                    XmlAttribute mustUndAtt = securityElem.Attributes[Attrib.mustUnderstand, Ns.soap];
                    if (mustUndAtt != null)
                    {
                        mustUndAtt.Value = "0";
                    }
                    //securityElem.ParentNode.RemoveChild(securityElem);

                    XmlElement encKeyElem = LameXpath.SelectSingleNode(securityElem, Elem.EncryptedKey);
                    if (encKeyElem != null)
                    {
                        XmlElement encMethodElem = LameXpath.SelectSingleNode(encKeyElem, Elem.EncryptionMethod);
                        if (encMethodElem != null)
                        {
                            encKeyMethod = encMethodElem.Attributes[Attrib.Algorithm].Value;
                        }
                        //ignore KeyInfo, use SecurityTokenReference instead

                        XmlElement cipherValElem = LameXpath.SelectSingleNode(securityElem, Elem.CipherValue);
                        if (cipherValElem != null)
                        {
                            baEncKey = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cipherValElem.InnerText);
                        }
                    }

                    XmlElement refListElem = LameXpath.SelectSingleNode(securityElem, Elem.ReferenceList);
                    if (refListElem != null)
                    {
                        //ignore refList, just do straight to encData
                    }
                    XmlElement keyIdElem = LameXpath.SelectSingleNode(securityElem, Elem.KeyIdentifier);
                    if (keyIdElem != null)                    //get keyId
                    {
                        string valueType = keyIdElem.Attributes[Attrib.ValueType].Value;
                        //"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier
                        if (valueType.EndsWith("#X509SubjectKeyIdentifier") == false && valueType != "wsse:X509v3")
                        {
                            throw new Exception("only support X.509v3 certificates");
                        }
                        encKeyId = keyIdElem.InnerText;
                    }
                    XmlElement refElem = LameXpath.SelectSingleNode(securityElem, Elem.Reference);
                    if (refElem != null)                    //get keyUri
                    {
                        string refUri = refElem.Attributes[Attrib.URI].Value;
                    }
                    XmlElement userTokElem = LameXpath.SelectSingleNode(securityElem, Elem.UsernameToken);
                    if (userTokElem != null)
                    {
                        nonce   = LameXpath.SelectSingleNode(userTokElem, Elem.Nonce);
                        created = LameXpath.SelectSingleNode(userTokElem, Elem.Created);
                    }
                }
                //end header processing
            }

            byte [] baPlainKey = null;
            if (encKeyMethod != null)            //decrypt key, assume RSA
            {
                baPlainKey = DecObj.RSACSP.Decrypt(baEncKey, false);
                KeyExchangeFormatter fmt = DecObj.SymmAlg.KeyExchangeFormatter;
                DecObj.SymmAlg.Key.Key = baPlainKey;
            }
            //UsernameToken decryption
            if (DecObj.ClearPassword != null)
            {
                //use XmlSigHandler values, because will more than likely be signing
                int numKeyBytes = DecObj.SymmAlg.Key.Key.Length;
                if (nonce == null || created == null)
                {
                    baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, XmlSigHandler.StrKeyLabel, DecObj.UserTok.Nonce.Text, DecObj.UserTok.Created, numKeyBytes);
                }
                else
                {
                    baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, XmlSigHandler.StrKeyLabel, nonce.InnerText, created.InnerText, numKeyBytes);
                }
                DecObj.SymmAlg.Key.Key = baPlainKey;
            }

            //TODO EncryptedKey in body?, multiple EncryptedData in body

            string     encBodMethod = null;
            string     keyName      = null;
            XmlElement cipherElem   = LameXpath.SelectSingleNode(cipherDoc, Elem.EncryptedData);

            //if(cipherElem == null)
            //	return cipherDoc; //nothing to decrypt
            if (cipherElem != null)
            {
                XmlElement encMethodElemBod = LameXpath.SelectSingleNode(cipherElem, Elem.EncryptionMethod);
                if (encMethodElemBod != null)
                {
                    encBodMethod = encMethodElemBod.Attributes[Attrib.Algorithm].Value;
                    if (encBodMethod == Alg.aes128cbc)
                    {
                        if (DecObj.SymmAlg is TripleDES)
                        {
                            throw new Exception("device expects TripleDES, not AES");
                        }
                    }
                    if (encBodMethod == Alg.tripledesCbc)
                    {
                        if ((DecObj.SymmAlg is TripleDES) == false)
                        {
                            throw new Exception("device expects AES, not TripleDES");
                        }
                    }
                }
                XmlElement keyNameElem = LameXpath.SelectSingleNode(cipherElem, Elem.KeyName);
                if (keyNameElem != null)
                {
                    keyName = keyNameElem.InnerText;
                }

                XmlElement cipherValueElem = LameXpath.SelectSingleNode(cipherElem, Elem.CipherValue);
                byte[]     baCipher        = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cipherValueElem.InnerText);

                //should have encMethod, key, and cipherData now

                System.Security.Cryptography.SymmetricAlgorithm sa = DecObj.SymmAlg.Key;
                byte[] baClear = DecObj.SymmAlg.EncryptionFormatter.Decrypt(baCipher);

                /*
                 * PlainTextType ptType = PlainTextType.Content; //default
                 * if(cipherElem.Attributes["Type"] != null)
                 * {
                 *      string strType = cipherElem.Attributes["Type"].Value;
                 *      if(strType == "http://www.w3.org/2001/04/xmlenc#Element")
                 *              ptType = PlainTextType.Element;
                 * }
                 */

                string strClear = OpenNETCF.Security.Cryptography.Internal.Format.GetString(baClear); //for debugging
                cipherElem.ParentNode.InnerXml = strClear;
            }

            //MOD for SecureConversation
            //XmlElement rstrElem = LameXpath.SelectSingleNode(body, Elem.RequestSecurityToken); //temp for testing
            XmlElement rstrElem = LameXpath.SelectSingleNode(body, Elem.RequestSecurityTokenResponse);

            if (rstrElem != null)
            {
                SecConvObj = new SecConvObject();
                //<TokenType/>
                XmlElement ttElem = LameXpath.SelectSingleNode(rstrElem, Elem.TokenType);
                if (ttElem != null)
                {
                    SecConvObj.tokenType           = new TokenType();
                    SecConvObj.tokenType.InnerText = ttElem.InnerText;
                }
                //ignore <AppliesTo/> for now

                //Entropy
                XmlElement entropyElem = LameXpath.SelectSingleNode(rstrElem, Elem.Entropy);
                if (entropyElem != null)
                {
                    XmlElement encKeyElem = LameXpath.SelectSingleNode(entropyElem, Elem.EncryptedKey);
                    if (encKeyElem != null)
                    {
                        XmlElement cipherValElem = LameXpath.SelectSingleNode(encKeyElem, Elem.CipherValue);
                        if (cipherValElem != null)
                        {
                            baEncKey = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cipherValElem.InnerText);
                        }
                        XmlElement encMethodElem = LameXpath.SelectSingleNode(encKeyElem, Elem.EncryptionMethod);
                        if (encMethodElem != null)
                        {
                            encKeyMethod = encMethodElem.Attributes[Attrib.Algorithm].Value;
                            if (encKeyMethod == Alg.kwTripledes)
                            {
                                throw new Exception("return Entropy with kw-TripleDes is not supported");
                            }
                            if (encKeyMethod == Alg.kwAes128)
                            {
                                XmlElement keyNameElem = LameXpath.SelectSingleNode(encKeyElem, Elem.KeyName);
                                if (keyNameElem != null)
                                {
                                    keyName = keyNameElem.InnerText;
                                }
                                if (DecObj.SymmAlg.Key is System.Security.Cryptography.TripleDES)
                                {
                                    throw new Exception("device expects TripleDES, not AES128");
                                }
                                //the request entropy is encrypted with RSA
                                //it passes a symmetric key
                                //the response is encrypted with kw-aes128
                                //the key for the kw-aes128 seems to be the symm key passed by RSA?
                                System.Security.Cryptography.SymmetricAlgorithm sa = DecObj.keyWrap;
                                //key should have already been set
                                byte[] unwrappedKey = Decrypt(sa, baEncKey);
                                SecConvObj.entropyKey = unwrappedKey;
                            }
                            if (encKeyMethod == Alg.rsa15)
                            {
                                //TODO - this scenario is not expected?
                                XmlElement keyIdElem = LameXpath.SelectSingleNode(encKeyElem, Elem.KeyIdentifier);
                                if (keyIdElem != null)
                                {
                                    keyName = keyIdElem.InnerText;
                                }
                                baPlainKey            = DecObj.RSACSP.DecryptValue(baEncKey);
                                SecConvObj.secConvKey = baPlainKey;
                                //went from 128 bytes to 16 decrypted - AES?
                                //DecObj.SymmAlg.Key.Key = baPlainKey;
                            }
                        }
                        XmlElement carriedKeyNameElem = LameXpath.SelectSingleNode(encKeyElem, Elem.CarriedKeyName);
                        if (carriedKeyNameElem != null)
                        {
                            keyName = carriedKeyNameElem.InnerText;
                        }
                    }
                }

                //RST
                XmlElement rstElem = LameXpath.SelectSingleNode(rstrElem, Elem.RequestedSecurityToken);
                if (rstElem != null)
                {
                    SecConvObj.requestedSecurityToken = rstElem;
                }
                //RPT
                XmlElement rptElem = LameXpath.SelectSingleNode(rstrElem, Elem.RequestedProofToken);
                if (rptElem != null)
                {
                    SecConvObj.requestedProofToken = rptElem;

                    //figure out if key is computed
                    //TODO use this later on
                    bool       computed    = false;
                    XmlElement compKeyElem = LameXpath.SelectSingleNode(rptElem, Elem.ComputedKey);
                    if (compKeyElem != null)
                    {
                        computed = true;
                    }
                    if (computed == true)
                    {
                        //throw new Exception("not handling computed return keys yet");
                        byte [] entropy1        = DecObj.keyWrap.Key;
                        byte [] entropy2        = SecConvObj.entropyKey;
                        byte [] concatEntropies = new byte[entropy1.Length + entropy2.Length];
                        Array.Copy(entropy1, 0, concatEntropies, 0, entropy1.Length);
                        Array.Copy(entropy2, 0, concatEntropies, entropy1.Length, entropy2.Length);
                        SecConvObj.secConvKey = P_SHA1.DeriveKey(entropy1, entropy2, XmlSigHandler.NumKeyBytes);
                    }

                    XmlElement encMethodElemBod = LameXpath.SelectSingleNode(rptElem, Elem.EncryptionMethod);
                    if (encMethodElemBod != null)
                    {
                        encBodMethod = encMethodElemBod.Attributes[Attrib.Algorithm].Value;
                        if (encBodMethod == Alg.kwAes128)
                        {
                            //throw new Exception("only supports TripleDes, no AES on device");
                            XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
                            //byte [] baPKey = null;
                            if (cvElem != null)
                            {
                                byte[] baCipher = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cvElem.InnerText);

                                int    numKeyBytes = DecObj.SymmAlg.Key.Key.Length;
                                string tempLabel   = XmlSigHandler.StrKeyLabel;                               //WS-Security

                                baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, tempLabel, nonce.InnerText, created.InnerText, numKeyBytes);

                                //TODO make TripleDES below work like this too - common codebase
                                System.Security.Cryptography.SymmetricAlgorithm sa = DecObj.keyWrap;
                                sa.Key = baPlainKey;
                                byte[] unwrappedKey = Decrypt(sa, baCipher);

                                SecConvObj.secConvKey = unwrappedKey;
                            }
                        }
                        else if (encBodMethod == Alg.kwTripledes)
                        {
                            XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
                            //byte [] baPKey = null;
                            if (cvElem != null)
                            {
                                byte[] baCipher = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cvElem.InnerText);

                                int    numKeyBytes = DecObj.SymmAlg.Key.Key.Length;
                                string tempLabel   = XmlSigHandler.StrKeyLabel;                               //WS-Security
                                //string tempLabel = "WS-SecureConversation";

                                baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, tempLabel, nonce.InnerText, created.InnerText, numKeyBytes);

                                //TODO make this work with KeyWrap interface
                                //SymmetricAlgorithm sa = DecObj.SymmAlg;
                                System.Security.Cryptography.TripleDESCryptoServiceProvider sa = (System.Security.Cryptography.TripleDESCryptoServiceProvider)DecObj.SymmAlg.Key;
                                sa.Key = baPlainKey;
                                TripleDesKeyWrap tdkw         = new TripleDesKeyWrap(sa);
                                byte []          unwrappedKey = tdkw.DecryptValue(baCipher);

                                SecConvObj.secConvKey = unwrappedKey;
                            }
                        }
                        else                         //http://www.w3.org/2001/04/xmlenc#rsa-1_5
                        {
                            XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
                            byte []    baPKey = null;
                            if (cvElem != null)
                            {
                                byte[] baEKey = OpenNETCF.Security.Cryptography.Internal.Format.GetB64(cvElem.InnerText);
                                baPKey = DecObj.RSACSP.DecryptValue(baEKey);
                                SecConvObj.secConvKey = baPKey;
                            }
                        }
                    }
                    //else
                    //{
                    //	throw new Exception("EncryptionMethod not specified");
                    //}
                }
                //ignore <LifeTime/> for now
            }

            DecObj = null;
            return(cipherDoc);
        }
예제 #2
0
		public static XmlDocument DecryptXml(XmlDocument cipherDoc)
		{
			SecConvObj = null;
			if(DecObj == null)
				return cipherDoc; //no keys to decrypt with

			XmlElement envelope = cipherDoc.DocumentElement;

			//add namespace
			//XmlAttribute xenc = xd.CreateAttribute(Pre.xmlns, Pre.xenc, Ns.xmlns);
			//xenc.Value = Ns.xenc;
			//envelope.Attributes.Append(xenc);

			XmlElement headerOrBody = (XmlElement) envelope.ChildNodes[0];
			XmlElement header = null;
			XmlElement body = null;
			if(headerOrBody.LocalName == Elem.Header)
			{
				header = (XmlElement) envelope.ChildNodes[0];
				body = (XmlElement) envelope.ChildNodes[1];
			}
			else //no header
			{
				body = (XmlElement) envelope.ChildNodes[0];
			}

			string encKeyMethod = null;
			byte [] baEncKey = null;
			string encKeyId = null;
			//UsernameToken encryption
			XmlElement nonce = null;
			XmlElement created = null;
			//search for Security in Header, remove MustUnderstand
			if(header != null)
			{
				XmlElement securityElem = LameXpath.SelectSingleNode(header, Elem.Security);
				if(securityElem != null)
				{
					XmlAttribute mustUndAtt = securityElem.Attributes[Attrib.mustUnderstand,Ns.soap];
					if(mustUndAtt != null)
						mustUndAtt.Value = "0";
					//securityElem.ParentNode.RemoveChild(securityElem);

					XmlElement encKeyElem = LameXpath.SelectSingleNode(securityElem, Elem.EncryptedKey);
					if(encKeyElem != null)
					{
						XmlElement encMethodElem = LameXpath.SelectSingleNode(encKeyElem, Elem.EncryptionMethod);
						if(encMethodElem != null)
						{
							encKeyMethod = encMethodElem.Attributes[Attrib.Algorithm].Value;
						}
						//ignore KeyInfo, use SecurityTokenReference instead

						XmlElement cipherValElem = LameXpath.SelectSingleNode(securityElem, Elem.CipherValue);
						if(cipherValElem != null)
						{
							baEncKey = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cipherValElem.InnerText);
						}
					}

					XmlElement refListElem = LameXpath.SelectSingleNode(securityElem, Elem.ReferenceList);
					if(refListElem != null)
					{
						//ignore refList, just do straight to encData
					}
					XmlElement keyIdElem = LameXpath.SelectSingleNode(securityElem, Elem.KeyIdentifier);
					if(keyIdElem != null) //get keyId
					{
						string valueType = keyIdElem.Attributes[Attrib.ValueType].Value;
						//"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier
						if(valueType.EndsWith("#X509SubjectKeyIdentifier") == false && valueType != "wsse:X509v3")
							throw new Exception("only support X.509v3 certificates");
						encKeyId = keyIdElem.InnerText;
					}
					XmlElement refElem = LameXpath.SelectSingleNode(securityElem, Elem.Reference);
					if(refElem != null) //get keyUri
					{
						string refUri = refElem.Attributes[Attrib.URI].Value;
					}
					XmlElement userTokElem = LameXpath.SelectSingleNode(securityElem, Elem.UsernameToken);
					if(userTokElem != null)
					{
						nonce = LameXpath.SelectSingleNode(userTokElem, Elem.Nonce);
						created = LameXpath.SelectSingleNode(userTokElem, Elem.Created);
					}
				}
				//end header processing
			}

			byte [] baPlainKey = null;
			if(encKeyMethod != null) //decrypt key, assume RSA
			{
				baPlainKey = DecObj.RSACSP.DecryptValue(baEncKey);
				DecObj.SymmAlg.Key = baPlainKey;
			}
			//UsernameToken decryption
			if(DecObj.ClearPassword != null)
			{
				//use XmlSigHandler values, because will more than likely be signing
				int numKeyBytes = DecObj.SymmAlg.Key.Length;
				if(nonce==null || created==null)
					baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, XmlSigHandler.StrKeyLabel, DecObj.UserTok.Nonce.Text, DecObj.UserTok.Created, numKeyBytes);
				else
					baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, XmlSigHandler.StrKeyLabel, nonce.InnerText, created.InnerText, numKeyBytes);
				DecObj.SymmAlg.Key = baPlainKey;
			}

			//TODO EncryptedKey in body?, multiple EncryptedData in body

			string encBodMethod = null;
			string keyName = null;
			XmlElement cipherElem = LameXpath.SelectSingleNode(cipherDoc, Elem.EncryptedData);
			//if(cipherElem == null)
			//	return cipherDoc; //nothing to decrypt
			if(cipherElem != null)
			{
				XmlElement encMethodElemBod = LameXpath.SelectSingleNode(cipherElem, Elem.EncryptionMethod);
				if(encMethodElemBod != null)
				{
					encBodMethod = encMethodElemBod.Attributes[Attrib.Algorithm].Value;
					if(encBodMethod == Alg.aes128cbc)
					{
						if(DecObj.SymmAlg is TripleDES)
							throw new Exception("device expects TripleDES, not AES");
					}
					if(encBodMethod == Alg.tripledesCbc)
					{
						if((DecObj.SymmAlg is TripleDES) == false)
							throw new Exception("device expects AES, not TripleDES");
					}
				}
				XmlElement keyNameElem = LameXpath.SelectSingleNode(cipherElem, Elem.KeyName);
				if(keyNameElem != null)
					keyName = keyNameElem.InnerText;
			
				XmlElement cipherValueElem = LameXpath.SelectSingleNode(cipherElem, Elem.CipherValue);
				byte [] baCipherIv = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cipherValueElem.InnerText);

				//should have encMethod, key, and cipherData now

				SymmetricAlgorithm sa = DecObj.SymmAlg;
				Array.Copy(baCipherIv, 0, sa.IV, 0, sa.IV.Length);
				byte [] baCipher = new byte [baCipherIv.Length - sa.IV.Length];
				Array.Copy(baCipherIv, sa.IV.Length, baCipher, 0, baCipher.Length);
				byte [] baClear = sa.DecryptValue(baCipher);

				/*
				PlainTextType ptType = PlainTextType.Content; //default
				if(cipherElem.Attributes["Type"] != null)
				{
					string strType = cipherElem.Attributes["Type"].Value;
					if(strType == "http://www.w3.org/2001/04/xmlenc#Element")
						ptType = PlainTextType.Element;
				}
				*/

				string strClear = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetString(baClear); //for debugging
				cipherElem.ParentNode.InnerXml = strClear;
			}

			//MOD for SecureConversation
			//XmlElement rstrElem = LameXpath.SelectSingleNode(body, Elem.RequestSecurityToken); //temp for testing
			XmlElement rstrElem = LameXpath.SelectSingleNode(body, Elem.RequestSecurityTokenResponse);
			if(rstrElem != null)
			{
				SecConvObj = new SecConvObject();
				//<TokenType/>
				XmlElement ttElem = LameXpath.SelectSingleNode(rstrElem, Elem.TokenType);
				if(ttElem != null)
				{
					SecConvObj.tokenType = new TokenType();
					SecConvObj.tokenType.InnerText = ttElem.InnerText;
				}
				//ignore <AppliesTo/> for now

				//Entropy
				XmlElement entropyElem = LameXpath.SelectSingleNode(rstrElem, Elem.Entropy);
				if(entropyElem != null)
				{
					XmlElement encKeyElem = LameXpath.SelectSingleNode(entropyElem, Elem.EncryptedKey);
					if(encKeyElem != null)
					{
						XmlElement cipherValElem = LameXpath.SelectSingleNode(encKeyElem, Elem.CipherValue);
						if(cipherValElem != null)
						{
							baEncKey = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cipherValElem.InnerText);
						}
						XmlElement encMethodElem = LameXpath.SelectSingleNode(encKeyElem, Elem.EncryptionMethod);
						if(encMethodElem != null)
						{
							encKeyMethod = encMethodElem.Attributes[Attrib.Algorithm].Value;
							if(encKeyMethod == Alg.kwTripledes)
							{
								throw new Exception("return Entropy with kw-TripleDes is not supported");
							}
							if(encKeyMethod == Alg.kwAes128)
							{
								XmlElement keyNameElem = LameXpath.SelectSingleNode(encKeyElem, Elem.KeyName);
								if(keyNameElem != null)
								{
									keyName = keyNameElem.InnerText;
								}
								if(DecObj.SymmAlg is TripleDES)
									throw new Exception("device expects TripleDES, not AES128");
								//the request entropy is encrypted with RSA
								//it passes a symmetric key
								//the response is encrypted with kw-aes128
								//the key for the kw-aes128 seems to be the symm key passed by RSA?
								SymmetricAlgorithm sa = DecObj.keyWrap;
								//key should have already been set
								byte [] unwrappedKey = sa.DecryptValue(baEncKey);
								SecConvObj.entropyKey = unwrappedKey;
							}
							if(encKeyMethod == Alg.rsa15)
							{
								//TODO - this scenario is not expected?
								XmlElement keyIdElem = LameXpath.SelectSingleNode(encKeyElem, Elem.KeyIdentifier);
								if(keyIdElem != null)
								{
									keyName = keyIdElem.InnerText;
								}
								baPlainKey = DecObj.RSACSP.DecryptValue(baEncKey);
								SecConvObj.secConvKey = baPlainKey;
								//went from 128 bytes to 16 decrypted - AES?
								//DecObj.SymmAlg.Key = baPlainKey;
							}
						}
						XmlElement carriedKeyNameElem = LameXpath.SelectSingleNode(encKeyElem, Elem.CarriedKeyName);
						if(carriedKeyNameElem != null)
						{
							keyName = carriedKeyNameElem.InnerText;
						}
					}
				}

				//RST
				XmlElement rstElem = LameXpath.SelectSingleNode(rstrElem, Elem.RequestedSecurityToken);
				if(rstElem != null)
					SecConvObj.requestedSecurityToken = rstElem;
				//RPT
				XmlElement rptElem = LameXpath.SelectSingleNode(rstrElem, Elem.RequestedProofToken);
				if(rptElem != null)
				{
					SecConvObj.requestedProofToken = rptElem;

					//figure out if key is computed
					//TODO use this later on
					bool computed = false;
					XmlElement compKeyElem = LameXpath.SelectSingleNode(rptElem, Elem.ComputedKey);
					if(compKeyElem != null)
						computed = true;
					if(computed == true)
					{
						//throw new Exception("not handling computed return keys yet");
						byte [] entropy1 = DecObj.keyWrap.Key;
						byte [] entropy2 = SecConvObj.entropyKey;
						byte [] concatEntropies = new byte[entropy1.Length + entropy2.Length];
						Array.Copy(entropy1, 0, concatEntropies, 0, entropy1.Length);
						Array.Copy(entropy2, 0, concatEntropies, entropy1.Length, entropy2.Length);
						SecConvObj.secConvKey = P_SHA1.DeriveKey(entropy1, entropy2, XmlSigHandler.NumKeyBytes);
					}

					XmlElement encMethodElemBod = LameXpath.SelectSingleNode(rptElem, Elem.EncryptionMethod);
					if(encMethodElemBod != null)
					{
						encBodMethod = encMethodElemBod.Attributes[Attrib.Algorithm].Value;
						if(encBodMethod == Alg.kwAes128)
						{
							//throw new Exception("only supports TripleDes, no AES on device");
							XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
							//byte [] baPKey = null;
							if(cvElem != null)
							{
								byte [] baCipher = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cvElem.InnerText);

								int numKeyBytes = DecObj.SymmAlg.Key.Length;
								string tempLabel = XmlSigHandler.StrKeyLabel; //WS-Security
								
								baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, tempLabel, nonce.InnerText, created.InnerText, numKeyBytes);

								//TODO make TripleDES below work like this too - common codebase
								SymmetricAlgorithm sa = DecObj.keyWrap;
								sa.Key = baPlainKey;
								byte [] unwrappedKey = sa.DecryptValue(baCipher);

								SecConvObj.secConvKey = unwrappedKey;
							}
						}
						else if(encBodMethod == Alg.kwTripledes)
						{
							XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
							//byte [] baPKey = null;
							if(cvElem != null)
							{
								byte [] baCipher = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cvElem.InnerText);

								int numKeyBytes = DecObj.SymmAlg.Key.Length;
								string tempLabel = XmlSigHandler.StrKeyLabel; //WS-Security
								//string tempLabel = "WS-SecureConversation";
								
								baPlainKey = P_SHA1.DeriveKey(DecObj.ClearPassword, tempLabel, nonce.InnerText, created.InnerText, numKeyBytes);

								//TODO make this work with KeyWrap interface
								//SymmetricAlgorithm sa = DecObj.SymmAlg;
								TripleDESCryptoServiceProvider sa = (TripleDESCryptoServiceProvider) DecObj.SymmAlg;
								sa.Key = baPlainKey;
								TripleDesKeyWrap tdkw = new TripleDesKeyWrap(sa);
								byte [] unwrappedKey = tdkw.DecryptValue(baCipher);

								SecConvObj.secConvKey = unwrappedKey;
							}
						}
						else //http://www.w3.org/2001/04/xmlenc#rsa-1_5
						{
							XmlElement cvElem = LameXpath.SelectSingleNode(rptElem, Elem.CipherValue);
							byte [] baPKey = null;
							if(cvElem != null)
							{
								byte [] baEKey = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(cvElem.InnerText);
								baPKey = DecObj.RSACSP.DecryptValue(baEKey);
								SecConvObj.secConvKey = baPKey;
							}
						}
					}
					//else
					//{
					//	throw new Exception("EncryptionMethod not specified");
					//}
				}
				//ignore <LifeTime/> for now
			}

			DecObj = null;
			return cipherDoc;
		}