Example #1
0
        private static byte[] MakeTicketIntoBinaryBlob(FormsAuthenticationTicket ticket)
        {
            if (((ticket.Name == null) || (ticket.UserData == null)) || (ticket.CookiePath == null))
            {
                return(null);
            }
            if (!AppSettings.UseLegacyFormsAuthenticationTicketCompatibility)
            {
                return(FormsAuthenticationTicketSerializer.Serialize(ticket));
            }
            byte[] dst    = new byte[0x1000];
            byte[] pBytes = new byte[4];
            long[] pDates = new long[2];
            if (((_Protection != FormsProtectionEnum.All) && (_Protection != FormsProtectionEnum.Encryption)) || (MachineKeySection.CompatMode == MachineKeyCompatibilityMode.Framework20SP1))
            {
                byte[] data = new byte[8];
                new RNGCryptoServiceProvider().GetBytes(data);
                Buffer.BlockCopy(data, 0, dst, 0, 8);
            }
            pBytes[0] = (byte)ticket.Version;
            pBytes[1] = ticket.IsPersistent ? ((byte)1) : ((byte)0);
            pDates[0] = ticket.IssueDate.ToFileTime();
            pDates[1] = ticket.Expiration.ToFileTime();
            int count = System.Web.UnsafeNativeMethods.CookieAuthConstructTicket(dst, dst.Length, ticket.Name, ticket.UserData, ticket.CookiePath, pBytes, pDates);

            if (count < 0)
            {
                return(null);
            }
            byte[] buffer4 = new byte[count];
            Buffer.BlockCopy(dst, 0, buffer4, 0, count);
            return(buffer4);
        }
Example #2
0
        /////////////////////////////////////////////////////////////////////////////
        private static byte[] MakeTicketIntoBinaryBlob(FormsAuthenticationTicket ticket)
        {
            // None of the modes (Framework20 / Framework40 / beyond) support null values for these fields;
            // they always eventually just returned a null value.
            if (ticket.Name == null || ticket.UserData == null || ticket.CookiePath == null)
            {
                return(null);
            }

            // ** MSRC 11838 **
            // Framework20 / Framework40 ticket generation modes are insecure. We should use a
            // secure serialization mode by default.
            if (!AppSettings.UseLegacyFormsAuthenticationTicketCompatibility)
            {
                return(FormsAuthenticationTicketSerializer.Serialize(ticket));
            }

            // ** MSRC 11838 **
            // If we have reached this point of execution, the developer has explicitly elected
            // to continue using the insecure code path instead of the secure one. We removed
            // the Framework40 serialization mode, so everybody using the legacy code path is
            // forced to Framework20.

            byte [] bData  = new byte[4096];
            byte [] pBin   = new byte[4];
            long [] pDates = new long[2];
            byte [] pNull  = { 0, 0, 0 };

            // DevDiv Bugs 137864: 8 bytes may not be enough random bits as the length should be equal to the
            // key size. In CompatMode > Framework20SP1, use the IVType.Random feature instead of these 8 bytes,
            // but still include empty 8 bytes for compat with webengine.dll, where CookieAuthConstructTicket is.
            // Note that even in CompatMode = Framework20SP2 we fill 8 bytes with random data if the ticket
            // is not going to be encrypted.

            bool willEncrypt   = (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Encryption);
            bool legacyPadding = !willEncrypt || (MachineKeySection.CompatMode == MachineKeyCompatibilityMode.Framework20SP1);

            if (legacyPadding)
            {
                // Fill the first 8 bytes of the blob with random bits
                byte[] bRandom = new byte[8];
                RNGCryptoServiceProvider randgen = new RNGCryptoServiceProvider();
                randgen.GetBytes(bRandom);
                Buffer.BlockCopy(bRandom, 0, bData, 0, 8);
            }
            else
            {
                // use blank 8 bytes for compatibility with CookieAuthConstructTicket (do nothing)
            }

            pBin[0] = (byte)ticket.Version;
            pBin[1] = (byte)(ticket.IsPersistent ? 1 : 0);

            pDates[0] = ticket.IssueDate.ToFileTime();
            pDates[1] = ticket.Expiration.ToFileTime();

            int iRet = UnsafeNativeMethods.CookieAuthConstructTicket(
                bData, bData.Length,
                ticket.Name, ticket.UserData, ticket.CookiePath,
                pBin, pDates);

            if (iRet < 0)
            {
                return(null);
            }

            byte[] ciphertext = new byte[iRet];
            Buffer.BlockCopy(bData, 0, ciphertext, 0, iRet);
            return(ciphertext);
        }