mscorlib(4.0.0.0) API with additions
PublicKey.cs
1 using System.IO;
3 
5 {
7  public sealed class PublicKey
8  {
9  private AsnEncodedData m_encodedKeyValue;
10 
11  private AsnEncodedData m_encodedParameters;
12 
13  private Oid m_oid;
14 
15  private uint m_aiPubKey;
16 
17  private byte[] m_cspBlobData;
18 
19  private AsymmetricAlgorithm m_key;
20 
21  internal uint AlgorithmId
22  {
23  get
24  {
25  if (m_aiPubKey == 0)
26  {
27  m_aiPubKey = System.Security.Cryptography.X509Certificates.X509Utils.OidToAlgId(m_oid.Value);
28  }
29  return m_aiPubKey;
30  }
31  }
32 
33  private byte[] CspBlobData
34  {
35  get
36  {
37  if (m_cspBlobData == null)
38  {
39  DecodePublicKeyObject(AlgorithmId, m_encodedKeyValue.RawData, m_encodedParameters.RawData, out m_cspBlobData);
40  }
41  return m_cspBlobData;
42  }
43  }
44 
49  {
50  get
51  {
52  if (m_key == null)
53  {
54  switch (AlgorithmId)
55  {
56  case 9216u:
57  case 41984u:
58  {
59  RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
60  rSACryptoServiceProvider.ImportCspBlob(CspBlobData);
61  m_key = rSACryptoServiceProvider;
62  break;
63  }
64  case 8704u:
65  {
66  DSACryptoServiceProvider dSACryptoServiceProvider = new DSACryptoServiceProvider();
67  dSACryptoServiceProvider.ImportCspBlob(CspBlobData);
68  m_key = dSACryptoServiceProvider;
69  break;
70  }
71  default:
72  throw new NotSupportedException(SR.GetString("NotSupported_KeyAlgorithm"));
73  }
74  }
75  return m_key;
76  }
77  }
78 
81  public Oid Oid => new Oid(m_oid);
82 
85  public AsnEncodedData EncodedKeyValue => m_encodedKeyValue;
86 
89  public AsnEncodedData EncodedParameters => m_encodedParameters;
90 
91  private PublicKey()
92  {
93  }
94 
99  public PublicKey(Oid oid, AsnEncodedData parameters, AsnEncodedData keyValue)
100  {
101  m_oid = new Oid(oid);
102  m_encodedParameters = new AsnEncodedData(parameters);
103  m_encodedKeyValue = new AsnEncodedData(keyValue);
104  }
105 
106  internal PublicKey(PublicKey publicKey)
107  {
108  m_oid = new Oid(publicKey.m_oid);
109  m_encodedParameters = new AsnEncodedData(publicKey.m_encodedParameters);
110  m_encodedKeyValue = new AsnEncodedData(publicKey.m_encodedKeyValue);
111  }
112 
113  private static void DecodePublicKeyObject(uint aiPubKey, byte[] encodedKeyValue, byte[] encodedParameters, out byte[] decodedData)
114  {
115  decodedData = null;
116  IntPtr zero = IntPtr.Zero;
117  switch (aiPubKey)
118  {
119  case 8704u:
120  zero = new IntPtr(38L);
121  break;
122  case 9216u:
123  case 41984u:
124  zero = new IntPtr(19L);
125  break;
126  case 43521u:
127  case 43522u:
128  throw new NotSupportedException(SR.GetString("NotSupported_KeyAlgorithm"));
129  default:
130  throw new NotSupportedException(SR.GetString("NotSupported_KeyAlgorithm"));
131  }
132  SafeLocalAllocHandle decodedValue = null;
133  uint cbDecodedValue = 0u;
134  if (!CAPI.DecodeObject(zero, encodedKeyValue, out decodedValue, out cbDecodedValue))
135  {
136  throw new CryptographicException(Marshal.GetLastWin32Error());
137  }
138  if ((int)zero == 19)
139  {
140  decodedData = new byte[cbDecodedValue];
141  Marshal.Copy(decodedValue.DangerousGetHandle(), decodedData, 0, decodedData.Length);
142  }
143  else if ((int)zero == 38)
144  {
145  SafeLocalAllocHandle decodedValue2 = null;
146  uint cbDecodedValue2 = 0u;
147  if (!CAPI.DecodeObject(new IntPtr(39L), encodedParameters, out decodedValue2, out cbDecodedValue2))
148  {
149  throw new CryptographicException(Marshal.GetLastWin32Error());
150  }
151  decodedData = ConstructDSSPubKeyCspBlob(decodedValue, decodedValue2);
152  decodedValue2.Dispose();
153  }
154  decodedValue.Dispose();
155  }
156 
157  private static byte[] ConstructDSSPubKeyCspBlob(SafeLocalAllocHandle decodedKeyValue, SafeLocalAllocHandle decodedParameters)
158  {
159  CAPIBase.CRYPTOAPI_BLOB cRYPTOAPI_BLOB = (CAPIBase.CRYPTOAPI_BLOB)Marshal.PtrToStructure(decodedKeyValue.DangerousGetHandle(), typeof(CAPIBase.CRYPTOAPI_BLOB));
160  CAPIBase.CERT_DSS_PARAMETERS cERT_DSS_PARAMETERS = (CAPIBase.CERT_DSS_PARAMETERS)Marshal.PtrToStructure(decodedParameters.DangerousGetHandle(), typeof(CAPIBase.CERT_DSS_PARAMETERS));
161  uint cbData = cERT_DSS_PARAMETERS.p.cbData;
162  if (cbData == 0)
163  {
164  throw new CryptographicException(-2146893803);
165  }
166  uint capacity = 16 + cbData + 20 + cbData + cbData + 24;
167  MemoryStream memoryStream = new MemoryStream((int)capacity);
168  BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
169  binaryWriter.Write((byte)6);
170  binaryWriter.Write((byte)2);
171  binaryWriter.Write((short)0);
172  binaryWriter.Write(8704u);
173  binaryWriter.Write(827544388u);
174  binaryWriter.Write(cbData * 8);
175  byte[] array = new byte[cERT_DSS_PARAMETERS.p.cbData];
176  Marshal.Copy(cERT_DSS_PARAMETERS.p.pbData, array, 0, array.Length);
177  binaryWriter.Write(array);
178  uint cbData2 = cERT_DSS_PARAMETERS.q.cbData;
179  if (cbData2 == 0 || cbData2 > 20)
180  {
181  throw new CryptographicException(-2146893803);
182  }
183  byte[] array2 = new byte[cERT_DSS_PARAMETERS.q.cbData];
184  Marshal.Copy(cERT_DSS_PARAMETERS.q.pbData, array2, 0, array2.Length);
185  binaryWriter.Write(array2);
186  if (20 > cbData2)
187  {
188  binaryWriter.Write(new byte[20 - cbData2]);
189  }
190  cbData2 = cERT_DSS_PARAMETERS.g.cbData;
191  if (cbData2 == 0 || cbData2 > cbData)
192  {
193  throw new CryptographicException(-2146893803);
194  }
195  byte[] array3 = new byte[cERT_DSS_PARAMETERS.g.cbData];
196  Marshal.Copy(cERT_DSS_PARAMETERS.g.pbData, array3, 0, array3.Length);
197  binaryWriter.Write(array3);
198  if (cbData > cbData2)
199  {
200  binaryWriter.Write(new byte[cbData - cbData2]);
201  }
202  cbData2 = cRYPTOAPI_BLOB.cbData;
203  if (cbData2 == 0 || cbData2 > cbData)
204  {
205  throw new CryptographicException(-2146893803);
206  }
207  byte[] array4 = new byte[cRYPTOAPI_BLOB.cbData];
208  Marshal.Copy(cRYPTOAPI_BLOB.pbData, array4, 0, array4.Length);
209  binaryWriter.Write(array4);
210  if (cbData > cbData2)
211  {
212  binaryWriter.Write(new byte[cbData - cbData2]);
213  }
214  binaryWriter.Write(uint.MaxValue);
215  binaryWriter.Write(new byte[20]);
216  return memoryStream.ToArray();
217  }
218  }
219 }
Performs asymmetric encryption and decryption using the implementation of the T:System....
Represents Abstract Syntax Notation One (ASN.1)-encoded data.
void ImportCspBlob(byte[] keyBlob)
Imports a blob that represents RSA key information.
Represents a cryptographic object identifier. This class cannot be inherited.
Definition: Oid.cs:6
AsnEncodedData EncodedParameters
Gets the ASN.1-encoded representation of the public key parameters.
Definition: PublicKey.cs:89
Definition: __Canon.cs:3
string Value
Gets or sets the dotted number of the identifier.
Definition: Oid.cs:17
Represents a certificate's public key information. This class cannot be inherited.
Definition: PublicKey.cs:7
Oid Oid
Gets an object identifier (OID) object of the public key.
Definition: PublicKey.cs:81
static void Copy(int[] source, int startIndex, IntPtr destination, int length)
Copies data from a one-dimensional, managed 32-bit signed integer array to an unmanaged memory pointe...
Definition: Marshal.cs:301
Creates a stream whose backing store is memory.To browse the .NET Framework source code for this type...
Definition: MemoryStream.cs:13
virtual byte [] ToArray()
Writes the stream contents to a byte array, regardless of the P:System.IO.MemoryStream....
byte [] RawData
Gets or sets the Abstract Syntax Notation One (ASN.1)-encoded data represented in a byte array.
A platform-specific type that is used to represent a pointer or a handle.
Definition: IntPtr.cs:14
Represents the abstract base class from which all implementations of asymmetric algorithms must inher...
Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks,...
Definition: Marshal.cs:15
virtual void Write(bool value)
Writes a one-byte Boolean value to the current stream, with 0 representing false and 1 representing t...
void ImportCspBlob(byte[] keyBlob)
Imports a blob that represents DSA key information.
Defines a wrapper object to access the cryptographic service provider (CSP) implementation of the T:S...
static void PtrToStructure(IntPtr ptr, object structure)
Marshals data from an unmanaged block of memory to a managed object.
Definition: Marshal.cs:1198
PublicKey(Oid oid, AsnEncodedData parameters, AsnEncodedData keyValue)
Initializes a new instance of the T:System.Security.Cryptography.X509Certificates....
Definition: PublicKey.cs:99
static readonly IntPtr Zero
A read-only field that represents a pointer or handle that has been initialized to zero.
Definition: IntPtr.cs:20
AsymmetricAlgorithm Key
Gets an T:System.Security.Cryptography.RSACryptoServiceProvider or T:System.Security....
Definition: PublicKey.cs:49
AsnEncodedData EncodedKeyValue
Gets the ASN.1-encoded representation of the public key value.
Definition: PublicKey.cs:85
The exception that is thrown when an invoked method is not supported, or when there is an attempt to ...
static int GetLastWin32Error()
Returns the error code returned by the last unmanaged function that was called using platform invoke ...
Writes primitive types in binary to a stream and supports writing strings in a specific encoding.
Definition: BinaryWriter.cs:12