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); }
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; }