Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • r61697 -trunk/mcs/class/Mono.Security/Mono.Security.Authenticode

    0 answers - 10505 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Author: spouliot
    Date: 2006-06-14 11:26:34 -0400 (Wed, 14 Jun 2006)
    New Revision: 61697
    Modified:
    Log:
    2006-06-14 Sebastien Pouliot <sebastien (AT) ximian (DOT) com>
    * AuthenticodeBase.cs: Fix destination offset. Note that this works
    under MS but not under Mono.
    * AuthenticodeDeformatter.cs: Report a more useful error if the file
    hash doesn't match the signed hash.
    * AuthenticodeFormatter.cs: Implemented support for Timestamp method.
    Modified:
    2006-06-14 15:22:57 UTC (rev 61696)
    2006-06-14 15:26:34 UTC (rev 61697)
    @@ -182,7 +182,7 @@
    }
    else {
    // hash the last part of the first (already in memory) block
    -hash.TransformBlock (fileblock, pe, blockLength - pe, fileblock, 0);
    +hash.TransformBlock (fileblock, pe, blockLength - pe, fileblock, pe);
    // hash by blocks of 4096 bytes
    long blocks = (n >12);
    Modified:
    2006-06-14 15:22:57 UTC (rev 61696)
    2006-06-14 15:26:34 UTC (rev 61697)
    @@ -210,8 +210,10 @@
    }
    base.Close ();
    -if (!signedHash.CompareValue (hash))
    +if (!signedHash.CompareValue (hash)) {
    +reason = 2;
    return false;
    +}
    // messageDigest is a hash of spcIndirectDataContext (which includes the file hash)
    byte[] spcIDC = spc [0].Value;
    Modified:
    2006-06-14 15:22:57 UTC (rev 61696)
    2006-06-14 15:26:34 UTC (rev 61697)
    @@ -219,13 +219,60 @@
    (Attribute (countersignature, ts[1][0][4][0]));
    }
    -public bool Sign (string fileName)
    +private byte[] Timestamp (byte[] signature)
    {
    -string hashAlgorithm = "MD5";
    -byte[] file = null;
    +ASN1 tsreq = TimestampRequest (signature);
    +WebClient wc = new WebClient ();
    +wc.Headers.Add ("Content-Type", "application/octet-stream");
    +wc.Headers.Add ("Accept", "application/octet-stream");
    +byte[] tsdata = Encoding.ASCII.GetBytes (Convert.ToBase64String (tsreq.GetBytes ()));
    +return wc.UploadData (timestamp.ToString (), tsdata);
    +}
    +private byte[] file;
    +private int pe_offset = -1;
    +private int sec_offset = -1;
    +private int sec_size = -1;
    +
    +private int PE {
    +get {
    +if (file == null)
    +return -1;
    +if (pe_offset == -1) {
    +int = BitConverterLE.ToInt32 (file, 60);
    +if ( < file.Length)
    +pe_offset = ;
    +}
    +return pe_offset;
    +}
    +}
    +
    +private int S {
    +get {
    +if (file == null)
    +return -1;
    +if (sec_offset == -1) {
    +sec_offset = BitConverterLE.ToInt32 (file, PE + 152);
    +}
    +return sec_offset;
    +}
    +}
    +
    +private int SecuritySize {
    +get {
    +if (file == null)
    +return -1;
    +if (sec_size == -1) {
    +sec_size = BitConverterLE.ToInt32 (file, PE + 156);
    +}
    +return sec_size;
    +}
    +}
    +
    +private bool (string fileName)
    +{
    using (FileStream fs = new FileStream (fileName, FileM, FileAccess.Read, FileShare.Read)) {
    -file = new byte [fs.Length];
    +file = new byte[fs.Length];
    fs.Read (file, 0, file.Length);
    fs.Close ();
    }
    @@ -234,58 +281,27 @@
    if (BitConverterLE.ToUInt16 (file, 0) != 0x5A4D)
    return false;
    -// find offset of PE header
    -int = BitConverterLE.ToInt32 (file, 60);
    -if ( file.Length)
    +// PE Header
    +if (PE == -1)
    return false;
    // PE - NT header
    -if (BitConverterLE.ToUInt16 (file, ) != 0x4550)
    +if (BitConverterLE.ToUInt16 (file, PE) != 0x4550)
    return false;
    // IMAGE_DIRECTRY_ENTRY_SECURITY
    -int dirS = BitConverterLE.ToInt32 (file, + 152);
    -int dirSecuritySize = BitConverterLE.ToInt32 (file, + 156);
    -
    -if (dirSecuritySize 8) {
    -entry = new byte [dirSecuritySize - 8];
    -Buffer.BlockCopy (file, dirS + 8, entry, 0, entry.Length);
    -}
    -else
    +if (SecuritySize 8) {
    +entry = new byte[SecuritySize - 8];
    +Buffer.BlockCopy (file, S + 8, entry, 0, entry.Length);
    +} else
    entry = null;
    -HashAlgorithm hash = HashAlgorithm.Create (hashAlgorithm);
    -// 0 to 215 (216) then skip 4 (checksum)
    -int pe = + 88;
    -hash.TransformBlock (file, 0, pe, file, 0);
    -pe += 4;
    -// 220 to 279 (60) then skip 8 (IMAGE_DIRECTRY_ENTRY_SECURITY)
    -hash.TransformBlock (file, pe, 60, file, pe);
    -pe += 68;
    -// 288 to end of file
    -int n = file.Length - pe;
    -// minus any authenticode signature (with 8 bytes header)
    -if (dirS != 0)
    -n -= (dirSecuritySize);
    -hash.TransformFinalBlock (file, pe, n);
    +return true;
    +}
    -//
    -byte[] signature = Header (hash.Hash, hashAlgorithm);
    -if (timestamp != null) {
    -ASN1 tsreq = TimestampRequest (signature);
    -WebClient wc = new WebClient ();
    -wc.Headers.Add ("Content-Type", "application/octet-stream");
    -wc.Headers.Add ("Accept", "application/octet-stream");
    -byte[] tsdata = Encoding.ASCII.GetBytes (Convert.ToBase64String (tsreq.GetBytes ()));
    -byte[] tsres = wc.UploadData (timestamp.ToString (), tsdata);
    -ProcessTimestamp (tsres);
    -}
    -PKCS7.ContentInfo sign = new PKCS7.ContentInfo (signedData);
    -sign.Content.Add (pkcs7.ASN1);
    -authenticode = sign.ASN1;
    -
    -byte[] asn = authenticode.GetBytes ();
    -#if DEBUG
    +private bool Save (string fileName, byte[] asn)
    +{
    +#if !DEBUG
    using (FileStream fs = F (fileName + ".sig", FileMode.Create, FileAccess.Write)) {
    fs.Write (asn, 0, asn.Length);
    fs.Close ();
    @@ -295,13 +311,13 @@
    File.Copy (fileName, fileName + ".bak", true);
    using (FileStream fs = F (fileName, FileMode.Create, FileAccess.Write)) {
    -int filesize = (dirS == 0) ? file.Length : dirS;
    +int filesize = (S == 0) ? file.Length : S;
    // IMAGE_DIRECTRY_ENTRY_SECURITY (offset, size)
    byte[] data = BitConverterLE.GetBytes (filesize);
    -file [ + 152] = data [0];
    -file [ + 153] = data [1];
    -file [ + 154] = data [2];
    -file [ + 155] = data [3];
    +file[PE + 152] = data[0];
    +file[PE + 153] = data[1];
    +file[PE + 154] = data[2];
    +file[PE + 155] = data[3];
    int size = asn.Length + 8;
    // must be a multiple of 8 bytes
    int addsize = (size % 8);
    @@ -309,27 +325,113 @@
    addsize = 8 - addsize;
    size += addsize;
    data = BitConverterLE.GetBytes (size);// header
    -file [ + 156] = data [0];
    -file [ + 157] = data [1];
    -file [ + 158] = data [2];
    -file [ + 159] = data [3];
    +file[PE + 156] = data[0];
    +file[PE + 157] = data[1];
    +file[PE + 158] = data[2];
    +file[PE + 159] = data[3];
    fs.Write (file, 0, filesize);
    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);
    // fill up
    -byte[] fillup = new byte [addsize];
    +byte[] fillup = new byte[addsize];
    fs.Write (fillup, 0, fillup.Length);
    fs.Close ();
    }
    return true;
    }
    +public bool Sign (string fileName)
    +{
    +try {
    +if (! (fileName))
    +return false;
    +
    +HashAlgorithm hash = HashAlgorithm.Create (Hash);
    +// 0 to 215 (216) then skip 4 (checksum)
    +int pe = PE + 88;
    +hash.TransformBlock (file, 0, pe, file, 0);
    +pe += 4;
    +// 220 to 279 (60) then skip 8 (IMAGE_DIRECTRY_ENTRY_SECURITY)
    +hash.TransformBlock (file, pe, 60, file, pe);
    +pe += 68;
    +// 288 to end of file
    +int n = file.Length - pe;
    +// minus any authenticode signature (with 8 bytes header)
    +if (S != 0)
    +n -= (SecuritySize);
    +hash.TransformFinalBlock (file, pe, n);
    +
    +byte[] signature = Header (hash.Hash, Hash);
    +if (timestamp != null) {
    +byte[] ts = Timestamp (signature);
    +// add timestamp information inside the current pkcs7 SignedData instance
    +// (this is possible because the data isn't yet signed)
    +ProcessTimestamp (ts);
    +}
    +
    +PKCS7.ContentInfo sign = new PKCS7.ContentInfo (signedData);
    +sign.Content.Add (pkcs7.ASN1);
    +authenticode = sign.ASN1;
    +
    +return Save (fileName, authenticode.GetBytes ());
    +}
    +catch (Exception e) {
    +Console.WriteLine (e);
    +}
    +return false;
    +}
    +
    // in case we just want to timestamp the file
    public bool Timestamp (string fileName)
    {
    -return true;
    +try {
    +AuthenticodeDeformatter def = new AuthenticodeDeformatter (fileName);
    +byte[] signature = def.Signature;
    +if ((signature != null) && (fileName)) {
    +PKCS7.ContentInfo ci = new PKCS7.ContentInfo (signature);
    +pkcs7 = new PKCS7.SignedData (ci.Content);
    +
    +byte[] response = Timestamp (pkcs7.SignerInfo.Signature);
    +ASN1 ts = new ASN1 (Convert.FromBase64String (Encoding.ASCII.GetString (response)));
    +// insert new certificates and countersignature into the original signature
    +ASN1 asn = new ASN1 (signature);
    +ASN1 content = asn.Element (1, 0xA0);
    +if (content == null)
    +return false;
    +
    +ASN1 signedData = content.Element (0, 0x30);
    +if (signedData == null)
    +return false;
    +
    +// add the supplied certificates inside our signature
    +ASN1 certificates = signedData.Element (3, 0xA0);
    +if (certificates == null) {
    +certificates = new ASN1 (0xA0);
    +signedData.Add (certificates);
    +}
    +for (int i = 0; i < ts[1][0][3].Count; i++) {
    +certificates.Add (ts[1][0][3][i]);
    +}
    +
    +// add an unauthentified attribute to our signature
    +ASN1 signerInfoSet = signedData[signedData.Count - 1];
    +ASN1 signerInfo = signerInfoSet[0];
    +ASN1 unauthenticated = signerInfo[signerInfo.Count - 1];
    +if (unauthenticated.Tag != 0xA1) {
    +unauthenticated = new ASN1 (0xA1);
    +signerInfo.Add (unauthenticated);
    +}
    +unauthenticated.Add (Attribute (countersignature, ts[1][0][4][0]));
    +
    +return Save (fileName, asn.GetBytes ());
    +}
    +}
    +catch (Exception e) {
    +Console.WriteLine (e);
    +}
    +return false;
    }
    }
    }
    Modified:
    2006-06-14 15:22:57 UTC (rev 61696)
    2006-06-14 15:26:34 UTC (rev 61697)
    @@ -1,3 +1,11 @@
    +2006-06-14 Sebastien Pouliot <sebastien (AT) ximian (DOT) com>
    +
    +* AuthenticodeBase.cs: Fix destination offset. Note that this works
    +under MS but not under Mono.
    +* AuthenticodeDeformatter.cs: Report a more useful error if the file
    +hash doesn't match the signed hash.
    +* AuthenticodeFormatter.cs: Implemented support for Timestamp method.
    +
    2005-04-18 Sebastien Pouliot <sebastien (AT) ximian (DOT) com>
    * AuthenticodeFormatter.cs: Commented unused private constants to
    Mono-patches maillist - Mono-patches (AT) lists (DOT) ximian.com

Re: r61697 -trunk/mcs/class/Mono.Security/Mono.Security.Authenticode


max 4000 letters.
Your nickname that display:
In order to stop the spam: 3 + 3 =
QUESTION ON "Development"

EMSDN.COM