2 // X509AsymmetricSecurityKey.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections.Generic;
31 using System.IdentityModel.Policy;
32 using System.Security.Cryptography;
33 using System.Security.Cryptography.X509Certificates;
34 using System.Security.Cryptography.Xml;
36 namespace System.IdentityModel.Tokens
38 public class X509AsymmetricSecurityKey : AsymmetricSecurityKey
40 public X509AsymmetricSecurityKey (X509Certificate2 certificate)
42 if (certificate == null)
43 throw new ArgumentNullException ("certificate");
47 X509Certificate2 cert;
49 // AsymmetricSecurityKey implementation
51 public override AsymmetricAlgorithm GetAsymmetricAlgorithm (
52 string algorithm, bool privateKey)
54 if (algorithm == null)
55 throw new ArgumentNullException ("algorithm");
56 if (privateKey && !cert.HasPrivateKey)
57 throw new NotSupportedException ("The certificate does not contain a private key.");
59 AsymmetricAlgorithm alg = privateKey ?
60 cert.PrivateKey : cert.PublicKey.Key;
63 // case SignedXml.XmlDsigDSAUrl:
66 // throw new NotSupportedException (String.Format ("The certificate does not contain DSA private key while '{0}' requires it.", algorithm));
67 case EncryptedXml.XmlEncRSA15Url:
68 case EncryptedXml.XmlEncRSAOAEPUrl:
69 case SignedXml.XmlDsigRSASHA1Url:
70 case SecurityAlgorithms.RsaSha256Signature:
73 throw new NotSupportedException (String.Format ("The certificate does not contain RSA private key while '{0}' requires it.", algorithm));
76 throw new NotSupportedException (String.Format ("The asymmetric algorithm '{0}' is not supported.", algorithm));
79 public override HashAlgorithm GetHashAlgorithmForSignature (
82 if (algorithm == null)
83 throw new ArgumentNullException ("algorithm");
85 //case SignedXml.XmlDsigDSAUrl: // it is documented as supported, but it isn't in reality and it wouldn't be possible.
86 case SignedXml.XmlDsigRSASHA1Url:
87 return new SHA1Managed ();
88 case SecurityAlgorithms.RsaSha256Signature:
89 return new SHA256Managed ();
91 throw new NotSupportedException (String.Format ("'{0}' Hash algorithm is not supported in this security key.", algorithm));
95 public override AsymmetricSignatureDeformatter GetSignatureDeformatter (string algorithm)
98 //case SignedXml.XmlDsigDSAUrl:
99 // DSA dsa = (cert.PublicKey.Key as DSA);
100 // if (dsa == null) {
101 // throw new NotSupportedException (String.Format ("The certificate does not contain DSA public key while '{0}' requires it.", algorithm));
104 // return new DSASignatureDeformatter(dsa);
106 case SignedXml.XmlDsigRSASHA1Url:
107 case SecurityAlgorithms.RsaSha256Signature:
108 RSA rsa = (cert.PublicKey.Key as RSA);
110 throw new NotSupportedException (String.Format ("The certificate does not contain RSA public key while '{0}' requires it.", algorithm));
113 return new RSAPKCS1SignatureDeformatter (rsa);
116 throw new NotSupportedException (String.Format ("'{0}' Hash algorithm is not supported in this security key.", algorithm));
120 public override AsymmetricSignatureFormatter GetSignatureFormatter (string algorithm)
123 //case SignedXml.XmlDsigDSAUrl:
124 // DSA dsa = (cert.PrivateKey as DSA);
125 // if (dsa == null) {
126 // throw new NotSupportedException (String.Format ("The certificate does not contain DSA private key while '{0}' requires it.", algorithm));
129 // return new DSASignatureFormatter(dsa);
131 case SignedXml.XmlDsigRSASHA1Url:
132 case SecurityAlgorithms.RsaSha256Signature:
133 RSA rsa = (cert.PrivateKey as RSA);
135 throw new NotSupportedException (String.Format ("The certificate does not contain RSA private key while '{0}' requires it.", algorithm));
138 return new RSAPKCS1SignatureFormatter (rsa);
141 throw new NotSupportedException (String.Format ("'{0}' Hash algorithm is not supported in this security key.", algorithm));
145 public override bool HasPrivateKey ()
147 return cert.HasPrivateKey;
150 // SecurityKey implementation
152 public override int KeySize {
153 get { return cert.PublicKey.Key.KeySize; }
156 public override byte [] DecryptKey (string algorithm, byte [] keyData)
158 if (algorithm == null)
159 throw new ArgumentNullException ("algorithm");
161 throw new ArgumentNullException ("keyData");
163 if (!HasPrivateKey ())
164 throw new NotSupportedException ("This X509 certificate does not contain private key.");
166 if (cert.PrivateKey.KeyExchangeAlgorithm == null)
167 throw new NotSupportedException ("The exchange algorithm of the X509 certificate private key is null");
170 case EncryptedXml.XmlEncRSA15Url:
171 case EncryptedXml.XmlEncRSAOAEPUrl:
174 throw new NotSupportedException (String.Format ("This X509 security key does not support specified algorithm '{0}'", algorithm));
178 algorithm == EncryptedXml.XmlEncRSAOAEPUrl;
179 return EncryptedXml.DecryptKey (keyData, cert.PrivateKey as RSA, useOAEP);
182 public override byte [] EncryptKey (string algorithm, byte [] keyData)
184 if (algorithm == null)
185 throw new ArgumentNullException ("algorithm");
187 throw new ArgumentNullException ("keyData");
190 case EncryptedXml.XmlEncRSA15Url:
191 case EncryptedXml.XmlEncRSAOAEPUrl:
194 throw new NotSupportedException (String.Format ("This X509 security key does not support specified algorithm '{0}'", algorithm));
198 algorithm == EncryptedXml.XmlEncRSAOAEPUrl;
200 return EncryptedXml.EncryptKey (keyData, cert.PublicKey.Key as RSA, useOAEP);
203 public override bool IsAsymmetricAlgorithm (string algorithm)
205 return GetAlgorithmSupportType (algorithm) == AlgorithmSupportType.Asymmetric;
208 public override bool IsSupportedAlgorithm (string algorithm)
211 case SecurityAlgorithms.RsaV15KeyWrap:
212 case SecurityAlgorithms.RsaOaepKeyWrap:
213 case SecurityAlgorithms.RsaSha1Signature:
214 case SecurityAlgorithms.RsaSha256Signature:
221 public override bool IsSymmetricAlgorithm (string algorithm)
223 return GetAlgorithmSupportType (algorithm) == AlgorithmSupportType.Symmetric;