[ExpectedException(typeof(InvalidOperationException))]           // not ArgumentNullException?
        public void GenerateDerivedKeyUnsupportedAlgorithm()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            key.GenerateDerivedKey("urn:my-own-way", wssc_label, nonce, key.KeySize, 0);
        }
        [ExpectedException(typeof(InvalidOperationException))]           // not ArgumentNullException?
        public void GenerateDerivedKeyNullAlgorithm()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            key.GenerateDerivedKey(null, wssc_label, nonce, key.KeySize, 0);
        }
        public void GenerateDerivedKeyUnusualOffset()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            key.GenerateDerivedKey(
                SecurityAlgorithms.Psha1KeyDerivation,
                wssc_label, nonce, 5, 0);
        }
        public void GenerateDerivedKeyNegativeLength()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            key.GenerateDerivedKey(
                SecurityAlgorithms.Psha1KeyDerivation,
                wssc_label, nonce, -32, 0);
        }
        public void GenerateDerivedKeyNullNonce()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            key.GenerateDerivedKey(
                SecurityAlgorithms.Psha1KeyDerivation,
                wssc_label, null, key.KeySize, 0);
        }
        public void GenerateDerivedKey()
        {
            Key key = new Key(raw);

            byte [] nonce = new byte [256];

            byte [] derived = key.GenerateDerivedKey(
                SecurityAlgorithms.Psha1KeyDerivation,
                wssc_label, nonce, key.KeySize, 0);
            Assert.IsTrue(Convert.ToBase64String(derived) != Convert.ToBase64String(raw), "#4");
            // the precomputed derivation value.
            byte [] expected = Convert.FromBase64String("50UfLeg58TbfADujVeafUAS8typGX9LvqLOXezK/eJY=");
            Assert.AreEqual(Convert.ToBase64String(expected), Convert.ToBase64String(derived), "#5");
        }
		public void GenerateDerivedKeyUnusualOffset ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			key.GenerateDerivedKey (
				SecurityAlgorithms.Psha1KeyDerivation,
				wssc_label, nonce, 5, 0);
		}
		XmlElement VerifyInput2 (MessageBuffer buf)
		{
			Message msg2 = buf.CreateMessage ();
			StringWriter sw = new StringWriter ();
			using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw))) {
				msg2.WriteMessage (w);
			}
			XmlDocument doc = new XmlDocument ();
			doc.PreserveWhitespace = true;
			doc.LoadXml (sw.ToString ());

			// decrypt the key with service certificate privkey
			PaddingMode mode = PaddingMode.PKCS7; // not sure which is correct ... ANSIX923, ISO10126, PKCS7, Zeros, None.
			EncryptedXml encXml = new EncryptedXml (doc);
			encXml.Padding = mode;
			X509Certificate2 cert2 = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
			XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable);
			nsmgr.AddNamespace ("s", "http://www.w3.org/2003/05/soap-envelope");
			nsmgr.AddNamespace ("c", "http://schemas.xmlsoap.org/ws/2005/02/sc");
			nsmgr.AddNamespace ("o", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
			nsmgr.AddNamespace ("e", "http://www.w3.org/2001/04/xmlenc#");
			nsmgr.AddNamespace ("dsig", "http://www.w3.org/2000/09/xmldsig#");
			XmlNode n = doc.SelectSingleNode ("//o:Security/e:EncryptedKey/e:CipherData/e:CipherValue", nsmgr);
			Assert.IsNotNull (n, "premise: enckey does not exist");
			string raw = n.InnerText;
			byte [] rawbytes = Convert.FromBase64String (raw);
			RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) cert2.PrivateKey;
			byte [] decryptedKey = EncryptedXml.DecryptKey (rawbytes, rsa, true);//rsa.Decrypt (rawbytes, true);

#if false
			// create derived keys
			Dictionary<string,byte[]> keys = new Dictionary<string,byte[]> ();
			InMemorySymmetricSecurityKey skey =
				new InMemorySymmetricSecurityKey (decryptedKey);
			foreach (XmlElement el in doc.SelectNodes ("//o:Security/c:DerivedKeyToken", nsmgr)) {
				n = el.SelectSingleNode ("c:Offset", nsmgr);
				int offset = (n == null) ? 0 :
					int.Parse (n.InnerText, CultureInfo.InvariantCulture);
				n = el.SelectSingleNode ("c:Length", nsmgr);
				int length = (n == null) ? 32 :
					int.Parse (n.InnerText, CultureInfo.InvariantCulture);
				n = el.SelectSingleNode ("c:Label", nsmgr);
				byte [] label = (n == null) ? decryptedKey :
					Convert.FromBase64String (n.InnerText);
				n = el.SelectSingleNode ("c:Nonce", nsmgr);
				byte [] nonce = (n == null) ? new byte [0] :
					Convert.FromBase64String (n.InnerText);
				byte [] derkey = skey.GenerateDerivedKey (
					//SecurityAlgorithms.Psha1KeyDerivation,
					"http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1",
// FIXME: maybe due to the label, this key resolution somehow does not seem to work.
					label,
					nonce,
					length * 8,
					offset);

				keys [el.GetAttribute ("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")] = derkey;
			}
