/****************** * protected methods */ protected static OffsetTable ReadOffsetTable(OTFile file, uint filepos) { // read the Offset Table from the file const int SIZEOF_OFFSETTABLE = 12; OffsetTable ot = null; // read the offset table MBOBuffer buf = file.ReadPaddedBuffer(filepos, SIZEOF_OFFSETTABLE); if (buf != null) { if (OTFile.IsValidSfntVersion(buf.GetUint(0))) { ot = new OffsetTable(buf); } } // now read the directory entries if (ot != null) { const int SIZEOF_DIRECTORYENTRY = 16; for (int i = 0; i < ot.numTables; i++) { uint dirFilePos = (uint)(filepos + SIZEOF_OFFSETTABLE + i * SIZEOF_DIRECTORYENTRY); MBOBuffer DirEntBuf = file.ReadPaddedBuffer(dirFilePos, SIZEOF_DIRECTORYENTRY); if (DirEntBuf != null) { DirectoryEntry de = new DirectoryEntry(DirEntBuf); ot.DirectoryEntries.Add(de); } else { Debug.Assert(false); break; } } } return(ot); }
/****************** * protected methods */ protected static OffsetTable ReadOffsetTable(OTFile file, uint filepos) { // read the Offset Table from the file const int SIZEOF_OFFSETTABLE = 12; OffsetTable ot = null; // read the offset table MBOBuffer buf = file.ReadPaddedBuffer(filepos, SIZEOF_OFFSETTABLE); if (buf != null) { if (OTFile.IsValidSfntVersion(buf.GetUint(0))) { ot = new OffsetTable(buf); } } // now read the directory entries if (ot != null) { const int SIZEOF_DIRECTORYENTRY = 16; for (int i=0; i<ot.numTables; i++) { uint dirFilePos = (uint)(filepos+SIZEOF_OFFSETTABLE+i*SIZEOF_DIRECTORYENTRY); MBOBuffer DirEntBuf = file.ReadPaddedBuffer(dirFilePos, SIZEOF_DIRECTORYENTRY); if (DirEntBuf != null) { DirectoryEntry de = new DirectoryEntry(DirEntBuf); ot.DirectoryEntries.Add(de); } else { Debug.Assert(false); break; } } } return ot; }
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; }
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(); }
/************************ * public static methods */ public static TTCHeader ReadTTCHeader(OTFile file) { TTCHeader ttc = null; const int SIZEOF_FIRSTTHREEFIELDS = 12; const int SIZEOF_UINT = 4; // read the first three fields of the TTC Header // starting at the beginning of the file MBOBuffer buf = file.ReadPaddedBuffer(0, SIZEOF_FIRSTTHREEFIELDS); OTTag tag = null; uint version = 0; uint DirectoryCount = 0; if (buf != null) { tag = new OTTag(buf.GetBuffer()); version = buf.GetUint(4); DirectoryCount = buf.GetUint(8); } // if the tag and the version and the dir count seem correct then // allocate a TTCHeader object and try to read the rest of the header if ((string)tag == "ttcf" && (version == 0x00010000 || version == 0x00020000) && 12 + DirectoryCount * SIZEOF_UINT < file.GetFileLength()) { ttc = new TTCHeader(); ttc.TTCTag = tag; ttc.version = version; ttc.DirectoryCount = DirectoryCount; // Directory offsets buf = file.ReadPaddedBuffer(SIZEOF_FIRSTTHREEFIELDS, DirectoryCount*SIZEOF_UINT); if (buf != null) { for (uint i=0; i<ttc.DirectoryCount; i++) { uint offset = buf.GetUint(i*SIZEOF_UINT); ttc.DirectoryOffsets.Add(offset); } } // only read Dsig fields if version 2.0 and last buffer was successfully read if ((version == 0x00010000 || version == 0x00020000) && buf != null) { uint filepos = SIZEOF_FIRSTTHREEFIELDS + DirectoryCount*SIZEOF_UINT; buf = file.ReadPaddedBuffer(filepos, 3*SIZEOF_UINT); if (buf != null) { // DsigTag ttc.DsigTag = new OTTag(buf.GetBuffer()); if ( ( version == 0x00010000 ) && ( (string) ttc.DsigTag != "DSIG" ) ) { // failed v1 trial - reset & bail ttc.DsigTag = null; return ttc; } // DsigLength ttc.DsigLength = buf.GetUint(4); // DsigOffset ttc.DsigOffset = buf.GetUint(8); } } } return ttc; }
/************************ * public static methods */ public static TTCHeader ReadTTCHeader(OTFile file) { TTCHeader ttc = null; const int SIZEOF_FIRSTTHREEFIELDS = 12; const int SIZEOF_UINT = 4; // read the first three fields of the TTC Header // starting at the beginning of the file MBOBuffer buf = file.ReadPaddedBuffer(0, SIZEOF_FIRSTTHREEFIELDS); OTTag tag = null; uint version = 0; uint DirectoryCount = 0; if (buf != null) { tag = new OTTag(buf.GetBuffer()); version = buf.GetUint(4); DirectoryCount = buf.GetUint(8); } // if the tag and the version and the dir count seem correct then // allocate a TTCHeader object and try to read the rest of the header if ((string)tag == "ttcf" && (version == 0x00010000 || version == 0x00020000) && 12 + DirectoryCount * SIZEOF_UINT < file.GetFileLength()) { ttc = new TTCHeader(); ttc.TTCTag = tag; ttc.version = version; ttc.DirectoryCount = DirectoryCount; // Directory offsets buf = file.ReadPaddedBuffer(SIZEOF_FIRSTTHREEFIELDS, DirectoryCount * SIZEOF_UINT); if (buf != null) { for (uint i = 0; i < ttc.DirectoryCount; i++) { uint offset = buf.GetUint(i * SIZEOF_UINT); ttc.DirectoryOffsets.Add(offset); } } // only read Dsig fields if version 2.0 and last buffer was successfully read if ((version == 0x00010000 || version == 0x00020000) && buf != null) { uint filepos = SIZEOF_FIRSTTHREEFIELDS + DirectoryCount * SIZEOF_UINT; buf = file.ReadPaddedBuffer(filepos, 3 * SIZEOF_UINT); if (buf != null) { // DsigTag ttc.DsigTag = new OTTag(buf.GetBuffer()); if ((version == 0x00010000) && ((string)ttc.DsigTag != "DSIG")) { // failed v1 trial - reset & bail ttc.DsigTag = null; return(ttc); } // DsigLength ttc.DsigLength = buf.GetUint(4); // DsigOffset ttc.DsigOffset = buf.GetUint(8); } } } return(ttc); }
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; int verbose = 0; string filename = null; 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); } } 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 e) { 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); } Console.WriteLine( "#Certificates: {0}", cms.Certificates.Count ); foreach ( var x509 in cms.Certificates ) { if ( verbose > 0 ) { Console.WriteLine(x509); } else { Console.WriteLine(x509.IssuerName.Name); } }; 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); Console.WriteLine("Digest Algorithm: {0}", (new Oid(algo)).FriendlyName); byte[] Value = digest.Value; StringBuilder hexLine = new StringBuilder (); for (int i = 0; i < Value.Length; i++) { hexLine.AppendFormat ("{0} ", Value [i].ToString ("X2")); } hexLine.AppendFormat (Environment.NewLine); Console.WriteLine("{0} Digest: {1}", (new Oid(algo)).FriendlyName, hexLine); } return 0; }