| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- //
- // System.Reflection.StrongNameKeyPair.cs
- //
- // Authors:
- // Kevin Winchester ([email protected])
- // Sebastien Pouliot ([email protected])
- //
- // (C) 2002 Kevin Winchester
- // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
- //
- using System.IO;
- namespace System.Reflection {
- [Serializable]
- public class StrongNameKeyPair
- {
- private byte[] keyPair;
- private byte[] publicKey;
- private int bitLen;
- private bool keypairValid;
- public StrongNameKeyPair (byte[] keyPairArray)
- {
- if (keyPairArray == null)
- throw new ArgumentNullException ("keyPairArray");
- keypairValid = Validate (keyPairArray);
- }
-
- public StrongNameKeyPair (FileStream keyPairFile)
- {
- if (keyPairFile == null)
- throw new ArgumentNullException ("keyPairFile");
- byte[] input = new byte [keyPairFile.Length];
- keyPairFile.Read (input, 0, input.Length);
- keypairValid = Validate (input);
- }
-
- [MonoTODO("We do not, yet, support keypair persistance")]
- public StrongNameKeyPair (string keyPairContainer)
- {
- // named key container
- if (keyPairContainer == null)
- throw new ArgumentNullException ("keyPairContainer");
- // only RSA ? or both RSA and DSA ?
- throw new NotImplementedException ();
- }
- private bool Validate (byte[] keypair) {
- // Type - PRIVATEKEYBLOB (0x07)
- if (keypair[0] != 0x07)
- return false;
- // Version - Always CUR_BLOB_VERSION (0x02)
- if (keypair[1] != 0x02)
- return false;
- // RESERVED - Always 0
- if ((keypair[2] != 0x00) || (keypair[3] != 0x00))
- return false;
- // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
- if ((keypair[4] != 0x00) || (keypair[5] != 0x24) || (keypair[6] != 0x00) || (keypair[7] != 0x00))
- return false;
- // Magic - RSA2 (ASCII in hex)
- if ((keypair[8] != 0x52) || (keypair[9] != 0x53) || (keypair[10] != 0x41) || (keypair[11] != 0x32))
- return false;
- // bitlen - ex: 1024 - must be a multiple of 8
- bitLen = (keypair[15] << 24) + (keypair[14] << 16) + (keypair[13] << 8) + keypair[12];
- if (bitLen % 8 != 0)
- return false;
- // public exponent (DWORD)
- // modulus
- // private key
- keyPair = keypair;
- return true;
- }
- public byte[] PublicKey {
- get {
- if (!keypairValid)
- throw new ArgumentException ("invalid keypair");
- // first call (will be cached for all subsequent calls)
- if (publicKey == null) {
- publicKey = new byte [(bitLen >> 3) + 32];
- // The first 12 bytes are documented at:
- // http://msdn.microsoft.com/library/en-us/cprefadd/html/grfungethashfromfile.asp
- // ALG_ID - Signature
- publicKey[0] = keyPair[4];
- publicKey[1] = keyPair[5];
- publicKey[2] = keyPair[6];
- publicKey[3] = keyPair[7];
- // ALG_ID - Hash
- publicKey[4] = 0x04;
- publicKey[5] = 0x80;
- publicKey[6] = 0x00;
- publicKey[7] = 0x00;
- // Length of Public Key (in bytes)
- int lastPart = publicKey.Length - 12;
- publicKey[8] = (byte)(lastPart % 256);
- publicKey[9] = (byte)(lastPart / 256); // just in case
- publicKey[10] = 0x00;
- publicKey[11] = 0x00;
- // Ok from here - Same structure as keypair - expect for public key
- publicKey[12] = 0x06; // PUBLICKEYBLOB
- // we can copy this part
- Array.Copy (keyPair, 1, publicKey, 13, publicKey.Length - 13);
- // and make a small adjustment
- publicKey[23] = 0x31; // (RSA1 not RSA2)
- }
- return publicKey;
- }
- }
- }
- }
|