Пример #1
0
        static int Main( string[] args )
        {
            if (args.Length == 0) {
                Console.WriteLine("DSIGInfo [-v] [-v] [-v] fontfile");
                return 0;
            }

            OTFile f = new OTFile();
            Table_DSIG tDSIG = null;
            string filename = null;
            verbose = 0;

            for ( int i = 0; i < args.Length; i++ ) {
                if ( "-v" == args[i] )
                    verbose++;
                else
                    filename = args[i];
            }

            if ( !f.open(filename) )
            {
                    Console.WriteLine("Error: Cannot open {0} as font file", filename);
                    return 0;
            }

            TTCHeader ttc = null;
            if ( f.IsCollection() )
            {
                ttc = f.GetTTCHeader();
                if ( f.GetTableManager().GetUnaliasedTableName(ttc.DsigTag) == "DSIG" )
                {
                MBOBuffer buf = f.ReadPaddedBuffer(ttc.DsigOffset, ttc.DsigLength);
                tDSIG = (Table_DSIG) f.GetTableManager().CreateTableObject(ttc.DsigTag, buf);
                }
                for (uint i = 0; i < f.GetNumFonts() ; i++)
                {
                    OTFont fn = f.GetFont(i);
                    Table_DSIG memDSIG = (Table_DSIG) fn.GetTable("DSIG");
                    if (memDSIG != null)
                    {
                        Console.WriteLine("Warning: DSIG in member font");
                        break;
                    }
                }
            }
            else
            {
                OTFont fn = f.GetFont(0);
                tDSIG = (Table_DSIG) fn.GetTable("DSIG");
            }

            Console.WriteLine("{0} DSIG table: {1}", filename,
                              ( tDSIG == null ) ? "Absent" : "Present" );
            if (tDSIG == null)
                return 0;
            if ( f.IsCollection() && ttc.version != 0x00020000 )
                Console.WriteLine("Warning: TTC has DSIG but header version is 0x{0}, != 0x00020000", ttc.version.ToString("X8"));

            if ( tDSIG.usNumSigs != 1 )
            Console.WriteLine("NumSigs = {0}", tDSIG.usNumSigs);
            for ( uint v = 0; v < tDSIG.usNumSigs ; v++ )
            {
                Table_DSIG.SignatureBlock sgb;
                try {
                    sgb = tDSIG.GetSignatureBlock(v);
                } catch (IndexOutOfRangeException)
                {
                    Console.WriteLine("Error: Out of Range SignatureBlock {0}", v);
                    break;
                }

                SignedCms cms = new SignedCms();
                cms.Decode(sgb.bSignature);

                if ( cms.SignerInfos.Count > 1 )
                Console.WriteLine( "#SignerInfos: {0}", cms.SignerInfos.Count );
                foreach ( var si in cms.SignerInfos )
                {
                    Console.WriteLine(si.Certificate);
                    if ( Type.GetType("Mono.Runtime") == null )
                        foreach ( var ua in si.UnsignedAttributes )
                        {
                            foreach ( var asnd in ua.Values )
                            {
                                try
                                {
                                    ASN1 vv = new ASN1(asnd.RawData);
                                    ASN1 t = new ASN1(vv[3][1][1].Value);
                                    Console.WriteLine("Decoded Signing Time: {0}", ASN1Convert.ToDateTime (t) );
                                }
                                catch (Exception e)
                                {/* Nothing to do */ }
                            }
                        }
                }
                Console.WriteLine( "#Certificates: {0}", cms.Certificates.Count );
            #if HAVE_MONO_X509
                certs =  new Mono.Security.X509.X509CertificateCollection ();
                //Mono.Security.X509.X509Chain signerChain = new Mono.Security.X509.X509Chain ();
            #endif
                foreach ( var x509 in cms.Certificates )
                {
            #if HAVE_MONO_X509
                    certs.Add(new Mono.Security.X509.X509Certificate(x509.RawData));
            #endif
                if ( verbose > 0 )
                {
                    Console.WriteLine(x509);
                }
                else
                {
                    Console.WriteLine(x509.Subject);
                }
                };
            #if HAVE_MONO_X509
                Mono.Security.X509.X509Certificate x = new Mono.Security.X509.X509Certificate(cms.SignerInfos[0].Certificate.RawData);
                Mono.Security.X509.X509Certificate parent = x;
                while (x != null) { // Self-signed is fine - the font bundled CA is self-signed.
                    parent = x; // last valid
                    x = FindCertificateParent (x);
                    if (x != null && x.Equals(parent))
                        break;
                }
            #endif
                ASN1 spc = new ASN1(cms.ContentInfo.Content);

                ASN1 playload_oid = null;
                ASN1 oid = null;
                ASN1 digest = null;
                ASN1 obsolete = null;
                if ( Type.GetType("Mono.Runtime") == null )
                {
                    // DotNet is much saner!
                    playload_oid = spc[0][0];
                    obsolete = spc[0][1][0];
                    oid = spc[1][0][0];
                    digest = spc[1][1];
                }
                else
                {
                    playload_oid = spc[0];
                    obsolete = spc[1][0];
                    oid = spc[2][0][0];
                    digest = spc[2][1];
                }
                string algo = ASN1Convert.ToOid (oid);
                string algoname = (new Oid(algo)).FriendlyName;
                Console.WriteLine("Digest Algorithm: {0}", algoname);
                byte[] Value = digest.Value;
                StringBuilder hexLine_sig = new StringBuilder ();
                for (int i = 0; i < Value.Length; i++) {
                    hexLine_sig.AppendFormat ("{0} ", Value [i].ToString ("X2"));
                }
                hexLine_sig.AppendFormat (Environment.NewLine);

                switch ( algoname )
                {
                    case "md5":
                        hash = HashAlgorithm.Create ("MD5");
                        break;
                    case "sha1":
                        hash = HashAlgorithm.Create ("SHA1");
                        break;
                    default:
                        throw new NotImplementedException("Unknown HashAlgorithm: " + algoname );
                }

                byte[] cdigest;
                if ( f.IsCollection() )
                {
                    cdigest = get_TTC_digest( f );

                }
                else
                {
                    cdigest = get_TTF_digest( f );
                }
                StringBuilder hexLine = new StringBuilder ();
                for (int i = 0; i < cdigest.Length; i++) {
                    hexLine.AppendFormat ("{0} ", cdigest [i].ToString ("X2"));
                }
                hexLine.AppendFormat (Environment.NewLine);
                Console.WriteLine("{0} Signed Digest:\t{1}", algoname.ToUpper(), hexLine_sig);
                Console.WriteLine("Calculated Digest:\t{0}", hexLine);
                string root_thumb = "";
            #if HAVE_MONO_X509
                root_thumb =
                    (new System.Security.Cryptography.X509Certificates.X509Certificate2(parent.RawData)).Thumbprint;
                Console.WriteLine("ChainEnd Name: {0}", parent.SubjectName);
                Console.WriteLine("ChainEnd Self-Signed: {0}", parent.IsSelfSigned);
            #endif
                Console.WriteLine("ChainEnd: {0}", root_thumb);
                bool trusted = false;
                try
                {
                    string root_id = trusted_roots[root_thumb];
                    Console.WriteLine("RootID: {0}", root_id);
                    trusted = true;
                }
                catch (KeyNotFoundException)
                {}
                Console.WriteLine("Trusted: {0}", trusted);
            }

            return 0;
        }
