using System; using System.Collections; using System.Security.Cryptography; namespace Mono.Security.Cryptography { // Token: 0x02000031 RID: 49 public sealed class PKCS8 { // Token: 0x06000217 RID: 535 RVA: 0x0000D978 File Offset: 0x0000BB78 private PKCS8() { } // Token: 0x06000218 RID: 536 RVA: 0x0000D980 File Offset: 0x0000BB80 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: 0x02000032 RID: 50 public enum KeyInfo { // Token: 0x040000E5 RID: 229 PrivateKey, // Token: 0x040000E6 RID: 230 EncryptedPrivateKey, // Token: 0x040000E7 RID: 231 Unknown } // Token: 0x02000033 RID: 51 public class PrivateKeyInfo { // Token: 0x06000219 RID: 537 RVA: 0x0000DA24 File Offset: 0x0000BC24 public PrivateKeyInfo() { this._version = 0; this._list = new ArrayList(); } // Token: 0x0600021A RID: 538 RVA: 0x0000DA40 File Offset: 0x0000BC40 public PrivateKeyInfo(byte[] data) : this() { this.Decode(data); } // Token: 0x17000067 RID: 103 // (get) Token: 0x0600021B RID: 539 RVA: 0x0000DA50 File Offset: 0x0000BC50 // (set) Token: 0x0600021C RID: 540 RVA: 0x0000DA58 File Offset: 0x0000BC58 public string Algorithm { get { return this._algorithm; } set { this._algorithm = value; } } // Token: 0x17000068 RID: 104 // (get) Token: 0x0600021D RID: 541 RVA: 0x0000DA64 File Offset: 0x0000BC64 public ArrayList Attributes { get { return this._list; } } // Token: 0x17000069 RID: 105 // (get) Token: 0x0600021E RID: 542 RVA: 0x0000DA6C File Offset: 0x0000BC6C // (set) Token: 0x0600021F RID: 543 RVA: 0x0000DA8C File Offset: 0x0000BC8C 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: 0x1700006A RID: 106 // (get) Token: 0x06000220 RID: 544 RVA: 0x0000DABC File Offset: 0x0000BCBC // (set) Token: 0x06000221 RID: 545 RVA: 0x0000DAC4 File Offset: 0x0000BCC4 public int Version { get { return this._version; } set { if (value < 0) { throw new ArgumentOutOfRangeException("negative version"); } this._version = value; } } // Token: 0x06000222 RID: 546 RVA: 0x0000DAE0 File Offset: 0x0000BCE0 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: 0x06000223 RID: 547 RVA: 0x0000DBE0 File Offset: 0x0000BDE0 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: 0x06000224 RID: 548 RVA: 0x0000DCE8 File Offset: 0x0000BEE8 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: 0x06000225 RID: 549 RVA: 0x0000DD1C File Offset: 0x0000BF1C 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: 0x06000226 RID: 550 RVA: 0x0000DD5C File Offset: 0x0000BF5C 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: 0x06000227 RID: 551 RVA: 0x0000DEFC File Offset: 0x0000C0FC 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: 0x06000228 RID: 552 RVA: 0x0000DFCC File Offset: 0x0000C1CC 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: 0x06000229 RID: 553 RVA: 0x0000E01C File Offset: 0x0000C21C public static byte[] Encode(DSA dsa) { return ASN1Convert.FromUnsignedBigInteger(dsa.ExportParameters(true).X).GetBytes(); } // Token: 0x0600022A RID: 554 RVA: 0x0000E044 File Offset: 0x0000C244 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: 0x040000E8 RID: 232 private int _version; // Token: 0x040000E9 RID: 233 private string _algorithm; // Token: 0x040000EA RID: 234 private byte[] _key; // Token: 0x040000EB RID: 235 private ArrayList _list; } // Token: 0x02000034 RID: 52 public class EncryptedPrivateKeyInfo { // Token: 0x0600022B RID: 555 RVA: 0x0000E090 File Offset: 0x0000C290 public EncryptedPrivateKeyInfo() { } // Token: 0x0600022C RID: 556 RVA: 0x0000E098 File Offset: 0x0000C298 public EncryptedPrivateKeyInfo(byte[] data) : this() { this.Decode(data); } // Token: 0x1700006B RID: 107 // (get) Token: 0x0600022D RID: 557 RVA: 0x0000E0A8 File Offset: 0x0000C2A8 // (set) Token: 0x0600022E RID: 558 RVA: 0x0000E0B0 File Offset: 0x0000C2B0 public string Algorithm { get { return this._algorithm; } set { this._algorithm = value; } } // Token: 0x1700006C RID: 108 // (get) Token: 0x0600022F RID: 559 RVA: 0x0000E0BC File Offset: 0x0000C2BC // (set) Token: 0x06000230 RID: 560 RVA: 0x0000E0E0 File Offset: 0x0000C2E0 public byte[] EncryptedData { get { return (this._data != null) ? ((byte[])this._data.Clone()) : null; } set { this._data = ((value != null) ? ((byte[])value.Clone()) : null); } } // Token: 0x1700006D RID: 109 // (get) Token: 0x06000231 RID: 561 RVA: 0x0000E100 File Offset: 0x0000C300 // (set) Token: 0x06000232 RID: 562 RVA: 0x0000E148 File Offset: 0x0000C348 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: 0x1700006E RID: 110 // (get) Token: 0x06000233 RID: 563 RVA: 0x0000E15C File Offset: 0x0000C35C // (set) Token: 0x06000234 RID: 564 RVA: 0x0000E164 File Offset: 0x0000C364 public int IterationCount { get { return this._iterations; } set { if (value < 0) { throw new ArgumentOutOfRangeException("IterationCount", "Negative"); } this._iterations = value; } } // Token: 0x06000235 RID: 565 RVA: 0x0000E184 File Offset: 0x0000C384 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: 0x06000236 RID: 566 RVA: 0x0000E2B4 File Offset: 0x0000C4B4 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: 0x040000EC RID: 236 private string _algorithm; // Token: 0x040000ED RID: 237 private byte[] _salt; // Token: 0x040000EE RID: 238 private int _iterations; // Token: 0x040000EF RID: 239 private byte[] _data; } } }