3c500c5fdb6bf9347ece63cff6a7edc1f6f0082d
[mono.git] / mcs / class / referencesource / mscorlib / system / security / cryptography / rsapkcs1signaturedeformatter.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 // 
8
9 //
10 // RSAPKCS1SignatureDeformatter.cs
11 //
12
13 using System;
14 using System.Diagnostics.Contracts;
15 using System.Security.Cryptography.X509Certificates;
16
17 namespace System.Security.Cryptography {
18     [System.Runtime.InteropServices.ComVisible(true)]
19     public class RSAPKCS1SignatureDeformatter : AsymmetricSignatureDeformatter {
20         //
21         //  This class provides the PKCS#1 v1.5 signature format processing during
22         //  the verification process (i.e. decrypting the object).  The class has
23         //  some special code for dealing with the CSP based RSA keys as the 
24         //  formatting and verification is done within the CSP rather than in
25         //  managed code.
26         //
27
28         private RSA    _rsaKey; // RSA Key value to do decrypt operation
29         private String _strOID; // OID value for the HASH algorithm
30
31         //
32         // public constructors
33         //
34
35         public RSAPKCS1SignatureDeformatter() {}
36         public RSAPKCS1SignatureDeformatter(AsymmetricAlgorithm key) {
37             if (key == null) 
38                 throw new ArgumentNullException("key");
39             Contract.EndContractBlock();
40             _rsaKey = (RSA) key;
41         }
42
43         //
44         // public methods
45         //
46
47         public override void SetKey(AsymmetricAlgorithm key) {
48             if (key == null) 
49                 throw new ArgumentNullException("key");
50             Contract.EndContractBlock();
51             _rsaKey = (RSA) key;
52         }
53
54         public override void SetHashAlgorithm(String strName) {
55             _strOID = CryptoConfig.MapNameToOID(strName, OidGroup.HashAlgorithm);
56         }
57
58         [System.Security.SecuritySafeCritical]  // auto-generated
59         public override bool VerifySignature(byte[] rgbHash, byte[] rgbSignature) {
60             if (rgbHash == null)
61                 throw new ArgumentNullException("rgbHash");
62             if (rgbSignature == null)
63                 throw new ArgumentNullException("rgbSignature");
64             Contract.EndContractBlock();
65
66             if (_strOID == null)
67                 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingOID"));
68             if (_rsaKey == null)
69                 throw new CryptographicUnexpectedOperationException(Environment.GetResourceString("Cryptography_MissingKey"));
70
71             // Two cases here -- if we are talking to the CSP version or if we are talking to some other RSA provider.
72             if (_rsaKey is RSACryptoServiceProvider) {
73                 int calgHash = X509Utils.GetAlgIdFromOid(_strOID, OidGroup.HashAlgorithm);
74                 return ((RSACryptoServiceProvider)_rsaKey).VerifyHash(rgbHash, calgHash, rgbSignature);
75             }
76             else {
77                 byte[] pad = Utils.RsaPkcs1Padding(_rsaKey, CryptoConfig.EncodeOID(_strOID), rgbHash);
78                 // Apply the public key to the signature data to get back the padded buffer actually signed.
79                 // Compare the two buffers to see if they match; ignoring any leading zeros
80                 return Utils.CompareBigIntArrays(_rsaKey.EncryptValue(rgbSignature), pad);
81             }
82         }
83     }
84 }