Пример #2
0
        static byte[] get_TTC_digest( OTFile f )
        {
            TTCHeader ttc = f.GetTTCHeader();

            uint back_shift = 12;
            //if ( ttc.version == 0x00020000 )
                back_shift = 0;

            TTCHBuffer ttcb = new TTCHBuffer ( 12 + ttc.DirectoryCount * 4 + 12 - back_shift );

            // write the TTC header
            ttcb.FillUint32MBO((uint) ttc.TTCTag);
            ttcb.FillUint32MBO(ttc.version);
            ttcb.FillUint32MBO(ttc.DirectoryCount);

            for (int i=0; i< f.GetNumFonts() ; i++)
            {
                ttcb.FillUint32MBO( (uint) ttc.DirectoryOffsets[i] - back_shift);
            }
            //if ( ttc.version == 0x00020000 )
            {
                ttcb.FillUint32MBO( 0 );
                ttcb.FillUint32MBO( 0 );
                ttcb.FillUint32MBO( 0 );
            }
            hash.TransformBlock ( ttcb.buffer, 0, ttcb.buffer.Length, ttcb.buffer, 0 );

            // build an array of offset tables
            OffsetTable[] otArr = new OffsetTable[f.GetNumFonts()];
            for (uint iFont=0; iFont<f.GetNumFonts(); iFont++)
            {
                otArr[iFont] = new OffsetTable(new OTFixed(1,0), f.GetFont(iFont).GetNumTables());

                for (ushort i=0; i<f.GetFont(iFont).GetNumTables(); i++) {
                    DirectoryEntry old = f.GetFont(iFont).GetDirectoryEntry(i);
                    DirectoryEntry de = new DirectoryEntry(old);
                    de.offset -= back_shift;
                    otArr[iFont].DirectoryEntries.Add(de);
                }
            }

            if ( (uint) ttc.DirectoryOffsets[(int)f.GetNumFonts()-1] < f.GetFont(0).GetDirectoryEntry(0).offset )
            {
                // assume directory-contiguous
                for (uint iFont=0; iFont<f.GetNumFonts(); iFont++)
                {
                    // write the offset table
                    hash.TransformBlock (otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(),
                                         otArr[iFont].m_buf.GetBuffer(), 0);

                    // write the directory entries
                    for (int i=0; i<f.GetFont(iFont).GetNumTables(); i++)
                    {
                        DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                        hash.TransformBlock (de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(),
                                             de.m_buf.GetBuffer(), 0 );
                    }
                }
            }

            // write out each font
            uint PrevPos = 0;
            for (uint iFont=0; iFont<f.GetNumFonts(); iFont++)
            {
                ushort numTables = f.GetFont(iFont).GetNumTables();

                if ( (uint) ttc.DirectoryOffsets[(int)f.GetNumFonts()-1] > f.GetFont(0).GetDirectoryEntry(0).offset )
                {
                    // assume font-contiguous
                    // write the offset table
                    hash.TransformBlock (otArr[iFont].m_buf.GetBuffer(), 0, (int)otArr[iFont].m_buf.GetLength(),
                                         otArr[iFont].m_buf.GetBuffer(), 0 );

                    // write the directory entries
                    for (int i=0; i<numTables; i++)
                    {
                        DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                        hash.TransformBlock (de.m_buf.GetBuffer(), 0, (int)de.m_buf.GetLength(),
                                             de.m_buf.GetBuffer(), 0 );
                    }
                }

                // write out each table unless a shared version has been written
                for (ushort i=0; i<numTables; i++)
                {
                    DirectoryEntry de = (DirectoryEntry)otArr[iFont].DirectoryEntries[i];
                    if (PrevPos < de.offset) //crude
                    {
                        OTTable table = f.GetFont(iFont).GetTable(de.tag);
                        hash.TransformBlock (table.m_bufTable.GetBuffer(), 0, (int)table.GetBuffer().GetPaddedLength(),
                                             table.m_bufTable.GetBuffer(), 0 );
                        PrevPos = de.offset;
                    }
                }
            }

            byte[] usFlag = {0, 1};
            hash.TransformFinalBlock(usFlag, 0,2);
            return hash.Hash;
        }
