Example #1
0
        public void Save(string filename, string password)
        {
            if (filename == null)
            {
                throw new ArgumentNullException("filename");
            }
            byte[]     array      = null;
            FileStream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write);

            try
            {
                byte[] array2 = new byte[4];
                byte[] bytes  = BitConverterLE.GetBytes(2964713758u);
                fileStream.Write(bytes, 0, 4);
                fileStream.Write(array2, 0, 4);
                bytes = BitConverterLE.GetBytes(keyType);
                fileStream.Write(bytes, 0, 4);
                encrypted = (password != null);
                array     = CryptoConvert.ToCapiPrivateKeyBlob(rsa);
                if (encrypted)
                {
                    bytes = BitConverterLE.GetBytes(1);
                    fileStream.Write(bytes, 0, 4);
                    bytes = BitConverterLE.GetBytes(16);
                    fileStream.Write(bytes, 0, 4);
                    bytes = BitConverterLE.GetBytes(array.Length);
                    fileStream.Write(bytes, 0, 4);
                    byte[] array3 = new byte[16];
                    RC4    rC     = RC4.Create();
                    byte[] array4 = null;
                    try
                    {
                        RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
                        randomNumberGenerator.GetBytes(array3);
                        fileStream.Write(array3, 0, array3.Length);
                        array4 = DeriveKey(array3, password);
                        if (Weak)
                        {
                            Array.Clear(array4, 5, 11);
                        }
                        ICryptoTransform cryptoTransform = rC.CreateEncryptor(array4, null);
                        cryptoTransform.TransformBlock(array, 8, array.Length - 8, array, 8);
                    }
                    finally
                    {
                        Array.Clear(array3, 0, array3.Length);
                        Array.Clear(array4, 0, array4.Length);
                        rC.Clear();
                    }
                }
                else
                {
                    fileStream.Write(array2, 0, 4);
                    fileStream.Write(array2, 0, 4);
                    bytes = BitConverterLE.GetBytes(array.Length);
                    fileStream.Write(bytes, 0, 4);
                }
                fileStream.Write(array, 0, array.Length);
            }
            finally
            {
                Array.Clear(array, 0, array.Length);
                fileStream.Close();
            }
        }
Example #2
0
        public virtual float ReadSingle()
        {
            FillBuffer(4);

            return(BitConverterLE.ToSingle(m_buffer, 0));
        }
Example #3
0
        // note: using SecurityElement.ToXml wouldn't generate the same string as the MS implementation
        public override string ToXmlString(bool includePrivateParameters)
        {
            StringBuilder sb        = new StringBuilder();
            DSAParameters dsaParams = ExportParameters(includePrivateParameters);

            try {
                sb.Append("<DSAKeyValue>");

                sb.Append("<P>");
                sb.Append(Convert.ToBase64String(dsaParams.P));
                sb.Append("</P>");

                sb.Append("<Q>");
                sb.Append(Convert.ToBase64String(dsaParams.Q));
                sb.Append("</Q>");

                sb.Append("<G>");
                sb.Append(Convert.ToBase64String(dsaParams.G));
                sb.Append("</G>");

                sb.Append("<Y>");
                sb.Append(Convert.ToBase64String(dsaParams.Y));
                sb.Append("</Y>");

                if (dsaParams.J != null)
                {
                    // if J wasn't imported then it's not exported and neither
                    // is part of the XML output
                    sb.Append("<J>");
                    sb.Append(Convert.ToBase64String(dsaParams.J));
                    sb.Append("</J>");
                }

                if (dsaParams.Seed != null)
                {
                    sb.Append("<Seed>");
                    sb.Append(Convert.ToBase64String(dsaParams.Seed));
                    sb.Append("</Seed>");

                    sb.Append("<PgenCounter>");
                    // the number of bytes is important (no matter == 0x00)
                    if (dsaParams.Counter != 0)
                    {
                        byte[] inArr = BitConverterLE.GetBytes(dsaParams.Counter);
                        int    l     = inArr.Length;
                        while (inArr[l - 1] == 0x00)
                        {
                            l--;
                        }

                        sb.Append(Convert.ToBase64String(inArr, 0, l));
                    }
                    else
                    {
                        sb.Append("AA==");                              // base64 encoded 0
                    }
                    sb.Append("</PgenCounter>");
                }

                if (dsaParams.X != null)
                {
                    sb.Append("<X>");
                    sb.Append(Convert.ToBase64String(dsaParams.X));
                    sb.Append("</X>");
                }
                else if (includePrivateParameters)
                {
                    throw new ArgumentNullException("X");
                }

                sb.Append("</DSAKeyValue>");
            }
            catch {
                ZeroizePrivateKey(dsaParams);
                throw;
            }

            return(sb.ToString());
        }
