Esempio n. 1
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();
        }