Пример #1
0
        public static PACSAMKeyFile Load(string path, bool ignoreHash = false)
        {
            PACSAMKeyFile instance = Serialiser <PACSAMKeyFile> .Load(path);

            // Verify the hashes
            if (!ignoreHash && !instance.VerifyHash())
            {
                throw new InvalidDataException("Hash verification failed.");
            }

            return(instance);
        }
Пример #2
0
        public override PACSAMKeyRecord Clone(bool includeKey = false)
        {
            PACSAMKeyFile instance = new PACSAMKeyFile();

            CopyTo(instance, includeKey);

            foreach (var record in Records)
            {
                instance.Records.Add(record.Clone(includeKey));
            }

            return(instance);
        }
Пример #3
0
        public static void Save(PACSAMKeyFile instance, string path, bool recomputeHashes = false)
        {
            // Recompute the hashes if required
            if (recomputeHashes)
            {
                instance.UpdateHash();
                foreach (PACSAMKeyRecord r in instance.Records)
                {
                    r.UpdateHash();
                }
            }

            Serialiser <PACSAMKeyFile> .Save(path, instance);
        }
Пример #4
0
        public override void ExportParts(params PACSAMKeyRecord[] parts)
        {
            // There must be at least 3 or more parts
            if (parts.Length < 3)
            {
                throw new ArgumentException(@"ExportParts: There must be at 3 or more parts to export to!");
            }

            // Create the resulting keyfile parts
            for (int i = 0; i < parts.Length; i++)
            {
                // Generate the part
                parts[i] = new PACSAMKeyFile(this);
            }

            // Export each key
            foreach (var record in Records)
            {
                PACSAMKeyRecord[] keyParts = new PACSAMKeyRecord[parts.Length];

                // Generate the key parts
                record.ExportParts(keyParts);
                for (int i = 0; i < parts.Length; i++)
                {
                    var pI = (parts[i] as PACSAMKeyFile);
                    pI.Records.Add(keyParts[i]);
                }
            }

            // Export the SystemIdentifier
            for (int i = 1; i < parts.Length; i++)
            {
                var pI = (parts[i] as PACSAMKeyFile);
                var p0 = (parts[0] as PACSAMKeyFile);

                pI.SystemDiversifier = Crypto.CreateRandomEntropy(SystemDiversifier.Length);
                p0.SystemDiversifier = Crypto.XorArray(p0.SystemDiversifier, pI.SystemDiversifier);
            }

            // Set the Part and PartCount values
            for (int i = 0; i < parts.Length; i++)
            {
                (parts[i] as PACSAMKeyFile).Part      = (i + 1);
                (parts[i] as PACSAMKeyFile).PartCount = parts.Length;
            }
        }
Пример #5
0
        public void Personalise(uint esn, string pin, PACSAMKeyFile keys)
        {
            /*
             * Input validation
             */

            // Validate the ESN
            if (esn == 0)
            {
                throw new ArgumentException("The ESN must not be zero");
            }

            // Validate the PIN
            if (String.IsNullOrEmpty(pin))
            {
                throw new ArgumentException("The PIN must not be empty");
            }

            // Trim the PIN
            pin = pin.Trim();

            // Validate the PIN (Numeric check)
            if (!pin.All(Char.IsDigit))
            {
                throw new ArgumentException("The PIN must be numeric");
            }

            // Validate the PIN length
            if (pin.Length != PinLength)
            {
                throw new ArgumentException($"The PIN must be {PinLength} digits in length exactly");
            }

            // Validate the key record file
            if (keys == null)
            {
                throw new ArgumentException("The key container is empty");
            }

            // Validate the key integrity
            foreach (PACSAMKeyRecord r in keys.Records)
            {
                if (!r.VerifyHash())
                {
                    throw new InvalidDataException(string.Format("The key record '{0}' failed it's hash check"));
                }
            }

            /*
             * Personalisation steps
             *
             * NOTE:
             * We don't check whether this PACSAM instance is actually in the correct state to personalise.
             * We just try it and if it fails it fails.
             */

            // Select the PACSAM Application
            try
            {
                SelectApplication();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to SelectApplication failed", ex);
            }

            // Validate the PACSAM is in the SELECTABLE state
            try
            {
                var status = GetStatus();
                if (status.AppletState != PACSAMAppletState.Selectable)
                {
                    throw new InvalidOperationException("This PACSAM instance is not in the SELECTABLE state");
                }
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to GetStatus failed", ex);
            }



            // Set the ESN
            try
            {
                SetData(SetDataElement.ESN, BinaryParser.ConvertUInt32(esn, ByteEndianess.BigEndian));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to SET DATA failed (esn)", ex);
            }

            // Set the PIN
            try
            {
                byte[] pinData = ASCIIEncoding.ASCII.GetBytes(pin);
                SetData(SetDataElement.PIN, pinData);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to SET DATA failed (PIN)", ex);
            }

            // Set the Profile Identifier
            try
            {
                SetData(SetDataElement.Profile, keys.IdBytes);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to SET DATA failed (Profile Identifier)", ex);
            }

            // Set the System Diversifier
            try
            {
                SetData(SetDataElement.SystemDiversifier, keys.SystemDiversifier);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The call to SET DATA failed (System Diversifier)", ex);
            }

            // Write the keys
            foreach (PACSAMKeyRecord r in keys.Records)
            {
                // TDEA2KEY
                if (typeof(PACSAMTDEA2KeyRecord).IsAssignableFrom(r.GetType()))
                {
                    LoadKey(PACSAMKeyType.DES, 0, r.PackRecord());
                }

                // AES128
                else if (typeof(PACSAMAES128KeyRecord).IsAssignableFrom(r.GetType()))
                {
                    LoadKey(PACSAMKeyType.AES, 0, r.PackRecord());
                }

                // PLAID
                else if (typeof(PACSAMPlaidKeyRecord).IsAssignableFrom(r.GetType()))
                {
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyPElement, r.PackRecord("IAKEY_P"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyQElement, r.PackRecord("IAKEY_Q"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyPQElement, r.PackRecord("IAKEY_PQ"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyDPElement, r.PackRecord("IAKEY_DP"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyDQElement, r.PackRecord("IAKEY_DQ"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyModulusElement, r.PackRecord("IAKEY_MODULUS"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.IAKeyExponentElement, r.PackRecord("IAKEY_EXPONENT"));
                    LoadKey(PACSAMKeyType.PLAID, PACSAMPlaidKeyRecord.FAKeyElement, r.PackRecord("FAKEY"));
                }
            }

            // Activate this PACSAM instance
            Activate();
        }
Пример #6
0
 public PACSAMKeyFile(PACSAMKeyFile copyObject)
 {
     copyObject.CopyTo(this);
 }