Example #4
0
 // PKCS #1 v.2.1, Section 4.1
 // I2OSP converts a non-negative integer to an octet string of a specified length.
 public static byte[] I2OSP(int x, int size)
 {
     byte[] array = BitConverterLE.GetBytes(x);
     Array.Reverse(array, 0, array.Length);
     return(I2OSP(array, size));
 }
Example #5
0
        public virtual double ReadDouble()
        {
            FillBuffer(8);

            return(BitConverterLE.ToDouble(m_buffer, 0));
        }
Example #6
0
        private bool Save(string fileName, byte[] asn)
        {
#if DEBUG
            using (FileStream fs = File.Open(fileName + ".sig", FileMode.Create, FileAccess.Write)) {
                fs.Write(asn, 0, asn.Length);
                fs.Close();
            }
#endif
            // someday I may be sure enough to move this into DEBUG ;-)
            File.Copy(fileName, fileName + ".bak", true);

            using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite)) {
                int filesize;
                if (SecurityOffset > 0)
                {
                    // FIXME Does it fit? Is it always the same size?
                    // file was already signed, we'll reuse the position for the updated signature
                    filesize = SecurityOffset;
                }
                else if (CoffSymbolTableOffset > 0)
                {
                    // FIXME This is not documented as something to remove.
                    // However some documentation says to remove after the last
                    // section, and some does not, and this might be there,
                    // or it might not.
                    // strip (deprecated) COFF symbol table
                    fs.Seek(PEOffset + 12, SeekOrigin.Begin);
                    for (int i = 0; i < 8; i++)
                    {
                        fs.WriteByte(0);
                    }
                    // we'll put the Authenticode signature at this same place (just after the last section)
                    filesize = CoffSymbolTableOffset;
                }
                else
                {
                    // file was never signed, nor does it contains (deprecated) COFF symbols
                    filesize = (int)fs.Length;
                }
                // must be a multiple of 8 bytes
                int addsize = (filesize & 7);
                if (addsize > 0)
                {
                    addsize = 8 - addsize;
                }

                // IMAGE_DIRECTORY_ENTRY_SECURITY (offset, size)
                byte[] data = BitConverterLE.GetBytes(filesize + addsize);
                if (PE64)
                {
                    fs.Seek(PEOffset + 168, SeekOrigin.Begin);
                }
                else
                {
                    fs.Seek(PEOffset + 152, SeekOrigin.Begin);
                }

                fs.Write(data, 0, 4);
                int size = asn.Length + 8;
                int addsize_signature = (size & 7);
                if (addsize_signature > 0)
                {
                    addsize_signature = 8 - addsize_signature;
                }
                data = BitConverterLE.GetBytes(size + addsize_signature);
                if (PE64)
                {
                    fs.Seek(PEOffset + 168 + 4, SeekOrigin.Begin);
                }
                else
                {
                    fs.Seek(PEOffset + 156, SeekOrigin.Begin);
                }

                fs.Write(data, 0, 4);
                fs.Seek(filesize, SeekOrigin.Begin);
                // align certificate entry to a multiple of 8 bytes
                if (addsize > 0)
                {
                    byte[] fillup = new byte[addsize];
                    fs.Write(fillup, 0, fillup.Length);
                }

                /*
                 * https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx
                 * The Authenticode signature is in a WIN_CERTIFICATE structure, which is declared in Wintrust.h as follows:
                 * typedef struct _WIN_CERTIFICATE
                 * {
                 *  DWORD       dwLength;
                 *  WORD        wRevision;
                 *  WORD        wCertificateType;
                 *  BYTE        bCertificate[ANYSIZE_ARRAY];
                 * } WIN_CERTIFICATE, *LPWIN_CERTIFICATE;
                 *
                 * The fields in WIN_CERTIFICATE are set to the following values:
                 * dwLength is set to the length of bCertificate.
                 * wRevision is set to the WIN_CERTIFICATE version number.
                 *
                 * wCertificateType is set to 0x0002 for Authenticode signatures.
                 * This value is defined in Wintrust.h as WIN_CERT_TYPE_PKCS_SIGNED_DATA.
                 * bCertificate is set to a variable-length binary array that contains the Authenticode PKCS #7 signedData.
                 * The PKCS #7 integrity is verified as described in ”PKCS #7: Cryptographic Message Syntax Standard.”
                 */
                // write WIN_CERTIFICATE.dwLength
                fs.Write(data, 0, data.Length);                                 // length (again)
                // write WIN_CERTIFICATE.wRevision = 0x0200 and wCertificateType = 2.
                // /usr/local/Cellar/mingw-w64/5.0.3/toolchain-x86_64/x86_64-w64-mingw32/include/wintrust.h
                // const short WIN_CERT_REVISION_1_0 = 0x0100;
                const short WIN_CERT_REVISION_2_0 = 0x0200;
                // const short WIN_CERT_TYPE_X509 = 0x0001;
                const short WIN_CERT_TYPE_PKCS_SIGNED_DATA = 0x0002;
                // const short WIN_CERT_TYPE_RESERVED_1 = 0x0003;
                // const short WIN_CERT_TYPE_TS_STACK_SIGNED = 0x0004;
                data = BitConverterLE.GetBytes(WIN_CERT_REVISION_2_0);
                fs.Write(data, 0, data.Length);
                data = BitConverterLE.GetBytes(WIN_CERT_TYPE_PKCS_SIGNED_DATA);
                fs.Write(data, 0, data.Length);
                fs.Write(asn, 0, asn.Length);
                if (addsize_signature > 0)
                {
                    byte[] fillup = new byte[addsize_signature];
                    fs.Write(fillup, 0, fillup.Length);
                }
                fs.Close();
            }
            return(true);
        }
 protected override void Decode(byte[] message)
 {
     base.Decode(message);
     base.Flags = (NtlmFlags)BitConverterLE.ToUInt32(message, 20);
     Buffer.BlockCopy(message, 24, this._nonce, 0, 8);
 }
