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(); } }
public virtual float ReadSingle() { FillBuffer(4); return(BitConverterLE.ToSingle(m_buffer, 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()); }
// 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)); }
public virtual double ReadDouble() { FillBuffer(8); return(BitConverterLE.ToDouble(m_buffer, 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); }
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); }
public static byte[] I2OSP(int x, int size) { byte[] bytes = BitConverterLE.GetBytes(x); Array.Reverse(bytes, 0, bytes.Length); return(PKCS1.I2OSP(bytes, size)); }
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(); } }
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); }
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); }