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); }
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); }
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); }
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; } }
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(); }
public PACSAMKeyFile(PACSAMKeyFile copyObject) { copyObject.CopyTo(this); }