Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs')
-rwxr-xr-xmcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs123
1 files changed, 42 insertions, 81 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs b/mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs
index ea0bd30e242..4d30ea38aab 100755
--- a/mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Authenticode/AuthenticodeDeformatter.cs
@@ -5,7 +5,9 @@
// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -54,9 +56,6 @@ namespace Mono.Security.Authenticode {
private DateTime timestamp;
private X509Certificate signingCertificate;
private int reason;
- private bool trustedRoot;
- private bool trustedTimestampRoot;
- private byte[] entry;
private X509Chain signerChain;
private X509Chain timestampChain;
@@ -70,20 +69,17 @@ namespace Mono.Security.Authenticode {
public AuthenticodeDeformatter (string fileName) : this ()
{
- FileName = fileName;
+ if (!CheckSignature (fileName)) {
+ // invalid or no signature
+ if (signedHash != null)
+ throw new COMException ("Invalid signature");
+ // no exception is thrown when there's no signature in the PE file
+ }
}
public string FileName {
get { return filename; }
- set {
- Reset ();
- try {
- CheckSignature (value);
- }
- catch {
- reason = 1;
- }
- }
+ set { CheckSignature (value); }
}
public byte[] Hash {
@@ -104,7 +100,7 @@ namespace Mono.Security.Authenticode {
public bool IsTrusted ()
{
- if (entry == null) {
+ if (rawData == null) {
reason = 1;
return false;
}
@@ -114,13 +110,13 @@ namespace Mono.Security.Authenticode {
return false;
}
- if ((signerChain.Root == null) || !trustedRoot) {
+ if (signerChain.Root == null) {
reason = 6;
return false;
}
if (timestamp != DateTime.MinValue) {
- if ((timestampChain.Root == null) || !trustedTimestampRoot) {
+ if (timestampChain.Root == null) {
reason = 6;
return false;
}
@@ -142,11 +138,7 @@ namespace Mono.Security.Authenticode {
}
public byte[] Signature {
- get {
- if (entry == null)
- return null;
- return (byte[]) entry.Clone ();
- }
+ get { return (byte[]) rawData.Clone (); }
}
public DateTime Timestamp {
@@ -164,58 +156,43 @@ namespace Mono.Security.Authenticode {
private bool CheckSignature (string fileName)
{
filename = fileName;
- base.Open (filename);
- entry = base.GetSecurityEntry ();
- if (entry == null) {
- // no signature is present
- reason = 1;
- base.Close ();
+
+ // by default we try with MD5
+ string hashName = "MD5";
+ // compare the signature's hash with the hash of the file
+ hash = HashFile (filename, hashName);
+
+ // is a signature present ?
+ if (rawData == null)
return false;
- }
- PKCS7.ContentInfo ci = new PKCS7.ContentInfo (entry);
- if (ci.ContentType != PKCS7.Oid.signedData) {
- base.Close ();
+ PKCS7.ContentInfo ci = new PKCS7.ContentInfo (rawData);
+ if (ci.ContentType != PKCS7.Oid.signedData)
return false;
- }
PKCS7.SignedData sd = new PKCS7.SignedData (ci.Content);
- if (sd.ContentInfo.ContentType != spcIndirectDataContext) {
- base.Close ();
+ if (sd.ContentInfo.ContentType != spcIndirectDataContext)
return false;
- }
coll = sd.Certificates;
ASN1 spc = sd.ContentInfo.Content;
signedHash = spc [0][1][1];
-
- HashAlgorithm ha = null;
- switch (signedHash.Length) {
- case 16:
- ha = HashAlgorithm.Create ("MD5");
- hash = GetHash (ha);
- break;
- case 20:
- ha = HashAlgorithm.Create ("SHA1");
- hash = GetHash (ha);
- break;
- default:
- reason = 5;
- base.Close ();
- return false;
+ if (signedHash.Length == 20) {
+ // seems to be SHA-1, restart hashing
+ hashName = "SHA1";
+ hash = HashFile (filename, hashName);
}
- base.Close ();
if (!signedHash.CompareValue (hash))
return false;
// messageDigest is a hash of spcIndirectDataContext (which includes the file hash)
byte[] spcIDC = spc [0].Value;
- ha.Initialize (); // re-using hash instance
+ HashAlgorithm ha = HashAlgorithm.Create (hashName);
byte[] messageDigest = ha.ComputeHash (spcIDC);
- return VerifySignature (sd, messageDigest, ha);
+ return VerifySignature (sd, messageDigest, hashName);
}
private bool CompareIssuerSerial (string issuer, byte[] serial, X509Certificate x509)
@@ -235,7 +212,7 @@ namespace Mono.Security.Authenticode {
}
//private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName)
- private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha)
+ private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, string hashName)
{
string contentType = null;
ASN1 messageDigest = null;
@@ -264,7 +241,7 @@ namespace Mono.Security.Authenticode {
case "1.3.6.1.4.1.311.2.1.12":
// spcSpOpusInfo (Microsoft code signing)
try {
- spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value);
+ spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][1][0].Value);
}
catch (NullReferenceException) {
spcSpOpusInfo = null;
@@ -284,13 +261,13 @@ namespace Mono.Security.Authenticode {
return false;
// verify signature
- string hashOID = CryptoConfig.MapNameToOID (ha.ToString ());
+ string hashOID = CryptoConfig.MapNameToOID (hashName);
// change to SET OF (not [0]) as per PKCS #7 1.5
ASN1 aa = new ASN1 (0x31);
foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes)
aa.Add (a);
- ha.Initialize ();
+ HashAlgorithm ha = HashAlgorithm.Create (hashName);
byte[] p7hash = ha.ComputeHash (aa.GetBytes ());
byte[] signature = sd.SignerInfo.Signature;
@@ -304,9 +281,10 @@ namespace Mono.Security.Authenticode {
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA;
if (rsa.VerifyHash (p7hash, hashOID, signature)) {
signerChain.LoadCertificates (coll);
- trustedRoot = signerChain.Build (x509);
- signingCertificate = x509;
- break;
+ if (signerChain.Build (x509))
+ signingCertificate = x509;
+ else
+ return false;
}
}
}
@@ -322,18 +300,17 @@ namespace Mono.Security.Authenticode {
// countersignature (1 2 840 113549 1 9 6)
// SET {
PKCS7.SignerInfo cs = new PKCS7.SignerInfo (attr [1]);
- trustedTimestampRoot = VerifyCounterSignature (cs, signature);
- break;
+ return VerifyCounterSignature (cs, signature, hashName);
default:
// we don't support other unauthenticated attributes
break;
}
}
- return (trustedRoot && trustedTimestampRoot);
+ return true;
}
- private bool VerifyCounterSignature (PKCS7.SignerInfo cs, byte[] signature)
+ private bool VerifyCounterSignature (PKCS7.SignerInfo cs, byte[] signature, string hashName)
{
// SEQUENCE {
// INTEGER 1
@@ -380,7 +357,6 @@ namespace Mono.Security.Authenticode {
if (messageDigest == null)
return false;
// TODO: must be read from the ASN.1 structure
- string hashName = null;
switch (messageDigest.Length) {
case 16:
hashName = "MD5";
@@ -421,20 +397,5 @@ namespace Mono.Security.Authenticode {
// no certificate can verify this signature!
return false;
}
-
- private void Reset ()
- {
- filename = null;
- entry = null;
- hash = null;
- signedHash = null;
- signingCertificate = null;
- reason = -1;
- trustedRoot = false;
- trustedTimestampRoot = false;
- signerChain.Reset ();
- timestampChain.Reset ();
- timestamp = DateTime.MinValue;
- }
}
}