void OnRequest(IAsyncResult ar) { try { int length = stream.EndRead(ar); if (length == 0) { Trace.WriteLine("Client: Connexion close"); stream.Close(); client.Close(); return; } Trace.WriteLine("Client: Got a request"); byte[] frame = RawData.CopyBuffer(ar.AsyncState as byte[], 0, length); Trace.WriteLine(">" + BinConvert.ToHex(frame)); Recv(frame[0], RawData.CopyBuffer(frame, 1, 0)); } catch (Exception) { throw; } WaitForRequest(); }
protected void Recv(byte[] buffer) { Logger.Trace(">" + BinConvert.ToHex(buffer)); if (pendingRecvBuffer == null) { if (IsBufferComplete(buffer)) { /* Process this buffer */ Recv(buffer, out pendingRecvBuffer); } else { /* Store this buffer for later use */ pendingRecvBuffer = buffer; } } else { /* Append new buffer after the one we already have received */ byte[] newPendingRecvBuffer = new byte[pendingRecvBuffer.Length + buffer.Length]; Array.Copy(pendingRecvBuffer, 0, newPendingRecvBuffer, 0, pendingRecvBuffer.Length); Array.Copy(buffer, 0, newPendingRecvBuffer, pendingRecvBuffer.Length, buffer.Length); pendingRecvBuffer = newPendingRecvBuffer; if (IsBufferComplete(pendingRecvBuffer)) { /* Process this buffer */ Recv(pendingRecvBuffer, out pendingRecvBuffer); } } }
public virtual bool SetData(byte[] cardData) { if ((cardData == null) || (PageSize <= 0)) { return(false); } Logger.Trace("New data: " + BinConvert.ToHex(cardData)); int address = 0; for (int i = 0; i < cardData.Length; i += PageSize) { byte[] pageData = new byte[PageSize]; Array.Copy(cardData, i, pageData, 0, PageSize); Logger.Trace("Page " + address + ": new value is " + BinConvert.ToHex(pageData)); if (!SetData(address, pageData)) { return(false); } address++; } return(true); }
protected override bool Send(byte endpoint, byte[] buffer) { Logger.Trace("\t" + BinConvert.ToHex(endpoint) + " < " + BinConvert.ToHex(buffer)); byte[] t = new byte[3 + buffer.Length]; t[0] = 0xCD; t[1] = endpoint; for (int i = 0; i < buffer.Length; i++) { t[2 + i] = buffer[i]; } byte crc = 0; for (int i = 1; i < t.Length - 1; i++) { crc ^= t[i]; } t[t.Length - 1] = crc; Logger.Trace("<" + BinConvert.ToHex(t)); try { serialPort.Write(t, 0, t.Length); } catch (Exception) { return(false); } return(true); }
void serialDataReceived(object sender, SerialDataReceivedEventArgs e) { try { int bytesReceived = serialPort.BytesToRead; byte[] buffer = new byte[bytesReceived]; serialPort.Read(buffer, 0, bytesReceived); receiverMutex.WaitOne(); if (recvBuffer == null) { recvBuffer = buffer; } else { byte[] t = new byte[recvBuffer.Length + buffer.Length]; int i; for (i = 0; i < recvBuffer.Length; i++) { t[i] = recvBuffer[i]; } for (i = 0; i < buffer.Length; i++) { t[recvBuffer.Length + i] = buffer[i]; } recvBuffer = t; } Logger.Trace(">>>" + BinConvert.ToHex(recvBuffer)); receiverMutex.ReleaseMutex(); receiverEvent.Set(); } catch (Exception ex) { Logger.Trace(ex.Message); } }
/// <summary> /// Write a sector (excluding the trailer sector) /// </summary> /// <param name="sector"></param> /// <returns></returns> public bool WriteSector(Sector sector) { int firstBlockAddress = SectorFirstBlockAddress(sector.Number); int lastBlockAddress = SectorTrailerAddress(sector.Number) - 1; int startingAddress = 0; byte[] sectorData = sector.GetBytes(); byte[] key = null; Logger.Trace("Content to be written: " + BinConvert.ToHex(sectorData) + ", sector number: " + sector.Number); for (int address = firstBlockAddress; address <= lastBlockAddress; address++) { byte[] data = new byte[16]; Array.Copy(sectorData, startingAddress, data, 0, 16); startingAddress += 16; Logger.Trace("Written content: " + BinConvert.ToHex(data)); if (sector.isSetWritingKey()) { key = sector.WritingKey; } if (!MifareClassicWrite((ushort)address, data, key)) { return(false); } } return(true); }
void Test(string pubKeyStr) { byte[] publicKey = StrUtils.Base64Decode(pubKeyStr); Logger.Debug("Raw public key:" + BinConvert.ToHex(publicKey)); Asn1Tlv tlv = Asn1Tlv.Unserialize(publicKey); DumpTlv(tlv); }
void recvBulk(byte[] buffer) { Logger.Debug("RecvBulk " + BinConvert.ToHex(buffer)); CCID.RDR_to_PC_Block block = new CCID.RDR_to_PC_Block(buffer); Logger.Debug("Calling child's RDR_to_PC"); Children[block.Slot].RDR_to_PC(block); Logger.Debug("Done with child's RDR_to_PC"); }
protected void Recv(byte endpoint, byte[] buffer) { Logger.Trace("\t" + BinConvert.ToHex(endpoint) + " > " + BinConvert.ToHex(buffer)); switch (endpoint) { case CCID.EP_Control_To_PC: if (OnRawControlIn != null) { if (OnRawControlIn(buffer)) { break; } } recvControl(buffer); break; case CCID.EP_Bulk_RDR_To_PC: if (OnRawBulkIn != null) { if (OnRawBulkIn(buffer)) { break; } } if (ReadersReady) { recvBulk(buffer); } break; case CCID.EP_Interrupt: if (OnRawInterruptIn != null) { if (OnRawInterruptIn(buffer)) { break; } } if (ReadersReady) { recvInterrupt(buffer); } break; default: break; } if ((endpoint == CCID.EP_Bulk_RDR_To_PC) || (endpoint == CCID.EP_Control_To_PC)) { CommandSyncEvent.Set(); } }
static private void init(byte[] base_key) { byte bMSB; byte block_size = 0; byte rb_xor_value = 0; /*BYTE abSavedInitVktr[16]; * DWORD t, i;*/ int i = 0; /*KEY_ISO_AES*/ rb_xor_value = 0x87; block_size = 16; cmac_subkey_0 = AESEncrypt(base_key, init_vector, cmac_subkey_0); LogManager.DoLogOperation(string.Format("K0={0}", BinConvert.ToHex(cmac_subkey_0))); Array.Copy(cmac_subkey_0, 0, cmac_subkey_1, 0, cmac_subkey_0.Length); // If the MSBit of the generated cipher == 1 -> K1 = (cipher << 1) ^ Rb ... // store MSB: bMSB = cmac_subkey_1[0]; // Shift the complete cipher for 1 bit ==> K1: for (i = 0; i < (int)(block_size - 1); i++) { cmac_subkey_1[i] <<= 1; // add the carry over bit: cmac_subkey_1[i] |= (byte)(((cmac_subkey_1[i + 1] & 0x80) == 0x80 ? 0x01 : 0x00)); } cmac_subkey_1[block_size - 1] <<= 1; if ((bMSB & 0x80) == 0x80) { // XOR with Rb: cmac_subkey_1[block_size - 1] ^= rb_xor_value; } // store MSB: bMSB = cmac_subkey_1[0]; // Shift K1 ==> K2: for (i = 0; i < (int)(block_size - 1); i++) { cmac_subkey_2[i] = (byte)(cmac_subkey_1[i] << 1); cmac_subkey_2[i] |= (byte)(((cmac_subkey_1[i + 1] & 0x80) == 0x80 ? 0x01 : 0x00)); } cmac_subkey_2[block_size - 1] = (byte)(cmac_subkey_1[block_size - 1] << 1); if ((bMSB & 0x80) == 0x80) { // XOR with Rb: cmac_subkey_2[block_size - 1] ^= rb_xor_value; } }
protected override void UpdateState() { _reader_state = ReaderDevice.State(Slot); Logger.Debug("UpdateState:" + BinConvert.ToHex(_reader_state)); if ((_reader_state & SCARD.STATE_PRESENT) != 0) { _card_atr = new CardBuffer(ReaderDevice.GetAtr(Slot)); } else { _card_atr = null; } }
protected bool Send(byte endpoint, byte[] buffer, bool sync) { Logger.Trace("\t" + BinConvert.ToHex(endpoint) + " < " + BinConvert.ToHex(buffer)); byte[] t = new byte[1 + buffer.Length]; t[0] = endpoint; for (int i = 0; i < buffer.Length; i++) { t[1 + i] = buffer[i]; } if (!clientSocket.Connected) { return(false); } bool success = false; try { if (sync) { lock (sync_request) { CommandSyncEvent.Reset(); clientStream.Write(t, 0, t.Length); success = CommandSyncEvent.WaitOne(CommandTimeout); } } else { clientStream.Write(t, 0, t.Length); success = true; } } catch (Exception e) { Logger.Error("Error while sending to device: " + e.Message); success = false; } if (!success) { Logger.Error("Device error"); clientSocket.Close(); return(false); } return(true); }
private void eMerchant2Name_TextChanged(object sender, EventArgs e) { if (eMerchant2Name.Text == "") { merchant2Id = null; eMerchant2Id.Text = ""; AppConfig.WriteSettingString("MerchantName2", ""); return; } merchant2Id = AppleVasConfig.ComputeId(eMerchant2Name.Text); Logger.Trace("MerchantId#2={0}", BinConvert.ToHex(merchant2Id)); eMerchant2Id.Text = BinConvert.ToHex_nice(merchant2Id, ":", "", 0); AppConfig.WriteSettingString("MerchantName2", eMerchant2Name.Text); }
void recvInterrupt(byte[] buffer) { byte bRequest = buffer[0]; byte[] abData = RawData.CopyBuffer(buffer, 10); if (bRequest == CCID.RDR_TO_PC_NOTIFYSLOTCHANGE) { if (abData != null) { int slot = 0; Trace.WriteLine("Interrupt: " + BinConvert.ToHex(abData)); for (int i = 0; i < abData.Length; i++) { byte b = abData[i]; for (int j = 0; i < 4; j++) { if (slot > SlotCount) { break; } if ((b & 0x02) != 0) { /* Change on this slot */ if ((b & 0x01) != 0) { /* Card inserted */ Children[slot].NotifyInsert(); } else { /* Card removed */ Children[slot].NotifyRemove(); } } b /= 4; slot++; } } WorkerWakeupEvent.Set(); } } }
public bool Send(byte endpoint, byte[] buffer) { byte[] frame = new byte[1 + buffer.Length]; frame[0] = endpoint; Array.Copy(buffer, 0, frame, 1, buffer.Length); Trace.WriteLine("Client: Sending"); Trace.WriteLine("<" + BinConvert.ToHex(frame)); stream.Write(frame, 0, frame.Length); stream.Flush(); return(true); }
public void RDR_to_PC(CCID.RDR_to_PC_Block block) { LastResponse = block; Logger.Trace("RDR_to_PC>" + BinConvert.ToHex(block.Message) + " " + BinConvert.ToHex(block.Status) + " " + BinConvert.ToHex(block.Error) + " " + BinConvert.ToHex(block.Data)); SlotState localState; lock (slotLocker) { localState = slotState; } switch (block.Status & 0x03) { case 0: if ((localState == SlotState.CardPowerUpPending) && (block.Message == CCID.RDR_TO_PC_DATABLOCK)) { cardAtr = block.Data; Logger.Trace("Card ATR is " + BinConvert.ToHex(cardAtr)); localState = SlotState.CardPowered; } break; case 1: localState = SlotState.CardUnpowered; break; case 2: localState = SlotState.CardAbsent; break; default: break; } lock (slotLocker) { if (localState != slotState) { Logger.Trace("New state is " + localState.ToString()); slotState = localState; } } ExchangeDoneEvent.Set(); }
protected uint PC_to_RDR(byte slot, byte command, byte[] data = null) { byte[] buffer; if (data != null) { buffer = new byte[10 + data.Length]; } else { buffer = new byte[10]; } buffer[0] = command; buffer[1] = (byte)((buffer.Length - 10) % 256); buffer[2] = (byte)((buffer.Length - 10) / 256); buffer[5] = slot; buffer[6] = bSequence; if (bSequence < 255) { bSequence++; } else { bSequence = 0; } if (data != null) { for (int i = 0; i < data.Length; i++) { buffer[i + 10] = data[i]; } } Trace.WriteLine("PC_To_Rdr:" + BinConvert.ToHex(buffer)); if (Send(CCID.EP_Bulk_PC_To_RDR, buffer)) { return(SCARD.S_SUCCESS); } return(SCARD.E_COMM_DATA_LOST); }
/// <summary> /// Validate the form and content of a Key /// </summary> /// <param name="data"></param> /// <param name="nbBytes"></param> /// <returns></returns> public static bool isKeyValid(string data, int nbBytes = 6) { if (data.Length != (nbBytes * 2)) { return(false); } for (int i = 0; i < data.Length; i++) { if (!BinConvert.isByte(data[i])) { return(false); } } return(true); }
public virtual bool SetData(int address, byte[] data) { if ((data == null) || (address < 0) || (PageSize <= 0)) { return(false); } bool updated = false; if (!Pages.ContainsKey(address)) { updated = true; } else { byte[] old_data = Pages[address]; Logger.Trace("Page " + address + ": current value is " + BinConvert.ToHex(old_data)); if (old_data.Length != data.Length) { return(false); } for (int i = 0; i < old_data.Length; i++) { if (old_data[i] != data[i]) { updated = true; } } } if (updated) { Logger.Trace("New content for page " + address + ": " + BinConvert.ToHex(data)); Pages[address] = data; if (UpdatedAddresses == null) { UpdatedAddresses = new List <int>(); } UpdatedAddresses.Add(address); } return(true); }
public override bool Transmit() { byte[] buffer; _last_error = ReaderDevice.Transmit(Slot, _capdu.GetBytes(), out buffer); if (_last_error != SCARD.S_SUCCESS) { return(false); } Trace.WriteLine("Transmit>" + BinConvert.ToHex(buffer)); _rapdu = new RAPDU(buffer); Trace.WriteLine("Transmit>" + _rapdu.AsString()); return(true); }
private void TextToConfig(GoogleVasConfig config, TextBox control) { string name = control.Name; if (name.StartsWith("ehex")) { name = name.Substring(4); byte[] value; try { value = BinConvert.HexToBytes(control.Text); } catch { Logger.Trace("Invalid hex value for {0}", name); value = null; } try { config.SetFieldValue(name, value); } catch { Logger.Warning("Unknown config property: {0}", name); } } else if (name.StartsWith("estr")) { name = name.Substring(4); try { config.SetFieldValue(name, control.Text); } catch { Logger.Warning("Unknown config property: {0}", name); } } }
/// <summary> /// Write a sector's trailer /// </summary> /// <param name="sector"></param> /// <returns></returns> public bool WriteSectorTrailer(Sector sector) { if (sector == null) { return(false); } int blockAddress = SectorTrailerAddress(sector.Number); byte[] sectorTrailerData = sector.SectorTrailer; byte[] key = null; Logger.Trace("WriteSectorTrailer: " + BinConvert.ToHex(sectorTrailerData) + ", sector number: " + sector.Number); if (sector.isSetWritingKey()) { key = sector.WritingKey; } return(MifareClassicWrite((ushort)blockAddress, sectorTrailerData, key)); }
private void ConfigToText(GoogleVasConfig config, TextBox control) { string name = control.Name; if (name.StartsWith("ehex")) { name = name.Substring(4); try { byte[] value = (byte[])config.GetFieldValue(name); Logger.Debug("- {0}: {1}", name, BinConvert.ToHex(value)); control.Text = BinConvert.ToHex(value); control.Enabled = true; } catch { Logger.Warning("Unknown config property: {0}", name); control.Text = ""; control.Enabled = false; } } else if (name.StartsWith("estr")) { name = name.Substring(4); try { string value = (string)config.GetFieldValue(name); Logger.Debug("- {0}: {1}", name, value); control.Text = value; control.Enabled = true; } catch { Logger.Warning("Unknown config property: {0}", name); control.Text = ""; control.Enabled = false; } } }
private void ePrivateKey1_TextChanged(object sender, EventArgs e) { merchant1PrivateKey = null; ePublicKey1.Text = ""; if (ePrivateKey1.Text == "") { AppConfig.WriteSettingString("PrivateKey", ""); return; } string str = ePrivateKey1.Text; str = str.Replace(Environment.NewLine, ""); str = str.Trim(); if (str.Length == 0) { return; } try { merchant1PrivateKey = StrUtils.Base64Decode(str); } catch { return; } if (AppleVasConfig.ValidatePrivateKey(merchant1PrivateKey, out uint keyId, out byte[] publicKey)) { Logger.Trace("PrivateKey#1={0}", BinConvert.ToHex(merchant1PrivateKey)); Logger.Trace("KeyId#1={0}", BinConvert.ToHex(keyId)); Logger.Trace("PublicKey#1(raw)={0}", BinConvert.ToHex(publicKey)); byte[] publicKeyPem = AppleVasConfig.EncodePublicKeyPem(publicKey); Logger.Trace("PublicKey#1(pem)={0}", BinConvert.ToHex(publicKeyPem)); ePublicKey1.Text = StrUtils.Base64Encode(publicKeyPem); AppConfig.WriteSettingString("PrivateKey", ePrivateKey1.Text); }
public override bool Connect() { if (connexionState == ConnexionState.Connected) { return(true); } if (connexionState == ConnexionState.ConnectedDirect) { Disconnect(SCARD.LEAVE_CARD); } _last_error = ReaderDevice.ConnectTo(Slot); if (_last_error != SCARD.S_SUCCESS) { Logger.Trace("Connect failed: " + BinConvert.ToHex(_last_error)); return(false); } connexionState = ConnexionState.Connected; return(true); }
public string DamRequestAuthKey(string jsonFile) { LogManager.DoLogOperation("[DAM Server] Receive Request to get PICCDAMAuthKey"); DamRestCommand.JsonDamAuthKey test = DamRestCommand.LoadJson_DamAuthKey(jsonFile); LogManager.DoLogOperation("[SERVER] Retrieve Diversified key from " + BinConvert.ToHex(test.uid)); byte[] AesKeyDiversified = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* le propriétaire connait sa clef racine utilisée pour sa diversification de clef */ byte[] AesKeyRootDiversified = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 }; DueInfo.Diversification.Diversification_AES128(AesKeyRootDiversified, test.uid, test.uid.Length, ref AesKeyDiversified); LogManager.DoLogOperation("[SERVER] Diversified key is " + BinConvert.ToHex(AesKeyDiversified)); /* format json response */ JObject result = new JObject(); JProperty d = new JProperty("Result", "ok"); result.Add(d); JProperty a = new JProperty("uid", Converters.ByteArrayToSimpleHexString(test.uid)); result.Add(a); JProperty b = new JProperty("damauthkey", Converters.ByteArrayToSimpleHexString(AesKeyDiversified)); result.Add(b); /* le propriétaire connait le numéro de version de sa clef */ /*string version = "00"; * JProperty c = new JProperty("damauthkeyversion", version); * result.Add(c); */ return(JsonConvert.SerializeObject(result, Formatting.Indented)); }
/// <summary> /// Look for DUEINFO and delete it if exists /// </summary> /// <returns></returns> public bool Disable() { long rc = 0; byte KeyId = 0x00; LogManager.DoLogOperation("[DEBUG] Select Application"); rc = this.SelectApplication(0x000000); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'SelectApplication' {0} command failed - rc= {1:X}\t", 0x000000, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } byte aid_max_count = 30; uint[] aid_list = new uint[aid_max_count]; byte aid_count = 15; rc = this.GetApplicationIDs(aid_max_count, ref aid_list, ref aid_count); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetApplicationIDs' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] aid_count =" + aid_count)); for (int i = 0; i < aid_count; i++) { LogManager.DoLogOperation(string.Format("[DEBUG] AID{0} = {1:X}", i, aid_list[i])); if (aid_list[i] == m_Aid) { LogManager.DoLogOperation("[DEBUG] Authentificate"); rc = this.AuthenticateAes(KeyId, AesKeyMaster); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } byte[] uid = new byte[8]; LogManager.DoLogOperation("[DEBUG] Get UID"); rc = this.GetCardUID(out uid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetCardUID' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("UID " + BinConvert.ToHex(uid)); rc = this.DeleteApplication(m_Aid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[ERROR]DeleteApplication fails {0}", rc)); return(false); } else { LogManager.DoLogOperation("[DEBUG] DeleteApplication"); uint pdwFreeBytes = 0; this.GetFreeMemory(ref pdwFreeBytes); LogManager.DoLogOperation(string.Format("[DEBUG] Desfire FreeMem' {0}", pdwFreeBytes)); return(true); } } } LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Erase DUEINFO' AID not found")); return(false); }
public bool Check(byte[] escn, byte[] sign, byte[] cert) { long rc = 0; /* select Desfire master application */ LogManager.DoLogOperation("[DEBUG] Select DUEINFO Application"); rc = this.SelectApplication(m_Aid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'SelectApplication' DUEINFO {0} command failed - rc= {1:X}\t", 0x000000, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } #region diversification /* Authentificate for diversification only */ LogManager.DoLogOperation("[DEBUG] Authentificate with ESCN Diversified key"); #if _SELP byte[] test = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; rc = this.AuthenticateAes(0x00, test); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' {0} command failed - rc= {1:X}", 0x00, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } // DueInfo.Diversification.Diversification_AES128(escn, AesKeyDueInfo, AesKeyDueInfo.Length, ref AesKeyDiversified); LogManager.DoLogOperation("SELP ESCN " + BinConvert.ToHex(escn)); LogManager.DoLogOperation("SELP RES " + BinConvert.ToHex(AesKeyDiversified)); #else DueInfo.Diversification.Diversification_AES128(AesKeyDueInfo, escn, escn.Length, ref AesKeyDiversified); #endif rc = this.AuthenticateAes(0x01, AesKeyDiversified); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' {0} command failed - rc= {1:X}", 0x00, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } #endregion /* retrieve DESFIRE UID */ byte[] uid = new byte[8]; LogManager.DoLogOperation("[DEBUG] Get UID"); rc = this.GetCardUID(out uid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetCardUID' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] UID " + BinConvert.ToHex(uid)); /* Authentificate for diversification only */ LogManager.DoLogOperation("[DEBUG] Authentificate with UID Diversified key"); #if _SELP DueInfo.Diversification.Diversification_AES128(uid, AesKeyDueInfo, AesKeyDueInfo.Length, ref AesKeyDiversified); #else DueInfo.Diversification.Diversification_AES128(AesKeyDueInfo, uid, uid.Length, ref AesKeyDiversified); #endif rc = this.AuthenticateAes(0x02, AesKeyDiversified); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' {0} command failed - rc= {1:X}", 0x00, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* create temporary files that will be use by openssl */ using (BinaryWriter writer = new BinaryWriter(File.Open("pem\\ca.dueinfo.cert.der", FileMode.Create))) { writer.Write(cert); writer.Close(); } using (BinaryWriter writer = new BinaryWriter(File.Open(escn_data, FileMode.Create))) { writer.Write(escn); writer.Write(uid); writer.Close(); } using (BinaryWriter writer = new BinaryWriter(File.Open(sign_file, FileMode.Create))) { writer.Write(sign); writer.Close(); } List <string> sign_args = new List <string>(); /* convert der certificate to pem */ LogManager.DoLogOperation("[DEBUG] OpenSsl convert certificate from der to pem"); sign_args.Add(cert_dueinfo_der_file); sign_args.Add(cert_pem_file); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actDerToPem) == false) { return(false); } sign_args.Clear(); /* extract public key from pem certificate */ LogManager.DoLogOperation("[DEBUG] Openssl extract public key from certificate"); sign_args.Add(cert_pem_file); sign_args.Add(pub_key_file); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actExtractPubKey) == false) { return(false); } sign_args.Clear(); /* extract public key from pem certificate */ LogManager.DoLogOperation("[DEBUG] Openssl verify signature with public key from certificate"); //sign_args.Add("test"); sign_args.Add(pub_key_file); sign_args.Add(sign_file); sign_args.Add(escn_data); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actSignVerify) == false) { return(false); } sign_args.Clear(); #if _0 /* convert der certificate to pem */ LogManager.DoLogOperation("[DEBUG] OpenSsl convert certificate from der to pem"); sign_args.Add(cert_der_file); sign_args.Add(cert_pem_file); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actDerToPem) == false) { return(false); } sign_args.Clear(); /* extract public key from pem certificate */ LogManager.DoLogOperation("[DEBUG] Openssl extract public key from certificate"); sign_args.Add(cert_pem_file); sign_args.Add(pub_key_file); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actExtractPubKey) == false) { return(false); } sign_args.Clear(); /* extract public key from pem certificate */ LogManager.DoLogOperation("[DEBUG] Openssl verify signature with public key from certificate"); sign_args.Add("test"); sign_args.Add(pub_key_file); sign_args.Add(sign_file); sign_args.Add(escn_data); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actSignVerify) == false) { return(false); } sign_args.Clear(); #endif return(true); }
/// <summary> /// Look for DUEINFO and delete it if exists /// </summary> /// <returns></returns> public bool Read(ref byte[] escn, ref byte[] sign, ref byte[] cert) { long rc = 0; byte file_id = 0x00; /* communication plain text for clear access */ byte comm_mode = 0x00; uint done = 0; byte[] local = new byte[1024]; /* select Desfire master application */ LogManager.DoLogOperation("[DEBUG] Select DUEINFO Application"); rc = this.SelectApplication(m_Aid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'SelectApplication' DUEINFO {0} command failed - rc= {1:X}\t", 0x000000, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* Read Standard files */ /* ESCN */ LogManager.DoLogOperation("[DEBUG] DUEINFO read ESCN"); rc = this.ReadData(file_id, comm_mode, 0, 0, ref local, ref done); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'ReadData' ECSN command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] DUEINFO read ESCN {0} OK ...", done)); escn = new byte[done]; Array.Copy(local, 0, escn, 0, done); LogManager.DoLogOperation(BinConvert.ToHex(escn)); /* SIGNATURE */ done = 0; file_id = 0x01; LogManager.DoLogOperation("[DEBUG] DUEINFO read SIGNATURE"); rc = this.ReadData(file_id, comm_mode, 0, 0, ref local, ref done); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'ReadData' SIGNATURE command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] DUEINFO read SIGNATURE {0} OK ...", done)); sign = new byte[done]; Array.Copy(local, 0, sign, 0, done); LogManager.DoLogOperation(BinConvert.ToHex(sign)); /* CERTIFICATE */ done = 0; file_id = 0x02; LogManager.DoLogOperation("[DEBUG] DUEINFO read CERTIFICATE"); rc = this.ReadData(file_id, comm_mode, 0, 0, ref local, ref done); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'ReadData' ECSN command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] DUEINFO read CERTIFICATE {0} OK ...", done)); cert = new byte[done]; Array.Copy(local, 0, cert, 0, done); LogManager.DoLogOperation(BinConvert.ToHex(cert)); LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'DUEINFO' read Ok ...")); return(true); }
/// <summary> /// Write DUEINFO application /// </summary> /// <returns></returns> public bool Create() { int i = 0; /*a0e4cacc - c5a8 - 441f - af57 - e7bd46d3b4ce*/ byte[] sign = null; byte[] cert = null; //string filename = "esdn.sha256"; string filename; long rc = 0; byte[] uid = new byte[8]; byte KeyId = 0x00; byte file_id = 0x00; /* communication plain text for clear access */ byte comm_mode = 0x00; /* read access clear 'E' */ /* write access '0' master key only */ /* read/write access clear '0' */ /* change acces rights '0' master key only */ UInt16 access_rights = 0xE000; byte aid_max_count = 30; uint[] aid_list = new uint[aid_max_count]; byte aid_count = 15; List <string> sign_args = new List <string>(); sign_args.Add("version"); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actVersion) == false) { return(false); } sign_args.Clear(); filename = cert_der_file; if (File.Exists(filename)) { using (FileStream sourceFile = new FileStream(filename, FileMode.Open)) { using (BinaryReader reader = new BinaryReader(sourceFile)) { cert = new byte[sourceFile.Length]; cert = reader.ReadBytes(cert.Length); reader.Close(); } sourceFile.Close(); } } if (cert == null) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire Fails to read certificate {0}", filename)); return(false); } /* select Desfire master application */ LogManager.DoLogOperation("[DEBUG] Select Application"); rc = this.SelectApplication(0x000000); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'SelectApplication' {0} command failed - rc= {1:X}\t", 0x000000, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* List Desfire AID */ rc = this.GetApplicationIDs(aid_max_count, ref aid_list, ref aid_count); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetApplicationIDs' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] aid_count =" + aid_count)); for (i = 0; i < aid_count; i++) { LogManager.DoLogOperation(string.Format("[DEBUG] AID{0} = {1:X}", i, aid_list[i])); if (aid_list[i] == m_Aid) { LogManager.DoLogOperation("[DEBUG] DUEINFO already exists !!!"); return(false); } } /* Authentificate */ LogManager.DoLogOperation("[DEBUG] Authentificate with master key"); rc = this.AuthenticateAes(KeyId, AesKeyMaster); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* retrieve DESFIRE UID */ LogManager.DoLogOperation("[DEBUG] Get UID"); rc = this.GetCardUID(out uid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetCardUID' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] UID " + BinConvert.ToHex(uid)); using (BinaryWriter writer = new BinaryWriter(File.Open(escn_data, FileMode.Create))) { writer.Write(Escn); writer.Write(uid); writer.Close(); } /* create signature from ESCN|UID */ LogManager.DoLogOperation("[DEBUG] Openssl create escn signature with university private key"); sign_args.Add("test"); sign_args.Add(priv_key_file); sign_args.Add(sign_file); sign_args.Add(escn_data); if (call_openssl(sign_args, Console_OpenSsl.ActionOpenSsl.actSign) == false) { return(false); } sign_args.Clear(); if (File.Exists(sign_file)) { using (FileStream sourceFile = new FileStream(sign_file, FileMode.Open)) { if (sourceFile.Length == 0) { sourceFile.Close(); LogManager.DoLogOperation(string.Format("[DEBUG] Signature file is empty {0}", sign_file)); return(false); } using (BinaryReader reader = new BinaryReader(sourceFile)) { sign = new byte[sourceFile.Length]; sign = reader.ReadBytes(sign.Length); reader.Close(); } sourceFile.Close(); } } if (sign == null) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire Fails to read signature {0}", filename)); return(false); } /* set configuration */ byte[] setting = new byte[2]; /* enable random ID */ //setting[0] = 0x02; rc = this.SetConfiguration(0x00, setting, 1); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[ERROR]SetConfiguration fails {0}", rc)); return(false); } /* read rest of memory */ LogManager.DoLogOperation("[DEBUG] GetFreeMemory"); uint pdwFreeBytes = 0; if (rc != SCARD.S_SUCCESS) { this.GetFreeMemory(ref pdwFreeBytes); LogManager.DoLogOperation(string.Format("[DEBUG] Desfire FreeMem' {0}", pdwFreeBytes)); return(true); } /*create application */ /* 0x0A -> configuration changeable, free directory list access without master key */ /* 0xA7 -> AES operation, ISO enbaled, 14 keys can be stored */ //rc = this.CreateApplication(m_Aid, 0x0A, 0x87); UInt16 iso_df_id = 0x1000; byte[] iso_df_name = new byte[] { 0xA0, 0x00, 0x00, 0x06, 0x14, 0x04, 0xF5, 0x88, 0x40 }; rc = this.CreateIsoApplication(m_Aid, 0x0A, 0xA7, iso_df_id, iso_df_name, (byte)iso_df_name.Length); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[ERROR]CreateApplication fails {0}", rc)); return(false); } rc = this.GetApplicationIDs(aid_max_count, ref aid_list, ref aid_count); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'GetApplicationIDs' command failed - rc= {0:X}", (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation(string.Format("[DEBUG] aid_count =" + aid_count)); for (i = 0; i < aid_count; i++) { LogManager.DoLogOperation(string.Format("[DEBUG] [DEBUG] AID{0} = {1:X}", i, aid_list[i])); if (aid_list[i] == m_Aid) { break; } } if (aid_count == i) { LogManager.DoLogOperation("[DEBUG] DUEINFO not found after creation !!!"); return(false); } /* select Desfire master application */ LogManager.DoLogOperation("[DEBUG] Select DUEINFO Application"); rc = this.SelectApplication(m_Aid); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'SelectApplication' DUEINFO {0} command failed - rc= {1:X}\t", 0x000000, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] Authentificate DUEINFO with master key"); rc = this.AuthenticateAes(KeyId, AesKeyMaster); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'Authenticate' DUEINFO {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* Create ESCN Standards files */ LogManager.DoLogOperation("[DEBUG] DUEINFO create Standard file for ESCN"); //rc = this.CreateStdDataFile(file_id, comm_mode, access_rights, (uint)Escn.Length);CreateIsoStdDataFile rc = this.CreateIsoStdDataFile(file_id, 0x1001, comm_mode, access_rights, (uint)Escn.Length); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'CreateStdDataFile' ECSN {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] DUEINFO write ESCN"); rc = this.WriteData(file_id, comm_mode, 0, (uint)Escn.Length, Escn); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'WriteData' ECSN {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* Create SIGNATURE Standard file */ file_id = 0x01; LogManager.DoLogOperation("[DEBUG] DUEINFO create Standard file for SIGNATURE"); rc = this.CreateIsoStdDataFile(file_id, 0x1002, comm_mode, access_rights, (uint)sign.Length); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'CreateStdDataFile' SIGNATURE {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] DUEINFO write SIGNATURE"); rc = this.WriteData(file_id, comm_mode, 0, (uint)sign.Length, sign); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'WriteData' SIGNATURE {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } /* Create DER Standard file */ file_id = 0x02; LogManager.DoLogOperation("[DEBUG] DUEINFO create Standard file for CERTIFICATE"); //rc = this.CreateStdDataFile(file_id, comm_mode, access_rights, (uint)cert.Length); rc = this.CreateIsoStdDataFile(file_id, 0x1003, comm_mode, access_rights, (uint)cert.Length); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'CreateStdDataFile' CERTIFICATE {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] DUEINFO write CERTIFICATE"); rc = this.WriteData(file_id, comm_mode, 0, (uint)cert.Length, cert); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'WriteData' CERTIFICATE {0} command failed - rc= {1:X}", KeyId, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } #region diversified LogManager.DoLogOperation("[DEBUG] DUEINFO set ESCN diversified key"); /* key 01 is diversified with escn */ DueInfo.Diversification.Diversification_AES128(AesKeyDueInfo, Escn, Escn.Length, ref AesKeyDiversified); /* we set à diversified key even if random UID is not enabled */ rc = this.ChangeKeyAes(0x01, 0x01, AesKeyDiversified, TransportKey); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'ChangeKeyAes' {0} command failed - rc= {1:X}", 0x01, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } LogManager.DoLogOperation("[DEBUG] DUEINFO set UID diversified key"); /* key 02 is diversified with uid */ DueInfo.Diversification.Diversification_AES128(AesKeyDueInfo, uid, uid.Length, ref AesKeyDiversified); /* we set à diversified key even if random UID is not enabled */ rc = this.ChangeKeyAes(0x02, 0x01, AesKeyDiversified, TransportKey); if (rc != SCARD.S_SUCCESS) { LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'ChangeKeyAes' {0} command failed - rc= {1:X}", 0x01, (0xFFFF - (0xFFFF + rc + 1000)))); return(false); } #endregion LogManager.DoLogOperation(string.Format("[DEBUG] Desfire 'DUEINFO' AID creation Ok ...")); return(false); }