Example #8
0
        internal int ProcessFirstBlock()
        {
            if (fs == null)
            {
                return(1);
            }

            fs.Position = 0;
            // read first block - it will include (100% sure)
            // the MZ header and (99.9% sure) the PE header
            blockLength = fs.Read(fileblock, 0, fileblock.Length);
            blockNo     = 1;
            if (blockLength < 64)
            {
                return(2);                      // invalid PE file
            }
            // 1. Validate the MZ header informations
            // 1.1. Check for magic MZ at start of header
            if (BitConverterLE.ToUInt16(fileblock, 0) != 0x5A4D)
            {
                return(3);
            }

            // 1.2. Find the offset of the PE header
            peOffset = BitConverterLE.ToInt32(fileblock, 60);
            if (peOffset > fileblock.Length)
            {
                // just in case (0.1%) this can actually happen
                // FIXME This does not mean the file is invalid,
                // just that this code cannot handle it.
                // FIXME Read the entire file into memory.
                // See earlier comments.
                string msg = String.Format("Header size too big (> {0} bytes).",
                                           fileblock.Length);
                throw new NotSupportedException(msg);
            }
            // FIXME This verifies that PE starts within the file,
            // but not that it fits.
            if (peOffset > fs.Length)
            {
                return(4);
            }

            // 2. Read between DOS header and first part of PE header
            // 2.1. Check for magic PE at start of header
            //	PE - NT header ('P' 'E' 0x00 0x00)
            if (BitConverterLE.ToUInt32(fileblock, peOffset) != 0x4550)
            {
                return(5);
            }

            // PE signature is followed by 20 byte file header, and
            // then 2 byte magic 0x10B for PE32 or 0x20B for PE32+,
            // or 0x107 for the obscure ROM case.
            // FIXME The code historically ignored this magic value
            // entirely, so we only treat 0x20B differently to maintain
            // this dubious behavior.
            // FIXME The code also lacks range checks in a number of places,
            // and will access arrays out of bounds for valid files.

            ushort    magic = BitConverterLE.ToUInt16(fileblock, peOffset + 24);
            const int IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20B;

            pe64 = magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;

            // FIXME This fails to validate NumberOfRvasAndSizes.
            // 2.2. Locate IMAGE_DIRECTORY_ENTRY_SECURITY (offset and size)
            // These offsets are from the documentation, but add 24 for
            // PE signature and file header.
            if (pe64)
            {
                dirSecurityOffset = BitConverterLE.ToInt32(fileblock, peOffset + 168);
                dirSecuritySize   = BitConverterLE.ToInt32(fileblock, peOffset + 168 + 4);
            }
            else
            {
                dirSecurityOffset = BitConverterLE.ToInt32(fileblock, peOffset + 152);
                dirSecuritySize   = BitConverterLE.ToInt32(fileblock, peOffset + 156);
            }

            // FIXME Remove this code and the dependency on it.
            coffSymbolTableOffset = BitConverterLE.ToInt32(fileblock, peOffset + 12);

            return(0);
        }
