- StringBuilder allTicket = new StringBuilder ();
- allTicket.Append (ticket.Version);
- allTicket.Append ('\u0001');
- allTicket.Append (ticket.Name);
- allTicket.Append ('\u0002');
- allTicket.Append (ticket.IssueDate.Ticks);
- allTicket.Append ('\u0003');
- allTicket.Append (ticket.Expiration.Ticks);
- allTicket.Append ('\u0004');
- allTicket.Append (ticket.IsPersistent ? '1' : '0');
- allTicket.Append ('\u0005');
- allTicket.Append (ticket.UserData);
- allTicket.Append ('\u0006');
- allTicket.Append (ticket.CookiePath);
- allTicket.Append ('\u0007');
- //if (protection == FormsProtectionEnum.None)
- return GetHexString (allTicket.ToString ());
- //TODO: encrypt and validate
+ byte [] ticket_bytes = ticket.ToByteArray ();
+ if (protection == FormsProtectionEnum.None)
+ return GetHexString (ticket_bytes);
+
+ byte [] result = ticket_bytes;
+ MachineKeyConfig config = HttpContext.GetAppConfig ("system.web/machineKey") as MachineKeyConfig;
+ bool all = (protection == FormsProtectionEnum.All);
+ if (all || protection == FormsProtectionEnum.Validation) {
+ byte [] valid_bytes = null;
+ byte [] vk = config.ValidationKey;
+ byte [] mix = new byte [ticket_bytes.Length + vk.Length];
+ Buffer.BlockCopy (ticket_bytes, 0, mix, 0, ticket_bytes.Length);
+ Buffer.BlockCopy (vk, 0, mix, result.Length, vk.Length);
+
+ switch (config.ValidationType) {
+ case MachineKeyValidation.MD5:
+ valid_bytes = MD5.Create ().ComputeHash (mix);
+ break;
+ // From MS docs: "When 3DES is specified, forms authentication defaults to SHA1"
+ case MachineKeyValidation.TripleDES:
+ case MachineKeyValidation.SHA1:
+ valid_bytes = SHA1.Create ().ComputeHash (mix);
+ break;
+ }
+
+ int tlen = ticket_bytes.Length;
+ int vlen = valid_bytes.Length;
+ result = new byte [tlen + vlen];
+ Buffer.BlockCopy (ticket_bytes, 0, result, 0, tlen);
+ Buffer.BlockCopy (valid_bytes, 0, result, tlen, vlen);
+ }
+
+ if (all || protection == FormsProtectionEnum.Encryption) {
+ ICryptoTransform encryptor;
+ encryptor = new TripleDESCryptoServiceProvider().CreateEncryptor (config.DecryptionKey192Bits, init_vector);
+ result = encryptor.TransformFinalBlock (result, 0, result.Length);
+ }
+
+ return GetHexString (result);