X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FMono.Security.Cryptography%2FPKCS1.cs;h=3b3252db94968196c67ca518cc84b9d2acab953b;hb=0146859e63468733659e108f7e8e4255e9ae0027;hp=f168a29c48b41619723efa867f6952174e03a490;hpb=a097b5471761180c4aae2dab224ed9caeeae3e86;p=mono.git diff --git a/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs b/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs index f168a29c48b..3b3252db949 100644 --- a/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs +++ b/mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs @@ -290,13 +290,39 @@ namespace Mono.Security.Cryptography { // PKCS #1 v.2.1, Section 8.2.2 // RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S) public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte[] hashValue, byte[] signature) + { + return Verify_v15 (rsa, hash, hashValue, signature, false); + } + + // DO NOT USE WITHOUT A VERY GOOD REASON + public static bool Verify_v15 (RSA rsa, HashAlgorithm hash, byte [] hashValue, byte [] signature, bool tryNonStandardEncoding) { int size = (rsa.KeySize >> 3); // div 8 byte[] s = OS2IP (signature); byte[] m = RSAVP1 (rsa, s); byte[] EM2 = I2OSP (m, size); byte[] EM = Encode_v15 (hash, hashValue, size); - return Compare (EM, EM2); + bool result = Compare (EM, EM2); + if (result || !tryNonStandardEncoding) + return result; + + // NOTE: some signatures don't include the hash OID (pretty lame but real) + // and compatible with MS implementation. E.g. Verisign Authenticode Timestamps + + // we're making this "as safe as possible" + if ((EM2 [0] != 0x00) || (EM2 [1] != 0x01)) + return false; + int i; + for (i = 2; i < EM2.Length - hashValue.Length - 1; i++) { + if (EM2 [i] != 0xFF) + return false; + } + if (EM2 [i++] != 0x00) + return false; + + byte [] decryptedHash = new byte [hashValue.Length]; + Buffer.BlockCopy (EM2, i, decryptedHash, 0, decryptedHash.Length); + return Compare (decryptedHash, hashValue); } // PKCS #1 v.2.1, Section 9.2 @@ -378,7 +404,7 @@ namespace Mono.Security.Cryptography { Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4); byte[] output = hash.ComputeHash (toBeHashed); Buffer.BlockCopy (output, 0, T, pos, hLen); - pos += mgfSeedLength; + pos += hLen; } // 4. Output the leading maskLen octets of T as the octet string mask.