Example #9
0
 public static byte[] I2OSP(int x, int size)
 {
     byte[] bytes = BitConverterLE.GetBytes(x);
     Array.Reverse(bytes, 0, bytes.Length);
     return(PKCS1.I2OSP(bytes, size));
 }
Example #10
0
        public void Save(string filename, string password)
        {
            if (filename == null)
            {
                throw new ArgumentNullException("filename");
            }

            byte[]     blob = null;
            FileStream fs   = File.Open(filename, FileMode.Create, FileAccess.Write);

            try {
                // header
                byte[] empty = new byte [4];
                byte[] data  = BitConverterLE.GetBytes(magic);
                fs.Write(data, 0, 4);                   // magic
                fs.Write(empty, 0, 4);                  // reserved
                data = BitConverterLE.GetBytes(keyType);
                fs.Write(data, 0, 4);                   // key type

                encrypted = (password != null);
                blob      = CryptoConvert.ToCapiPrivateKeyBlob(rsa);
                if (encrypted)
                {
                    data = BitConverterLE.GetBytes(1);
                    fs.Write(data, 0, 4);                       // encrypted
                    data = BitConverterLE.GetBytes(16);
                    fs.Write(data, 0, 4);                       // saltlen
                    data = BitConverterLE.GetBytes(blob.Length);
                    fs.Write(data, 0, 4);                       // keylen

                    byte[] salt = new byte [16];
                    RC4    rc4  = RC4.Create();
                    byte[] key  = null;
                    try {
                        // generate new salt (16 bytes)
                        RandomNumberGenerator rng = RandomNumberGenerator.Create();
                        rng.GetBytes(salt);
                        fs.Write(salt, 0, salt.Length);
                        key = DeriveKey(salt, password);
                        if (Weak)
                        {
                            Array.Clear(key, 5, 11);
                        }
                        ICryptoTransform enc = rc4.CreateEncryptor(key, null);
                        // we don't encrypt the header part of the BLOB
                        enc.TransformBlock(blob, 8, blob.Length - 8, blob, 8);
                    }
                    finally {
                        Array.Clear(salt, 0, salt.Length);
                        Array.Clear(key, 0, key.Length);
                        rc4.Clear();
                    }
                }
                else
                {
                    fs.Write(empty, 0, 4);                      // encrypted
                    fs.Write(empty, 0, 4);                      // saltlen
                    data = BitConverterLE.GetBytes(blob.Length);
                    fs.Write(data, 0, 4);                       // keylen
                }

                fs.Write(blob, 0, blob.Length);
            }
            finally {
                // BLOB may include an uncrypted keypair
                Array.Clear(blob, 0, blob.Length);
                fs.Close();
            }
        }
