using System; using System.Collections; using System.Security.Cryptography; namespace Mono.Security.Cryptography { // Token: 0x020000A9 RID: 169 internal sealed class PKCS8 { // Token: 0x06000949 RID: 2377 RVA: 0x00025360 File Offset: 0x00023560 private PKCS8() { } // Token: 0x0600094A RID: 2378 RVA: 0x00025368 File Offset: 0x00023568 public static PKCS8.KeyInfo GetType(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } PKCS8.KeyInfo keyInfo = PKCS8.KeyInfo.Unknown; try { ASN1 asn = new ASN1(data); if (asn.Tag == 48 && asn.Count > 0) { ASN1 asn2 = asn[0]; byte tag = asn2.Tag; if (tag != 2) { if (tag == 48) { keyInfo = PKCS8.KeyInfo.EncryptedPrivateKey; } } else { keyInfo = PKCS8.KeyInfo.PrivateKey; } } } catch { throw new CryptographicException("invalid ASN.1 data"); } return keyInfo; } // Token: 0x020000AA RID: 170 public enum KeyInfo { // Token: 0x04000205 RID: 517 PrivateKey, // Token: 0x04000206 RID: 518 EncryptedPrivateKey, // Token: 0x04000207 RID: 519 Unknown } // Token: 0x020000AB RID: 171 public class PrivateKeyInfo { // Token: 0x0600094B RID: 2379 RVA: 0x0002540C File Offset: 0x0002360C public PrivateKeyInfo() { this._version = 0; this._list = new ArrayList(); } // Token: 0x0600094C RID: 2380 RVA: 0x00025428 File Offset: 0x00023628 public PrivateKeyInfo(byte[] data) : this() { this.Decode(data); } // Token: 0x17000103 RID: 259 // (get) Token: 0x0600094D RID: 2381 RVA: 0x00025438 File Offset: 0x00023638 // (set) Token: 0x0600094E RID: 2382 RVA: 0x00025440 File Offset: 0x00023640 public string Algorithm { get { return this._algorithm; } set { this._algorithm = value; } } // Token: 0x17000104 RID: 260 // (get) Token: 0x0600094F RID: 2383 RVA: 0x0002544C File Offset: 0x0002364C public ArrayList Attributes { get { return this._list; } } // Token: 0x17000105 RID: 261 // (get) Token: 0x06000950 RID: 2384 RVA: 0x00025454 File Offset: 0x00023654 // (set) Token: 0x06000951 RID: 2385 RVA: 0x00025474 File Offset: 0x00023674 public byte[] PrivateKey { get { if (this._key == null) { return null; } return (byte[])this._key.Clone(); } set { if (value == null) { throw new ArgumentNullException("PrivateKey"); } this._key = (byte[])value.Clone(); } } // Token: 0x17000106 RID: 262 // (get) Token: 0x06000952 RID: 2386 RVA: 0x000254A4 File Offset: 0x000236A4 // (set) Token: 0x06000953 RID: 2387 RVA: 0x000254AC File Offset: 0x000236AC public int Version { get { return this._version; } set { if (value < 0) { throw new ArgumentOutOfRangeException("negative version"); } this._version = value; } } // Token: 0x06000954 RID: 2388 RVA: 0x000254C8 File Offset: 0x000236C8 private void Decode(byte[] data) { ASN1 asn = new ASN1(data); if (asn.Tag != 48) { throw new CryptographicException("invalid PrivateKeyInfo"); } ASN1 asn2 = asn[0]; if (asn2.Tag != 2) { throw new CryptographicException("invalid version"); } this._version = (int)asn2.Value[0]; ASN1 asn3 = asn[1]; if (asn3.Tag != 48) { throw new CryptographicException("invalid algorithm"); } ASN1 asn4 = asn3[0]; if (asn4.Tag != 6) { throw new CryptographicException("missing algorithm OID"); } this._algorithm = ASN1Convert.ToOid(asn4); ASN1 asn5 = asn[2]; this._key = asn5.Value; if (asn.Count > 3) { ASN1 asn6 = asn[3]; for (int i = 0; i < asn6.Count; i++) { this._list.Add(asn6[i]); } } } // Token: 0x06000955 RID: 2389 RVA: 0x000255C8 File Offset: 0x000237C8 public byte[] GetBytes() { ASN1 asn = new ASN1(48); asn.Add(ASN1Convert.FromOid(this._algorithm)); asn.Add(new ASN1(5)); ASN1 asn2 = new ASN1(48); asn2.Add(new ASN1(2, new byte[] { (byte)this._version })); asn2.Add(asn); asn2.Add(new ASN1(4, this._key)); if (this._list.Count > 0) { ASN1 asn3 = new ASN1(160); foreach (object obj in this._list) { ASN1 asn4 = (ASN1)obj; asn3.Add(asn4); } asn2.Add(asn3); } return asn2.GetBytes(); } // Token: 0x06000956 RID: 2390 RVA: 0x000256D0 File Offset: 0x000238D0 private static byte[] RemoveLeadingZero(byte[] bigInt) { int num = 0; int num2 = bigInt.Length; if (bigInt[0] == 0) { num = 1; num2--; } byte[] array = new byte[num2]; Buffer.BlockCopy(bigInt, num, array, 0, num2); return array; } // Token: 0x06000957 RID: 2391 RVA: 0x00025704 File Offset: 0x00023904 private static byte[] Normalize(byte[] bigInt, int length) { if (bigInt.Length == length) { return bigInt; } if (bigInt.Length > length) { return PKCS8.PrivateKeyInfo.RemoveLeadingZero(bigInt); } byte[] array = new byte[length]; Buffer.BlockCopy(bigInt, 0, array, length - bigInt.Length, bigInt.Length); return array; } // Token: 0x06000958 RID: 2392 RVA: 0x00025744 File Offset: 0x00023944 public static RSA DecodeRSA(byte[] keypair) { ASN1 asn = new ASN1(keypair); if (asn.Tag != 48) { throw new CryptographicException("invalid private key format"); } ASN1 asn2 = asn[0]; if (asn2.Tag != 2) { throw new CryptographicException("missing version"); } if (asn.Count < 9) { throw new CryptographicException("not enough key parameters"); } RSAParameters rsaparameters = default(RSAParameters); rsaparameters.Modulus = PKCS8.PrivateKeyInfo.RemoveLeadingZero(asn[1].Value); int num = rsaparameters.Modulus.Length; int num2 = num >> 1; rsaparameters.D = PKCS8.PrivateKeyInfo.Normalize(asn[3].Value, num); rsaparameters.DP = PKCS8.PrivateKeyInfo.Normalize(asn[6].Value, num2); rsaparameters.DQ = PKCS8.PrivateKeyInfo.Normalize(asn[7].Value, num2); rsaparameters.Exponent = PKCS8.PrivateKeyInfo.RemoveLeadingZero(asn[2].Value); rsaparameters.InverseQ = PKCS8.PrivateKeyInfo.Normalize(asn[8].Value, num2); rsaparameters.P = PKCS8.PrivateKeyInfo.Normalize(asn[4].Value, num2); rsaparameters.Q = PKCS8.PrivateKeyInfo.Normalize(asn[5].Value, num2); RSA rsa = null; try { rsa = RSA.Create(); rsa.ImportParameters(rsaparameters); } catch (CryptographicException) { rsa = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); rsa.ImportParameters(rsaparameters); } return rsa; } // Token: 0x06000959 RID: 2393 RVA: 0x000258E4 File Offset: 0x00023AE4 public static byte[] Encode(RSA rsa) { RSAParameters rsaparameters = rsa.ExportParameters(true); ASN1 asn = new ASN1(48); asn.Add(new ASN1(2, new byte[1])); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.Modulus)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.Exponent)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.D)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.P)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.Q)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.DP)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.DQ)); asn.Add(ASN1Convert.FromUnsignedBigInteger(rsaparameters.InverseQ)); return asn.GetBytes(); } // Token: 0x0600095A RID: 2394 RVA: 0x000259B4 File Offset: 0x00023BB4 public static DSA DecodeDSA(byte[] privateKey, DSAParameters dsaParameters) { ASN1 asn = new ASN1(privateKey); if (asn.Tag != 2) { throw new CryptographicException("invalid private key format"); } dsaParameters.X = PKCS8.PrivateKeyInfo.Normalize(asn.Value, 20); DSA dsa = DSA.Create(); dsa.ImportParameters(dsaParameters); return dsa; } // Token: 0x0600095B RID: 2395 RVA: 0x00025A04 File Offset: 0x00023C04 public static byte[] Encode(DSA dsa) { return ASN1Convert.FromUnsignedBigInteger(dsa.ExportParameters(true).X).GetBytes(); } // Token: 0x0600095C RID: 2396 RVA: 0x00025A2C File Offset: 0x00023C2C public static byte[] Encode(AsymmetricAlgorithm aa) { if (aa is RSA) { return PKCS8.PrivateKeyInfo.Encode((RSA)aa); } if (aa is DSA) { return PKCS8.PrivateKeyInfo.Encode((DSA)aa); } throw new CryptographicException("Unknown asymmetric algorithm {0}", aa.ToString()); } // Token: 0x04000208 RID: 520 private int _version; // Token: 0x04000209 RID: 521 private string _algorithm; // Token: 0x0400020A RID: 522 private byte[] _key; // Token: 0x0400020B RID: 523 private ArrayList _list; } // Token: 0x020000AC RID: 172 public class EncryptedPrivateKeyInfo { // Token: 0x0600095D RID: 2397 RVA: 0x00025A78 File Offset: 0x00023C78 public EncryptedPrivateKeyInfo() { } // Token: 0x0600095E RID: 2398 RVA: 0x00025A80 File Offset: 0x00023C80 public EncryptedPrivateKeyInfo(byte[] data) : this() { this.Decode(data); } // Token: 0x17000107 RID: 263 // (get) Token: 0x0600095F RID: 2399 RVA: 0x00025A90 File Offset: 0x00023C90 // (set) Token: 0x06000960 RID: 2400 RVA: 0x00025A98 File Offset: 0x00023C98 public string Algorithm { get { return this._algorithm; } set { this._algorithm = value; } } // Token: 0x17000108 RID: 264 // (get) Token: 0x06000961 RID: 2401 RVA: 0x00025AA4 File Offset: 0x00023CA4 // (set) Token: 0x06000962 RID: 2402 RVA: 0x00025AC8 File Offset: 0x00023CC8 public byte[] EncryptedData { get { return (this._data != null) ? ((byte[])this._data.Clone()) : null; } set { this._data = ((value != null) ? ((byte[])value.Clone()) : null); } } // Token: 0x17000109 RID: 265 // (get) Token: 0x06000963 RID: 2403 RVA: 0x00025AE8 File Offset: 0x00023CE8 // (set) Token: 0x06000964 RID: 2404 RVA: 0x00025B30 File Offset: 0x00023D30 public byte[] Salt { get { if (this._salt == null) { RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create(); this._salt = new byte[8]; randomNumberGenerator.GetBytes(this._salt); } return (byte[])this._salt.Clone(); } set { this._salt = (byte[])value.Clone(); } } // Token: 0x1700010A RID: 266 // (get) Token: 0x06000965 RID: 2405 RVA: 0x00025B44 File Offset: 0x00023D44 // (set) Token: 0x06000966 RID: 2406 RVA: 0x00025B4C File Offset: 0x00023D4C public int IterationCount { get { return this._iterations; } set { if (value < 0) { throw new ArgumentOutOfRangeException("IterationCount", "Negative"); } this._iterations = value; } } // Token: 0x06000967 RID: 2407 RVA: 0x00025B6C File Offset: 0x00023D6C private void Decode(byte[] data) { ASN1 asn = new ASN1(data); if (asn.Tag != 48) { throw new CryptographicException("invalid EncryptedPrivateKeyInfo"); } ASN1 asn2 = asn[0]; if (asn2.Tag != 48) { throw new CryptographicException("invalid encryptionAlgorithm"); } ASN1 asn3 = asn2[0]; if (asn3.Tag != 6) { throw new CryptographicException("invalid algorithm"); } this._algorithm = ASN1Convert.ToOid(asn3); if (asn2.Count > 1) { ASN1 asn4 = asn2[1]; if (asn4.Tag != 48) { throw new CryptographicException("invalid parameters"); } ASN1 asn5 = asn4[0]; if (asn5.Tag != 4) { throw new CryptographicException("invalid salt"); } this._salt = asn5.Value; ASN1 asn6 = asn4[1]; if (asn6.Tag != 2) { throw new CryptographicException("invalid iterationCount"); } this._iterations = ASN1Convert.ToInt32(asn6); } ASN1 asn7 = asn[1]; if (asn7.Tag != 4) { throw new CryptographicException("invalid EncryptedData"); } this._data = asn7.Value; } // Token: 0x06000968 RID: 2408 RVA: 0x00025C9C File Offset: 0x00023E9C public byte[] GetBytes() { if (this._algorithm == null) { throw new CryptographicException("No algorithm OID specified"); } ASN1 asn = new ASN1(48); asn.Add(ASN1Convert.FromOid(this._algorithm)); if (this._iterations > 0 || this._salt != null) { ASN1 asn2 = new ASN1(4, this._salt); ASN1 asn3 = ASN1Convert.FromInt32(this._iterations); ASN1 asn4 = new ASN1(48); asn4.Add(asn2); asn4.Add(asn3); asn.Add(asn4); } ASN1 asn5 = new ASN1(4, this._data); ASN1 asn6 = new ASN1(48); asn6.Add(asn); asn6.Add(asn5); return asn6.GetBytes(); } // Token: 0x0400020C RID: 524 private string _algorithm; // Token: 0x0400020D RID: 525 private byte[] _salt; // Token: 0x0400020E RID: 526 private int _iterations; // Token: 0x0400020F RID: 527 private byte[] _data; } } }