Пример #3
0
        static int Main( string[] args )
        {
            verbose = 0;

            if (args.Length == 0) {
                Console.WriteLine("CFFInfo [-v] [-v] [-v] fontfile");
                return 0;
            }

            OTFile f = new OTFile();
            Table_CFF tCFF = null;
            string filename = null;
            verbose = 0;

            for ( int i = 0; i < args.Length; i++ ) {
                if ( "-v" == args[i] )
                    verbose++;
                else
                    filename = args[i];
            }

            if ( !f.open(filename) )
            {
                    Console.WriteLine("Error: Cannot open {0} as font file", filename);
                    return 0;
            }

            if ( f.GetNumFonts() != 1 )
                Console.WriteLine("{0} contains {1} member fonts", filename, f.GetNumFonts() );
            for (uint iFont = 0; iFont < f.GetNumFonts() ; iFont++)
            {
                OTFont fn = f.GetFont(iFont);
                tCFF = (Table_CFF) fn.GetTable("CFF ");

                Console.WriteLine("{0} CFF table: {1}", filename,
                                  ( tCFF == null ) ? "Absent" : "Present" );
                if (tCFF == null)
                    continue;

                /* header */

                /* INDEX's */
                Console.WriteLine("Name:\tcount={0}\tsize={1}",
                                  tCFF.Name.count, tCFF.Name.size);
                Console.WriteLine("TopDICT:\tcount={0}\tsize={1}",
                                  tCFF.TopDICT.count, tCFF.TopDICT.size);
                Console.WriteLine("String:\tcount={0}\tsize={1}",
                                  tCFF.String.count, tCFF.String.size);
                Console.WriteLine("GlobalSubr:\tcount={0}\tsize={1}",
                                  tCFF.GlobalSubr.count, tCFF.GlobalSubr.size);
                /* INDEX success */

                var overlap = new DataOverlapDetector();
                overlap.CheckForNoOverlap(0, tCFF.hdrSize);
                overlap.CheckForNoOverlap(tCFF.Name.begin, tCFF.Name.size);
                overlap.CheckForNoOverlap(tCFF.TopDICT.begin, tCFF.TopDICT.size);
                overlap.CheckForNoOverlap(tCFF.String.begin, tCFF.String.size);
                overlap.CheckForNoOverlap(tCFF.GlobalSubr.begin, tCFF.GlobalSubr.size);

                if ( verbose > 1 )
                {
                    Console.WriteLine("Region-hdr        :\t{0}\t{1}", 0, tCFF.hdrSize);
                    Console.WriteLine("Region-Name       :\t{0}\t{1}", tCFF.Name.begin, tCFF.Name.size);
                    Console.WriteLine("Region-TopDICT    :\t{0}\t{1}", tCFF.TopDICT.begin, tCFF.TopDICT.size);
                    Console.WriteLine("Region-String     :\t{0}\t{1}", tCFF.String.begin, tCFF.String.size);
                    Console.WriteLine("Region-GlobalSubr :\t{0}\t{1}", tCFF.GlobalSubr.begin, tCFF.GlobalSubr.size);
                }
                for(uint i = 0; i< tCFF.Name.count; i++)
                    Console.WriteLine("Name: " + tCFF.Name.GetString(i));

                try{
                    for(uint i = 0; i< tCFF.String.count; i++)
                    {
                        var a = tCFF.String.GetString(i);
                        if ( verbose > 0 )
                            Console.WriteLine("String #{0}: {1}", i, a);
                    }
                }
                catch (DecoderFallbackException)
                {
                    for(uint i = 0; i< tCFF.String.count; i++)
                    {
                        var a = tCFF.String.GetUTFString(i);
                        if ( verbose > 0 )
                            Console.WriteLine("String #{0}: {1}", i, a);
                    }
                }

                for(uint iDICT = 0; iDICT < tCFF.TopDICT.count; iDICT++)
                {
                    var curTopDICT = tCFF.GetTopDICT(iDICT);

                    Console.WriteLine("FullName in TopDICT: " + curTopDICT.FullName);

                    overlap.CheckForNoOverlap((uint)curTopDICT.offsetPrivate, (uint)curTopDICT.sizePrivate);

                    if ( verbose > 1 )
                        Console.WriteLine("Region-Private    :\t{0}\t{1}", curTopDICT.offsetPrivate, curTopDICT.sizePrivate);

                    Console.WriteLine("Offset to Charset:\t"  + curTopDICT.offsetCharset);
                    Console.WriteLine("Offset to Encoding:\t" + curTopDICT.offsetEncoding);

                    Table_CFF.DICTData topPrivateDict = null;
                    try
                    {
                        topPrivateDict = tCFF.GetPrivate(curTopDICT);
                    }
                    catch (ArgumentOutOfRangeException e)
                    {
                        Console.WriteLine("Broken Private Dict:"  + e.Message);
                    }

                    if (topPrivateDict != null && topPrivateDict.Subrs != 0)
                    {
                        var topPrivSubrs = tCFF.GetINDEX(curTopDICT.offsetPrivate + topPrivateDict.Subrs);

                        overlap.CheckForNoOverlap(topPrivSubrs.begin, topPrivSubrs.size);

                        if ( verbose > 1 )
                            Console.WriteLine("Region-PrivSubrs  :\t{0}\t{1}", topPrivSubrs.begin, topPrivSubrs.size);
                    }

                    var CharStrings = tCFF.GetINDEX(curTopDICT.offsetCharStrings);
                    Console.WriteLine("CharStrings count: " + CharStrings.count);

                    overlap.CheckForNoOverlap(CharStrings.begin, CharStrings.size);

                    if ( verbose > 1 )
                        Console.WriteLine("Region-CharStrings:\t{0}\t{1}", CharStrings.begin, CharStrings.size);

                    if (curTopDICT.ROS != null)
                    {
                        Console.WriteLine("CID ROS: " + curTopDICT.ROS);
                        Console.WriteLine("Offset to CID FDSelect:\t" + curTopDICT.offsetFDSelect);
                    }

                    if (curTopDICT.offsetFDArray > 0)
                    {
                        var FDArray = tCFF.GetINDEX(curTopDICT.offsetFDArray);

                        overlap.CheckForNoOverlap(FDArray.begin, FDArray.size);

                        if ( verbose > 1 )
                            Console.WriteLine("Region-FDArray    :\t{0}\t{1}", FDArray.begin, FDArray.size);

                        for(uint i = 0; i< FDArray.count; i++)
                        {
                            var FDict = tCFF.GetDICT(FDArray.GetData(i));
                            Console.WriteLine("CID FontDict #{0}: {1}", i, FDict.FontName);

                            overlap.CheckForNoOverlap((uint)FDict.offsetPrivate, (uint)FDict.sizePrivate);

                            if ( verbose > 1 )
                                Console.WriteLine("Region-CID FontDict #{2}    :\t{0}\t{1}", FDict.offsetPrivate, FDict.sizePrivate, i);

                            Table_CFF.DICTData FDictPrivate = null;
                            try
                            {
                                FDictPrivate = tCFF.GetPrivate(FDict);
                            }
                            catch (ArgumentOutOfRangeException e)
                            {
                                Console.WriteLine("Broken CID FD Private Dict #{0}:{1}", i, e.Message);
                            }

                            if (FDictPrivate != null && FDictPrivate.Subrs != 0)
                            {
                                var PrivSubrs = tCFF.GetINDEX(FDict.offsetPrivate + FDictPrivate.Subrs);

                                overlap.CheckForNoOverlap(PrivSubrs.begin, PrivSubrs.size);
                                if ( verbose > 1 )
                                    Console.WriteLine("Region-CID PrivSubrs #{2}    :\t{0}\t{1}", PrivSubrs.begin, PrivSubrs.size, i);
                            }
                        }
                    }
                }
                Console.WriteLine("Tested region: {0} of {1}",
                                  overlap.Occupied, tCFF.GetLength());

                if ( overlap.ends != tCFF.GetLength() )
                {
                }
            }
            return 0;
        }