Example #11
0
        private bool Decode(byte[] pvk, string password)
        {
            // DWORD magic
            if (BitConverterLE.ToUInt32(pvk, 0) != magic)
            {
                return(false);
            }
            // DWORD reserved
            if (BitConverterLE.ToUInt32(pvk, 4) != 0x0)
            {
                return(false);
            }
            // DWORD keytype
            keyType = BitConverterLE.ToInt32(pvk, 8);
            // DWORD encrypted
            encrypted = (BitConverterLE.ToUInt32(pvk, 12) == 1);
            // DWORD saltlen
            int saltlen = BitConverterLE.ToInt32(pvk, 16);
            // DWORD keylen
            int keylen = BitConverterLE.ToInt32(pvk, 20);

            byte[] keypair = new byte [keylen];
            Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
            // read salt (if present)
            if (saltlen > 0)
            {
                if (password == null)
                {
                    return(false);
                }

                byte[] salt = new byte [saltlen];
                Buffer.BlockCopy(pvk, 24, salt, 0, saltlen);
                // first try with full (128) bits
                byte[] key = DeriveKey(salt, password);
                // decrypt in place and try this
                RC4 rc4 = RC4.Create();
                ICryptoTransform dec = rc4.CreateDecryptor(key, null);
                dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                try {
                    rsa  = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                    weak = false;
                }
                catch (CryptographicException) {
                    weak = true;
                    // second chance using weak crypto
                    Buffer.BlockCopy(pvk, 24 + saltlen, keypair, 0, keylen);
                    // truncate the key to 40 bits
                    Array.Clear(key, 5, 11);
                    // decrypt
                    RC4 rc4b = RC4.Create();
                    dec = rc4b.CreateDecryptor(key, null);
                    dec.TransformBlock(keypair, 8, keypair.Length - 8, keypair, 8);
                    rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                }
                Array.Clear(key, 0, key.Length);
            }
            else
            {
                weak = true;
                // read unencrypted keypair
                rsa = CryptoConvert.FromCapiPrivateKeyBlob(keypair);
                Array.Clear(keypair, 0, keypair.Length);
            }

            // zeroize pvk (which could contain the unencrypted private key)
            Array.Clear(pvk, 0, pvk.Length);

            return(rsa != null);
        }
Example #12
0
        private bool Save(string fileName, byte[] asn)
        {
#if DEBUG
            using (FileStream fs = File.Open(fileName + ".sig", FileMode.Create, FileAccess.Write)) {
                fs.Write(asn, 0, asn.Length);
                fs.Close();
            }
#endif
            // someday I may be sure enough to move this into DEBUG ;-)
            File.Copy(fileName, fileName + ".bak", true);

            using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite)) {
                int filesize;
                if (SecurityOffset > 0)
                {
                    // file was already signed, we'll reuse the position for the updated signature
                    filesize = SecurityOffset;
                }
                else if (CoffSymbolTableOffset > 0)
                {
                    // strip (deprecated) COFF symbol table
                    fs.Seek(PEOffset + 12, SeekOrigin.Begin);
                    for (int i = 0; i < 8; i++)
                    {
                        fs.WriteByte(0);
                    }
                    // we'll put the Authenticode signature at this same place (just after the last section)
                    filesize = CoffSymbolTableOffset;
                }
                else
                {
                    // file was never signed, nor does it contains (deprecated) COFF symbols
                    filesize = (int)fs.Length;
                }
                // must be a multiple of 8 bytes
                int addsize = (filesize & 7);
                if (addsize > 0)
                {
                    addsize = 8 - addsize;
                }

                // IMAGE_DIRECTORY_ENTRY_SECURITY (offset, size)
                byte[] data = BitConverterLE.GetBytes(filesize + addsize);
                fs.Seek(PEOffset + 152, SeekOrigin.Begin);
                fs.Write(data, 0, 4);
                int size = asn.Length + 8;
                int addsize_signature = (size & 7);
                if (addsize_signature > 0)
                {
                    addsize_signature = 8 - addsize_signature;
                }
                data = BitConverterLE.GetBytes(size + addsize_signature);
                fs.Seek(PEOffset + 156, SeekOrigin.Begin);
                fs.Write(data, 0, 4);
                fs.Seek(filesize, SeekOrigin.Begin);
                // align certificate entry to a multiple of 8 bytes
                if (addsize > 0)
                {
                    byte[] fillup = new byte[addsize];
                    fs.Write(fillup, 0, fillup.Length);
                }
                fs.Write(data, 0, data.Length);                                 // length (again)
                data = BitConverterLE.GetBytes(0x00020200);                     // magic
                fs.Write(data, 0, data.Length);
                fs.Write(asn, 0, asn.Length);
                if (addsize_signature > 0)
                {
                    byte[] fillup = new byte[addsize_signature];
                    fs.Write(fillup, 0, fillup.Length);
                }
                fs.Close();
            }
            return(true);
        }