#endif

			// decrypt the signature with the decrypted key
#if true
			n = doc.SelectSingleNode ("//o:Security/e:EncryptedData/e:CipherData/e:CipherValue", nsmgr);
			Assert.IsNotNull (n, "premise: encdata does not exist");
			raw = n.InnerText;
			rawbytes = Convert.FromBase64String (raw);
			Rijndael aes = RijndaelManaged.Create ();
//			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
			aes.Key = decryptedKey;
			aes.Mode = CipherMode.CBC;
			aes.Padding = mode;
			MemoryStream ms = new MemoryStream ();
			CryptoStream cs = new CryptoStream (ms, aes.CreateDecryptor (), CryptoStreamMode.Write);
			cs.Write (rawbytes, 0, rawbytes.Length);
			cs.Close ();
			byte [] decryptedSignature = ms.ToArray ();
#else
			Rijndael aes = RijndaelManaged.Create ();
//			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
			aes.Key = decryptedKey;
			aes.Mode = CipherMode.CBC;
			aes.Padding = mode;

			EncryptedData ed = new EncryptedData ();
			n = doc.SelectSingleNode ("//o:Security/e:EncryptedData", nsmgr);
			Assert.IsNotNull (n, "premise: encdata does not exist");
			ed.LoadXml (n as XmlElement);
			byte [] decryptedSignature = encXml.DecryptData (ed, aes);
#endif
//Console.Error.WriteLine (Encoding.UTF8.GetString (decryptedSignature));
//Console.Error.WriteLine ("============= Decrypted Signature End ===========");

			// decrypt the body with the decrypted key
#if true
			n = doc.SelectSingleNode ("//s:Body/e:EncryptedData/e:CipherData/e:CipherValue", nsmgr);
			Assert.IsNotNull (n, "premise: encdata does not exist");
			raw = n.InnerText;
			rawbytes = Convert.FromBase64String (raw);
//			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
			aes.Key = decryptedKey;
			ms = new MemoryStream ();
			cs = new CryptoStream (ms, aes.CreateDecryptor (), CryptoStreamMode.Write);
			cs.Write (rawbytes, 0, rawbytes.Length);
			cs.Close ();
			byte [] decryptedBody = ms.ToArray ();
#else
			// decrypt the body with the decrypted key
			EncryptedData ed2 = new EncryptedData ();
			XmlElement el = doc.SelectSingleNode ("/s:Envelope/s:Body/e:EncryptedData", nsmgr) as XmlElement;
			ed2.LoadXml (el);
//			aes.Key = keys [n.SelectSingleNode ("../../dsig:KeyInfo/o:SecurityTokenReference/o:Reference/@URI", nsmgr).InnerText.Substring (1)];
			aes.Key = decryptedKey;
			byte [] decryptedBody = encXml.DecryptData (ed2, aes);
#endif
//foreach (byte b in decryptedBody) Console.Error.Write ("{0:X02} ", b);
Console.Error.WriteLine (Encoding.UTF8.GetString (decryptedBody));
Console.Error.WriteLine ("============= Decrypted Body End ===========");

			// FIXME: find out what first 16 bytes mean.
			for (int mmm = 0; mmm < 16; mmm++) decryptedBody [mmm] = 0x20;
			doc.LoadXml (Encoding.UTF8.GetString (decryptedBody));
			Assert.AreEqual ("RequestSecurityToken", doc.DocumentElement.LocalName, "#b-1");
			Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2005/02/trust", doc.DocumentElement.NamespaceURI, "#b-2");

			return doc.DocumentElement;
		}
		public void GenerateDerivedKeyNegativeLength ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			key.GenerateDerivedKey (
				SecurityAlgorithms.Psha1KeyDerivation,
				wssc_label, nonce, -32, 0);
		}
		public void GenerateDerivedKeyNullNonce ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			key.GenerateDerivedKey (
				SecurityAlgorithms.Psha1KeyDerivation,
				wssc_label, null, key.KeySize, 0);
		}
		[ExpectedException (typeof (InvalidOperationException))] // not ArgumentNullException?
		public void GenerateDerivedKeyUnsupportedAlgorithm ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			key.GenerateDerivedKey ("urn:my-own-way", wssc_label, nonce, key.KeySize, 0);
		}
		[ExpectedException (typeof (InvalidOperationException))] // not ArgumentNullException?
		public void GenerateDerivedKeyNullAlgorithm ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			key.GenerateDerivedKey (null, wssc_label, nonce, key.KeySize, 0);
		}
		public void GenerateDerivedKey ()
		{
			Key key = new Key (raw);
			byte [] nonce = new byte [256];

			byte [] derived = key.GenerateDerivedKey (
				SecurityAlgorithms.Psha1KeyDerivation,
				wssc_label, nonce, key.KeySize, 0);
			Assert.IsTrue (Convert.ToBase64String (derived) != Convert.ToBase64String (raw), "#4");
			// the precomputed derivation value.
			byte [] expected = Convert.FromBase64String ("50UfLeg58TbfADujVeafUAS8typGX9LvqLOXezK/eJY=");
			Assert.AreEqual (Convert.ToBase64String (expected), Convert.ToBase64String (derived), "#5");
		}