Merge pull request #537 from madewokherd/ccwmarshal
[mono.git] / mcs / class / corlib / Mono.Security.Cryptography / PKCS1.cs
index e1fd58d78ddb2d0ee68e0099b66b942973df1434..3b3252db94968196c67ca518cc84b9d2acab953b 100644 (file)
@@ -290,6 +290,12 @@ 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);
@@ -297,17 +303,26 @@ namespace Mono.Security.Cryptography {
                        byte[] EM2 = I2OSP (m, size);
                        byte[] EM = Encode_v15 (hash, hashValue, size);
                        bool result = Compare (EM, EM2);
-                       if (!result) {
-                               // NOTE: some signatures don't include the hash OID (pretty lame but real)
-                               // and compatible with MS implementation
-                               if ((EM2 [0] != 0x00) || (EM2 [1] != 0x01))
+                       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;
-                               // TODO: add more validation
-                               byte[] decryptedHash = new byte [hashValue.Length];
-                               Buffer.BlockCopy (EM2, EM2.Length - hashValue.Length, decryptedHash, 0, decryptedHash.Length);
-                               result = Compare (decryptedHash, hashValue);
                        }
-                       return result;
+                       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
@@ -389,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.