Пример #4
0
        public DSIGInfo( string filename )
        {
            fontfile = new OTFile();
            tDSIG = null;

            Warn_TTCv1 = false;
            Warn_DSIG_in_memFonts = false;
            Warn_MalformedSIG = false;
            usNumSigs = 0;

            if ( !fontfile.open(filename) )
            {
                        throw new IOException("Cannot open file " + filename );
            }

            TTCHeader ttc = null;
            if ( fontfile.IsCollection() )
            {
                ttc = fontfile.GetTTCHeader();
                if ( fontfile.GetTableManager().GetUnaliasedTableName(ttc.DsigTag) == "DSIG" )
                {
                MBOBuffer buf = fontfile.ReadPaddedBuffer(ttc.DsigOffset, ttc.DsigLength);
                tDSIG = (Table_DSIG) fontfile.GetTableManager().CreateTableObject(ttc.DsigTag, buf);
                }
                for (uint i = 0; i < fontfile.GetNumFonts() ; i++)
                {
                    OTFont fn = fontfile.GetFont(i);
                    Table_DSIG memDSIG = (Table_DSIG) fn.GetTable("DSIG");
                    if (memDSIG != null)
                    {
                        Warn_DSIG_in_memFonts = true;
                        break;
                    }
                }
            }
            else
            {
                OTFont fn = fontfile.GetFont(0);
                tDSIG = (Table_DSIG) fn.GetTable("DSIG");
            }

            HaveDSIG = ( ( tDSIG == null ) ? false : true );

            // Officially we should only warn if HaveDSIG true
            if ( fontfile.IsCollection() && ttc.version != 0x00020000 )
                Warn_TTCv1 = true;

            if ( HaveDSIG )
                FurtherWork();
        }
