public SignedObjRet ValidateSignature(byte[] signedObj, HashAlgorithm preHash, SignedDataIndex inIndex) { long num1 = 0; if (signedObj.Length == 0) { return(SignedObjRet.InvalidSignature); } if (inIndex == null) { this.sdIndex = new SignedDataIndex(signedObj); if (!this.sdIndex.FindTags()) { return(SignedObjRet.InvalidSignature); } } else { this.sdIndex = inIndex; } this.CleanUp(); byte[] numArray1 = new byte[this.signedDataOid.Length]; Buffer.BlockCopy((Array)signedObj, (int)this.sdIndex.SignedDataObjectId, (Array)numArray1, 0, numArray1.Length); if (!SignedObjectAsn.CompareByteArrays(this.signedDataOid, numArray1) || this.sdIndex.CertList == 0L) { return(SignedObjRet.InvalidSignature); } long certListLen = this.sdIndex.CertListLen; long certListData = this.sdIndex.CertListData; while (certListLen > 0L) { long length = AbstractSyntaxNotationType.GetCurrentTypeLen(signedObj, ref certListData, false) + AbstractSyntaxNotationType.GetCurrentTagLen(signedObj, ref certListData, false); byte[] cert = new byte[length]; Buffer.BlockCopy((Array)signedObj, (int)certListData, (Array)cert, 0, (int)length); certListLen -= (long)cert.Length; if (!this.SetupMemStore(cert)) { return(SignedObjRet.InvalidSignature); } certListData += length; } this.sigCert = this.FindCertInStore(SignedObjectAsn.CreateHexString(signedObj, this.sdIndex.SignatureCertSerial, this.sdIndex.SignatureCertSerialLen)); if (this.sigCert == null) { return(SignedObjRet.InvalidSignature); } this.signerCert = this.sigCert.Handle; RSAParameters rsa = new RSAParameters(); if (!SignedObjectAsn.ConvertX509PublicKey(this.sigCert, ref rsa)) { return(SignedObjRet.InvalidSignature); } using (RSACryptoServiceProvider rsaManaged = new RSACryptoServiceProvider()) { ((RSA)rsaManaged).ImportParameters(rsa); byte[] authenticodeSigHash = this.ComputeAuthenticodeSigHash(signedObj, preHash); num1 = this.sdIndex.EncryptedDigest; byte[] numArray2 = new byte[this.sdIndex.EncryptedDigestLen]; Buffer.BlockCopy((Array)signedObj, (int)this.sdIndex.EncryptedDigestData, (Array)numArray2, 0, numArray2.Length); string str; if (preHash.Hash.Length == 20) { str = CryptoConfig.MapNameToOID("SHA1"); } else { str = preHash.Hash.Length != 32 ? CryptoConfig.MapNameToOID("MD5") : "2.16.840.1.101.3.4.2.1"; } if (!rsaManaged.VerifyHash(authenticodeSigHash, str, numArray2)) { return(SignedObjRet.InvalidSignature); } } X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String("-----BEGIN CERTIFICATE-----MIIDrDCCApSgAwIBAgIQM2O00UXfpQityCo2+LaytDANBgkqhkiG9w0BAQUFADBw\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXSGV3bGV0dC1QYWNrYXJkIENvbXBhbnkx\nPzA9BgNVBAMTNkhld2xldHQtUGFja2FyZCBQcmludGluZyBEZXZpY2UgSW5mcmFz\ndHJ1Y3R1cmUgUm9vdCBDQTAeFw0wNTA1MjQwMDAwMDBaFw0zODAxMDEyMzU5NTla\nMHAxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdIZXdsZXR0LVBhY2thcmQgQ29tcGFu\neTE/MD0GA1UEAxM2SGV3bGV0dC1QYWNrYXJkIFByaW50aW5nIERldmljZSBJbmZy\nYXN0cnVjdHVyZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAoT+gCaPVpaL3pZhIzso7zBiUxEldsASpXzfgUQdguxJsNVIoqNOQ3IUefmUf\ndfmYrf0ksh0bBNwVp7JlP/vtK01EbXefRHVRPwVIjYqmMPrOUjfVAam8SrOnA3rw\nVxyBJRedg2+gnwkZQ4prPKkMcnyd1p1/86SQPsLGJJx9zRleZ7Ix5QKJAGeH1ED0\n89E7uJYbOsd1XclsdunlNByrG9Z9b2/l95YaF3GLSiB4g82/flfEw7lZOtjBMHiL\nEl0BUTRMuaSherT5KDW5mApE4R82UvnPNTyVz2yb7DTU+MBc4WRClV/wtj2GkVaA\nvt1KyUODNujmkMAtI565aJFgrQIDAQABo0IwQDASBgNVHRMBAf8ECDAGAQH/AgEB\nMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUjPJcdcgMB+Kxa9uR0J3xCg9pdp4wDQYJ\nKoZIhvcNAQEFBQADggEBAEu1SPC8j53+eHkh9uYrj+38+Zl7sd0dLxOZdQ+cQs67\nahOKYcXU9kBAnKDNIfIXP1tnMbBTxCSG2WCum42cbrdvg1FxeQkY/bRyiDZgijGm\nEAsXCqGd1HJzCbLIjcTbqzXBjUWulj0KP743GgjTGw1+Le8B+V7/8nscFsdxXdas\nff6/fWXYWuiKtJq21mFq9+5fJNP6ynADccoq3h97icwf6c79TQ/Kl9+XFiv8KJfK\nZF4pY0jRYytcZ/VaiMSE58IhbCMN/TyHoGGiZL5j1AqRFIogL3SRfopDtYfmuYf+\nQBZnAFq20BlsBWDioLeN3S/l6zOLxOkoHuWibN6Wg8A=\n-----END CERTIFICATE-----".Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", ""))); using (HPX509Store hpX509Store = new HPX509Store(StoreName.Root, StoreLocation.LocalMachine)) { hpX509Store.Open(OpenFlags.ReadWrite); hpX509Store.Add(certificate); } uint num2 = this.VerifyCertChain(this.memCertStore, this.signerCert, true); bool timeCheck = false; if ((int)num2 != 0) { if ((int)num2 != 1) { return(SignedObjRet.InvalidSignature); } timeCheck = true; } //this.rootCert = NativeMethods.ChainRootCert(this.signerCert, this.memCertStore); //this.rootCert = GetRootCert(this.sigCert); if (/*!SignedObjectAsn.CompareByteArrays(new X509Certificate2(this.rootCert).GetCertHash(), certificate.GetCertHash()) ||*/ this.sdIndex.NonAuthAttributes == 0L && timeCheck) { return(SignedObjRet.InvalidSignature); } return(this.sdIndex.NonAuthAttributes != 0L && !this.VerifyTimeStamp(signedObj, timeCheck) ? SignedObjRet.InvalidTimestamp : SignedObjRet.ValidSignature); }
public SignedObjRet ValidatePeSignature(string fileName) { try { using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] numArray1 = new byte[8192]; int bytesRead = file.Read(numArray1, 0, numArray1.Length); if (bytesRead < 576 || 23117 != (int)BitConverter.ToUInt16(numArray1, 0)) { return(SignedObjRet.InvalidFileFormat); } int int32_1 = BitConverter.ToInt32(numArray1, 60); //This check looks for the string "PE" at offset *numArray1[3C] = 0x80 if (int32_1 > numArray1.Length || (int)BitConverter.ToUInt32(numArray1, int32_1) != 17744) { return(SignedObjRet.InvalidFileFormat); } //Now we index 152 bytes into the PE = 0x80 + 0x98 = 0x118 = this should specify an offset to //beginning of numArray2 int int32_2 = BitConverter.ToInt32(numArray1, int32_1 + 152); //Grab the int at index 0x80 + 0x9C = 0x11C int int32_3 = BitConverter.ToInt32(numArray1, int32_1 + 156); if (int32_3 <= 8 || ((long)int32_2 > file.Length || (long)(int32_2 + int32_3) > file.Length || int32_3 > 65536)) { return(SignedObjRet.InvalidFileFormat); } long position = file.Position; byte[] numArray2 = new byte[int32_3 - 8]; if (file.Position != (long)(int32_2 + 8)) { file.Seek((long)(int32_2 + 8), SeekOrigin.Begin); } file.Read(numArray2, 0, int32_3 - 8); SignedDataIndex inIndex = new SignedDataIndex(numArray2); inIndex.FindTags(); byte[] numArray3 = new byte[inIndex.SigHashOidLen]; Buffer.BlockCopy((Array)numArray2, (int)inIndex.SigHashOid, (Array)numArray3, 0, numArray3.Length); HashAlgorithm hashAlgorithm = !SignedObjectAsn.CompareByteArrays(numArray3, this.sha1Oid) ? (!SignedObjectAsn.CompareByteArrays(numArray3, this.sha256Oid) ? (HashAlgorithm) new MD5CryptoServiceProvider() : (HashAlgorithm) new WinSHA256()) : (HashAlgorithm) new SHA1CryptoServiceProvider(); using (hashAlgorithm) { file.Seek(position, SeekOrigin.Begin); SignedObject.PeHash(file, hashAlgorithm, numArray1, int32_1, int32_2, bytesRead); using (SignedObjectAsn signedObjectAsn = new SignedObjectAsn()) return(signedObjectAsn.ValidateSignature(numArray2, hashAlgorithm, inIndex)); } } } catch (ObjectDisposedException ex) { return(SignedObjRet.InvalidSignature); } catch (InvalidOperationException ex) { return(SignedObjRet.InvalidFileFormat); } catch (ArgumentException ex) { return(SignedObjRet.InvalidFileFormat); } catch (IOException ex) { return(SignedObjRet.InvalidFileFormat); } catch (COMException ex) { return(SignedObjRet.InvalidSignature); } }