2 // System.Reflection.StrongNameKeyPair.cs
5 // Kevin Winchester (kwin@ns.sympatico.ca)
6 // Sebastien Pouliot (spouliot@motus.com)
8 // (C) 2002 Kevin Winchester
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
14 namespace System.Reflection {
17 public class StrongNameKeyPair
19 private byte[] keyPair;
20 private byte[] publicKey;
22 private bool keypairValid;
24 public StrongNameKeyPair (byte[] keyPairArray)
26 if (keyPairArray == null)
27 throw new ArgumentNullException ("keyPairArray");
28 keypairValid = Validate (keyPairArray);
31 public StrongNameKeyPair (FileStream keyPairFile)
33 if (keyPairFile == null)
34 throw new ArgumentNullException ("keyPairFile");
35 byte[] input = new byte [keyPairFile.Length];
36 keyPairFile.Read (input, 0, input.Length);
37 keypairValid = Validate (input);
40 [MonoTODO("We do not, yet, support keypair persistance")]
41 public StrongNameKeyPair (string keyPairContainer)
43 // named key container
44 if (keyPairContainer == null)
45 throw new ArgumentNullException ("keyPairContainer");
46 // only RSA ? or both RSA and DSA ?
47 throw new NotImplementedException ();
50 private bool Validate (byte[] keypair) {
51 // Type - PRIVATEKEYBLOB (0x07)
52 if (keypair[0] != 0x07)
54 // Version - Always CUR_BLOB_VERSION (0x02)
55 if (keypair[1] != 0x02)
57 // RESERVED - Always 0
58 if ((keypair[2] != 0x00) || (keypair[3] != 0x00))
60 // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
61 if ((keypair[4] != 0x00) || (keypair[5] != 0x24) || (keypair[6] != 0x00) || (keypair[7] != 0x00))
63 // Magic - RSA2 (ASCII in hex)
64 if ((keypair[8] != 0x52) || (keypair[9] != 0x53) || (keypair[10] != 0x41) || (keypair[11] != 0x32))
66 // bitlen - ex: 1024 - must be a multiple of 8
67 bitLen = (keypair[15] << 24) + (keypair[14] << 16) + (keypair[13] << 8) + keypair[12];
70 // public exponent (DWORD)
77 public byte[] PublicKey {
80 throw new ArgumentException ("invalid keypair");
81 // first call (will be cached for all subsequent calls)
82 if (publicKey == null) {
83 publicKey = new byte [(bitLen >> 3) + 32];
84 // The first 12 bytes are documented at:
85 // http://msdn.microsoft.com/library/en-us/cprefadd/html/grfungethashfromfile.asp
87 publicKey[0] = keyPair[4];
88 publicKey[1] = keyPair[5];
89 publicKey[2] = keyPair[6];
90 publicKey[3] = keyPair[7];
96 // Length of Public Key (in bytes)
97 int lastPart = publicKey.Length - 12;
98 publicKey[8] = (byte)(lastPart % 256);
99 publicKey[9] = (byte)(lastPart / 256); // just in case
100 publicKey[10] = 0x00;
101 publicKey[11] = 0x00;
102 // Ok from here - Same structure as keypair - expect for public key
103 publicKey[12] = 0x06; // PUBLICKEYBLOB
104 // we can copy this part
105 Array.Copy (keyPair, 1, publicKey, 13, publicKey.Length - 13);
106 // and make a small adjustment
107 publicKey[23] = 0x31; // (RSA1 not RSA2)