Пример #5
0
        static int Main( string[] args )
        {
            verbose = 0;

            if (args.Length == 0) {
                Console.WriteLine("SVGInfo [-v] [-v] [-v] fontfile");
                return 0;
            }

            OTFile f = new OTFile();
            Table_SVG tSVG = null;
            string filename = null;
            verbose = 0;

            for ( int i = 0; i < args.Length; i++ ) {
                if ( "-v" == args[i] )
                    verbose++;
                else
                    filename = args[i];
            }

            if ( !f.open(filename) )
            {
                    Console.WriteLine("Error: Cannot open {0} as font file", filename);
                    return 0;
            }

            for (uint i = 0; i < f.GetNumFonts() ; i++)
            {
                OTFont fn = f.GetFont(i);
                tSVG = (Table_SVG) fn.GetTable("SVG ");

                Console.WriteLine("{0} SVG table: {1}", filename,
                                  ( tSVG == null ) ? "Absent" : "Present" );
                if (tSVG == null)
                    continue;

                Console.WriteLine("version={0}, reserved={1}, offsetToSVGDocIndex={2}, numEntries={3}",
                                  tSVG.version,
                                  tSVG.reserved,
                                  tSVG.offsetToSVGDocIndex,
                                  tSVG.numEntries);

                Console.WriteLine("start\tend\tOffset\tLength");
                Console.WriteLine("=====\t===\t======\t======");
                for (uint j = 0; j < tSVG.numEntries ; j++)
                {
                    var index = tSVG.GetDocIndexEntry(j);
                    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
                                      index.startGlyphID,
                                      index.endGlyphID,
                                      index.svgDocOffset,
                                      index.svgDocLength);
                }

                if ( verbose > 0 )
                {
                    XmlDocument doc = new XmlDocument();
                    if ( verbose < 2 )
                        doc.XmlResolver = null; //suppress network fetch
                    for (uint j = 0; j < tSVG.numEntries ; j++)
                    {
                        var svgdoc = tSVG.GetDoc(j);

                        Console.WriteLine("=={0}==", j);
                        using(MemoryStream ms = new MemoryStream(svgdoc))
                        {
                            doc.Load(ms);
                        }
                        using(XmlTextWriter writer = new XmlTextWriter(Console.Out))
                        {
                            writer.Formatting = Formatting.Indented;
                            writer.Indentation = 4;
                            doc.Save(writer);
                            writer.Flush();
                        }
                        Console.WriteLine(""); //Newline
                    }
                }
            }
            return 0;
        }