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(); }
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; }
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; }