public static Task <Dictionary <byte, string> > ReadIdentity(this SmartCardConnection connection) { using (var reader = new EIdReader(connection)) { return(ReadEIdIdentity(reader)); } }
/// <summary> /// class constructor. /// </summary> /// <param name="card"> /// smart card object /// </param> /// <param name="connection"> /// connection object to the smard card /// </param> public IccDetection(SmartCard card, SmartCardConnection connection) { smartCard = card; connectionObject = connection; PcscDeviceClass = DeviceClass.Unknown; PcscCardName = Pcsc.CardName.Unknown; }
public static async Task <byte[]> TransmitApduAsync(SmartCardConnection connection, byte[] ApduCommand) { IBuffer command = CryptographicBuffer.CreateFromByteArray(ApduCommand); IBuffer response = await connection.TransmitAsync(command); return(response.ToArray()); }
public void Dispose() { if (this.connection != null) { this.connection.Dispose(); } this.connection = null; }
/// <summary> /// Extension method to SmartCardConnection class similar to Transmit asyc method, however it accepts PCSC SDK /// commands. /// </summary> /// <param name="apduCommand"> /// APDU command object to send to the ICC /// </param> /// <param name="connection"> /// SmartCardConnection object /// </param> /// <returns>APDU response object of type defined by the APDU command object</returns> public static async Task <Iso7816.ApduResponse> TransceiveAsync(this SmartCardConnection connection, ApduCommand apduCommand) { var apduRes = (Iso7816.ApduResponse)Activator.CreateInstance(apduCommand.ApduResponseType); var responseBuf = await connection.TransmitAsync(apduCommand.GetBuffer().AsBuffer()); apduRes.ExtractResponse(responseBuf.ToArray()); return(apduRes); }
/// <summary> /// Extension method to SmartCardConnection class similar to Transmit asyc method, however it accepts PCSC SDK commands. /// </summary> /// <param name="apduCommand"> /// APDU command object to send to the ICC /// </param> /// <param name="connection"> /// SmartCardConnection object /// </param> /// <returns>APDU response object of type defined by the APDU command object</returns> public static async Task <Iso7816.ApduResponse> TransceiveAsyncOriginal(this SmartCardConnection connection, Iso7816.ApduCommand apduCommand) { Iso7816.ApduResponse apduRes = Activator.CreateInstance(apduCommand.ApduResponseType) as Iso7816.ApduResponse; IBuffer responseBuf = await connection.TransmitAsync(apduCommand.GetBuffer()); apduRes.ExtractResponse(responseBuf); return(apduRes); }
protected override void Dispose(bool disposing) { Debug.WriteLine("Dispose: " + nameof(MiFareWin32CardReader)); if (disposing) { connection?.Dispose(); connection = null; } base.Dispose(disposing); }
/// <summary> /// Reads the travel card data from HSL Mifare DESFire card. /// </summary> /// <param name="card">The card to try to read.</param> /// <returns>A deserialized Travel Card object if the card was valid, otherwise null.</returns> public static async Task <TravelCard> ReadTravelCardAsync(SmartCard card) { using (SmartCardConnection connection = await card.ConnectAsync()) { byte[] selection = (await connection.TransmitAsync(HslCommands.SelectHslCommand.AsBuffer())).ToArray(); if (selection != null && selection.Length > 0 && selection.SequenceEqual(HslCommands.OkResponse)) { // Travel card info bytes byte[] appInfo = null; byte[] periodPass = null; byte[] storedValue = null; byte[] eTicket = null; byte[] history = null; // Temporary containers for history chunks byte[] hist1 = new byte[2]; byte[] hist2 = new byte[2]; appInfo = (await connection.TransmitAsync(HslCommands.ReadAppInfoCommand.AsBuffer())).ToArray(); periodPass = (await connection.TransmitAsync(HslCommands.ReadPeriodPassCommand.AsBuffer())).ToArray(); storedValue = (await connection.TransmitAsync(HslCommands.ReadStoredValueCommand.AsBuffer())).ToArray(); eTicket = (await connection.TransmitAsync(HslCommands.ReadETicketCommand.AsBuffer())).ToArray(); hist1 = (await connection.TransmitAsync(HslCommands.ReadHistoryCommand.AsBuffer())).ToArray(); // If we have more history, the last two bytes of the history array will contain the MORE_DATA bytes. if (hist1.Skip(Math.Max(0, hist1.Length - 2)).ToArray() == HslCommands.MoreData) { hist2 = (await connection.TransmitAsync(HslCommands.ReadNextCommand.AsBuffer())).ToArray(); } // Combine the two history chunks into a single array, minus their last two MORE_DATA bytes history = hist1.Take(hist1.Length - 2) .Concat(hist2.Take(hist2.Length - 2)).ToArray(); var rawCard = new RawTravelCard(appInfo, periodPass, storedValue, eTicket, history); if (rawCard.Status == CardStatus.HslCardDataFailure) { return(null); } else { return(new TravelCard(rawCard)); } } else { return(null); } } }
private static async Task <byte[]> Get7ByteCardUID(CardAddedEventArgs args) { byte[] byteReadUID = new byte[] { (byte)0xFF, (byte)0xCA, (byte)0x00, (byte)0x00, (byte)0x00 }; SmartCardConnection cardConnection = await args.SmartCard.ConnectAsync(); IBuffer bufferResultUID = await cardConnection.TransmitAsync(byteReadUID.AsBuffer()); CryptographicBuffer.CopyToByteArray(bufferResultUID, out byte[] byteResultUID); return(byteResultUID); }
public static async Task <Iso7816.ApduResponse> TransceiveAsync(this SmartCardConnection connection, Iso7816.ApduCommand apduCommand) { Iso7816.ApduResponse apduRes = Activator.CreateInstance(apduCommand.ApduResponseType) as Iso7816.ApduResponse; IBuffer cmdBuffer = apduCommand.GetBuffer(); DeviceServerApp.Logger.Information("Transmitting <" + cmdBuffer.ToString() + ">"); IBuffer responseBuf = await connection.TransmitAsync(cmdBuffer); // <- throws exception (0x80004004 (E_ABORT)) apduRes.ExtractResponse(responseBuf); return(apduRes); } // TransceiveAsync
/// <summary> /// Extension method to SmartCardConnection class similar to Transmit asyc method, however it accepts PCSC SDK commands. /// </summary> /// <param name="apduCommand"> /// APDU command object to send to the ICC /// </param> /// <param name="connection"> /// SmartCardConnection object /// </param> /// <returns>APDU response object of type defined by the APDU command object</returns> internal static IAsyncOperation <Iso7816.ApduResponse> TransceiveAsync(this SmartCardConnection connection, Iso7816.ApduCommand apduCommand) { return(AsyncInfo.Run(async(cancel) => { Iso7816.ApduResponse apduRes = Activator.CreateInstance(apduCommand.ApduResponseType) as Iso7816.ApduResponse; IBuffer responseBuf = await connection.TransmitAsync(apduCommand.GetBuffer()); apduRes.ExtractResponse(responseBuf); return apduRes; })); }
protected virtual async void CardReader_CardAdded(SmartCardReader sender, CardAddedEventArgs args) { try { card = args.SmartCard; connection = await card.ConnectAsync(); //Tuple<CardName, DeviceClass> cardType = await DetectCardType(); OnCardPutInField(new EventArgs()); } catch (Exception ex) { LogMessage(ex.Message); } }
/// <summary> /// Extension method to SmartCardConnection class similar to Transmit asyc method, however it accepts PCSC SDK /// commands. /// </summary> /// <param name="apduCommand"> /// APDU command object to send to the ICC /// </param> /// <param name="connection"> /// SmartCardConnection object /// </param> /// <returns>APDU response object of type defined by the APDU command object</returns> public static async Task <Iso7816.ApduResponse> TransceiveAsync(this SmartCardConnection connection, ApduCommand apduCommand) { var apduRes = (Iso7816.ApduResponse)Activator.CreateInstance(apduCommand.ApduResponseType); if (!IsFirstConnection) { await Task.Delay(500); } var responseBuf = connection.Transceive(apduCommand.GetBuffer()); apduRes.ExtractResponse(responseBuf.ToArray()); return(apduRes); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private async void cardEV_Tap(SmartCardReader sender, CardAddedEventArgs args) { CardStatus = ScanningStatus.CardScanning; try { System.Diagnostics.Debug.WriteLine("Got card tap event."); // woooot using (SmartCardConnection connection = await args.SmartCard.ConnectAsync()) { // figure out what kind of card this is. IccDetection cardIdentification = new IccDetection(args.SmartCard, connection); await cardIdentification.DetectCardTypeAync(); System.Diagnostics.Debug.WriteLine("FOUND CARD"); System.Diagnostics.Debug.WriteLine(cardIdentification.PcscDeviceClass.ToString()); if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.MifareDesfire) { Pcsc.Desfire.AccessHandler desfireAccess = new Pcsc.Desfire.AccessHandler(connection); PhysicalCard.Desfire.DesfireCard _card = await ZaibatsuPass.PhysicalCard.Desfire.DesfireCard.SnapshotAsync(desfireAccess); var ignored = Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // try to parse the card tCard = _card; TransitCard.TransitCard parsedCard = TransitCard.TransitCardParser.parseTransitCard(tCard); if (parsedCard == null) { CardStatus = ScanningStatus.ScanningFailure; } else { (Window.Current.Content as Frame).Navigate(typeof(DetailsPage), parsedCard); } }); CardStatus = ScanningStatus.ScanningSuccess; } } } catch (Exception e) { System.Diagnostics.Debug.WriteLine(" ** OOPS: " + e.ToString()); CardStatus = ScanningStatus.ScanningFailure; } }
protected override void Dispose(bool disposing) { if (disposing) { try { connection?.Dispose(); } catch (Exception ex) { Debug.WriteLine(ex); } connection = null; } base.Dispose(disposing); }
private async Task ReadEdyAsync(SmartCardConnection connection) { EDYReader reader = new EDYReader(connection); // システムコードを指定してPolling await LogMessageAsync("EDYカードをポーリング: "); byte[] idm = await reader.Polling(); if (idm.Length > 0) { await LogMessageAsync(BitConverter.ToString(idm)); // ReadWithoutEncryptionでサービスコードを指定してデータ取得 // 属性情報 byte[] attributeData = await reader.GetAttribute(idm); await LogMessageAsync("属性情報: " + BitConverter.ToString(attributeData)); // 残額情報 byte[] balanceData = await reader.GetBalance(idm); await LogMessageAsync("残額情報: " + BitConverter.ToString(balanceData)); // 利用履歴 // 参考) http://iccard.jennychan.at-ninja.jp/format/edy.html#170F UsageHistory result = await reader.GetUsageHistory(idm); await LogMessageAsync("利用履歴: " + BitConverter.ToString(result.PacketData)); if (result.HasData) { await LogMessageAsync("■利用履歴の解析結果"); await LogMessageAsync("利用区分: 0x" + result.UsageType.ToString("X")); await LogMessageAsync("取引通番: " + result.RunningNumber); await LogMessageAsync("利用日時: " + result.UsedDateTime.ToString("yyyy/MM/dd HH:mm:ss")); await LogMessageAsync("利用金額: " + result.UsedAmount); await LogMessageAsync("残額: " + result.Balance); } } return; }
private async Task ReadSuicaAsync(SmartCardConnection connection) { byte[] result; SuicaReader reader = new SuicaReader(connection); // システムコードを指定してPolling await LogMessageAsync("Suicaカードをポーリング: "); byte[] idm = await reader.Polling(); if (idm.Length > 0) { await LogMessageAsync(BitConverter.ToString(idm)); // ReadWithoutEncryptionでサービスコードを指定してデータ取得 // TODO: 取得結果のクラス化 // 属性情報 result = await reader.GetAttributeInfo(idm); await LogMessageAsync("属性情報: " + BitConverter.ToString(result)); // 利用履歴 result = await reader.GetUsageHistory(idm); await LogMessageAsync("利用履歴: " + BitConverter.ToString(result)); // 改札入出場履歴 result = await reader.GetTicketGateEnterLeaveHistory(idm); await LogMessageAsync("改札入出場履歴: " + BitConverter.ToString(result)); // SF入場駅記録 result = await reader.GetSFEnteredStationInfo(idm); await LogMessageAsync("SF入場駅記録: " + BitConverter.ToString(result)); // 料金 発券/改札記録 result = await reader.GetTicketIssueInspectRecord(idm); await LogMessageAsync("料金 発券/改札記録: " + BitConverter.ToString(result)); } return; }
/// <summary> /// Click handler for the 'TransmitAPDU' button. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void Transmit_Click(object sender, RoutedEventArgs e) { if (!rootPage.ValidateTPMSmartCard()) { rootPage.NotifyUser("Use Scenario One to create a TPM virtual smart card.", NotifyType.ErrorMessage); return; } Button b = sender as Button; b.IsEnabled = false; try { SmartCard card = await rootPage.GetSmartCard(); IBuffer result = null; using (SmartCardConnection connection = await card.ConnectAsync()) { // Read EF.ATR file // The command is meant specifically for GIDS cards // (such as TPM VSCs), and will fail on other types. byte[] readEfAtrBytes = { 0x00, 0xCB, 0x2F, 0x01, 0x02, 0x5C, 0x00, 0xFF }; IBuffer readEfAtr = CryptographicBuffer.CreateFromByteArray(readEfAtrBytes); result = await connection.TransmitAsync(readEfAtr); rootPage.NotifyUser("Response: " + CryptographicBuffer.EncodeToHexString(result), NotifyType.StatusMessage); } } catch (Exception ex) { rootPage.NotifyUser("Transmitting APDU to card failed with exception: " + ex.ToString(), NotifyType.ErrorMessage); } finally { b.IsEnabled = true; } }
private async Task DoRead() { string selector = SmartCardReader.GetDeviceSelector(); DeviceInformationCollection smartCardReaders = await DeviceInformation.FindAllAsync(selector); var device = smartCardReaders.FirstOrDefault(); SmartCardReader reader = await SmartCardReader.FromIdAsync(device.Id); IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync(); var card = cards.FirstOrDefault(); if (card == null) { return; } (Dictionary <byte, string> address, Dictionary <byte, string> identity)? data = null; using (SmartCardConnection connection = await card.ConnectAsync()) { data = await connection.ReadEIdData(); } var identityData = data.Value.identity; var addressData = data.Value.address; var dateOfBirth = EIdDateHelper.GetDateTime(identityData[Tags.ID_BIRTH_DATE]); FullName.Text = $"{identityData[Tags.ID_FIRST_NAME]} {identityData[Tags.ID_LAST_NAME]}"; PlaceOfBirth.Text = identityData[Tags.ID_BIRTH_LOCATION]; DateOfBirth.Text = dateOfBirth.Value.ToString("dd/MM/yyyy"); Gender.Text = identityData[Tags.ID_SEX]; Nationality.Text = identityData[Tags.ID_NATIONALITY]; NationalNumber.Text = identityData[Tags.ID_NATIONAL_NUMBER]; Address.Text = $"{addressData[Tags.ADDRESS_STREET_NUMBER]} {addressData[Tags.ADDRESS_ZIP_CODE]} {addressData[Tags.ADDRESS_MUNICIPALITY]}"; }
} // TransceiveAsync /// <summary> /// Extension method to SmartCardConnection class to perform a transparent exchange to the ICC /// </summary> /// <param name="connection"> /// SmartCardConnection object /// </param> /// <param name="commandData"> /// Command object to send to the ICC /// </param> /// <returns>Response received from the ICC</returns> public static async Task <byte[]> TransparentExchangeAsync(this SmartCardConnection connection, byte[] commandData) { byte[] responseData = null; ManageSessionResponse apduRes = await TransceiveAsync(connection, new ManageSession(new byte[2] { (byte)ManageSession.DataObjectType.StartTransparentSession, 0x00 })) as ManageSessionResponse; if (!apduRes.Succeeded) { throw new Exception("Failure to start transparent session, " + apduRes.ToString()); } using (DataWriter dataWriter = new DataWriter()) { dataWriter.WriteByte((byte)TransparentExchange.DataObjectType.Transceive); dataWriter.WriteByte((byte)commandData.Length); dataWriter.WriteBytes(commandData); TransparentExchangeResponse apduRes1 = await TransceiveAsync(connection, new TransparentExchange(dataWriter.DetachBuffer().ToArray())) as TransparentExchangeResponse; if (!apduRes1.Succeeded) { throw new Exception("Failure transceive with card, " + apduRes1.ToString()); } responseData = apduRes1.IccResponse; } ManageSessionResponse apduRes2 = await TransceiveAsync(connection, new ManageSession(new byte[2] { (byte)ManageSession.DataObjectType.EndTransparentSession, 0x00 })) as ManageSessionResponse; if (!apduRes2.Succeeded) { throw new Exception("Failure to end transparent session, " + apduRes2.ToString()); } return(responseData); }
public async Task ConnectAsync(SmartCard smartcard) { _MifareSmartCard = smartcard; var newConnection = await smartcard.ConnectAsync(); lock (CardConnectionLock) { if (_MifareSmartCardConnection != null) { _MifareSmartCardConnection.Dispose(); } _MifareSmartCardConnection = newConnection; } mfStdAccess = new Mifare.AccessHandler(_MifareSmartCardConnection); IccDetection cardIdentification = new IccDetection(_MifareSmartCard, _MifareSmartCardConnection); await cardIdentification.DetectCardTypeAync(); CurrentCardName = cardIdentification.PcscCardName; if (!(CurrentCardName == CardName.MifareStandard1K || CurrentCardName == CardName.MifareStandard4K)) { throw new Mifare.Exceptions.CardTypeException("this Card is not mifare classic card"); } }
private async void cardReader_CardAdded(SmartCardReader sender, CardAddedEventArgs args) { SmartCard smartCard = args.SmartCard; try { await LogMessageAsync("カードを検知しました", true); using (SmartCardConnection connection = await smartCard.ConnectAsync()) { IccDetection cardIdentification = new IccDetection(smartCard, connection); await cardIdentification.DetectCardTypeAync(); await LogMessageAsync("PC/SCデバイスクラス: " + cardIdentification.PcscDeviceClass.ToString()); await LogMessageAsync("カード名: " + cardIdentification.PcscCardName.ToString()); if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass && cardIdentification.PcscCardName == CardName.FeliCa) { await LogMessageAsync("FelicaCardがみつかりました"); if (isEDYChecked) { await ReadEdyAsync(connection); } else { await ReadSuicaAsync(connection); } } } } catch (Exception ex) { await LogMessageAsync("例外が発生: " + ex.ToString()); } }
public UwpSmartCardConnection(SmartCardConnection backingConnection) { _backingConnection = backingConnection; }
/// <summary> /// Class constructor /// </summary> /// <param name="ScConnection"> /// connection object to a Mifare Standard ICC /// </param> public AccessHandler(SmartCardConnection ScConnection) { connectionObject = ScConnection; }
/// <summary> /// Class constructor /// </summary> /// <param name="ScConnection"> /// connection object to a Desfire ICC /// </param> public AccessHandler(SmartCardConnection ScConnection) { connectionObject = ScConnection; desfireCommand = new DesfireCommand(); }
public SuicaReader(SmartCardConnection connection) : base(connection) { }
public EDYReader(SmartCardConnection connection) : base(connection) { }
private async Task HandleCard(SmartCard card) { try { connection = await card.ConnectAsync(); IccDetection cardIdentification = new IccDetection(card, connection); await cardIdentification.DetectCardTypeAync(); LogMessage("Connected to card\r\nPC/SC device class: " + cardIdentification.PcscDeviceClass.ToString()); LogMessage("Card name: " + cardIdentification.PcscCardName.ToString()); LogMessage("ATR: " + BitConverter.ToString(cardIdentification.Atr)); if ((cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass) && (cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightC || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralight || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightEV1)) { MifareUltralight.AccessHandler mifareULAccess = new MifareUltralight.AccessHandler(connection); List<byte> dumpTmp = new List<byte>(); byte[] responseUid = await mifareULAccess.GetUidAsync(); dumpTmp.AddRange(new byte[] { 0x41, 0x6D, 0x69, 0x69, 0x67, 0x6F, 0x44, 0x75, 0x6D, 0x70, 0x00, 0x00, 0x00, 0x00 }); //MAGIC LogMessage("UID: " + BitConverter.ToString(responseUid)); dumpTmp.AddRange(responseUid); dumpTmp.AddRange(new byte[4]); for (byte i = 0; i < 33; i++) { byte[] response = await mifareULAccess.ReadAsync((byte)(4 * i)); dumpTmp.AddRange(response); LogMessage("Block " + (4 * i).ToString() + " to Block " + (4 * i + 3).ToString() + " " + BitConverter.ToString(response)); } LogMessage("Dump ended :) !"); dumpTmp.AddRange(new byte[4] { 0x5F, 0x00, 0x00, 0x00 }); Dump = dumpTmp.ToArray(); MessageDialog msg = new MessageDialog("Dump completed !"); await msg.ShowAsync(); } else { LogMessage("This tag is not an Amiibo and can't be dumped!"); MessageDialog msg = new MessageDialog("This tag is not an Amiibo and can't be dumped !"); await msg.ShowAsync(); var apduRes = await connection.TransceiveAsync(new Pcsc.GetUid()); if (!apduRes.Succeeded) { LogMessage("Failure getting UID of card, " + apduRes.ToString()); } else { LogMessage("UID: " + BitConverter.ToString(apduRes.ResponseData)); } } connection.Dispose(); } catch (Exception ex) { connection.Dispose(); LogMessage("Exception handling card: " + ex.ToString()); MessageDialog msg = new MessageDialog("Exception handling card: " + ex.ToString()); await msg.ShowAsync(); } }
public FelicaReader(SmartCardConnection connection) { this.connection = connection; this.felicaAccess = new Felica.AccessHandler(connection); }
/// <summary> /// Sample code to hande a couple of different cards based on the identification process /// </summary> /// <returns>None</returns> private async Task HandleCard(SmartCard card) { try { // Clear the messages MainPage.Current.NotifyUser(String.Empty, NotifyType.StatusMessage, true); // Connect to the card using (SmartCardConnection connection = await card.ConnectAsync()) { // Try to identify what type of card it was IccDetection cardIdentification = new IccDetection(card, connection); await cardIdentification.DetectCardTypeAync(); LogMessage("Connected to card\r\nPC/SC device class: " + cardIdentification.PcscDeviceClass.ToString()); LogMessage("Card name: " + cardIdentification.PcscCardName.ToString()); LogMessage("ATR: " + BitConverter.ToString(cardIdentification.Atr)); if ((cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass) && (cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightC || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralight || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightEV1)) { // Handle MIFARE Ultralight MifareUltralight.AccessHandler mifareULAccess = new MifareUltralight.AccessHandler(connection); // Each read should get us 16 bytes/4 blocks, so doing // 4 reads will get us all 64 bytes/16 blocks on the card for (byte i = 0; i < 4; i++) { byte[] response = await mifareULAccess.ReadAsync((byte)(4 * i)); LogMessage("Block " + (4 * i).ToString() + " to Block " + (4 * i + 3).ToString() + " " + BitConverter.ToString(response)); } byte[] responseUid = await mifareULAccess.GetUidAsync(); LogMessage("UID: " + BitConverter.ToString(responseUid)); } else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.MifareDesfire) { // Handle MIFARE DESfire Desfire.AccessHandler desfireAccess = new Desfire.AccessHandler(connection); Desfire.CardDetails desfire = await desfireAccess.ReadCardDetailsAsync(); LogMessage("DesFire Card Details: " + Environment.NewLine + desfire.ToString()); } else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass && cardIdentification.PcscCardName == Pcsc.CardName.FeliCa) { // Handle Felica LogMessage("Felica card detected"); var felicaAccess = new Felica.AccessHandler(connection); var uid = await felicaAccess.GetUidAsync(); LogMessage("UID: " + BitConverter.ToString(uid)); } else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass && (cardIdentification.PcscCardName == Pcsc.CardName.MifareStandard1K || cardIdentification.PcscCardName == Pcsc.CardName.MifareStandard4K)) { // Handle MIFARE Standard/Classic LogMessage("MIFARE Standard/Classic card detected"); var mfStdAccess = new MifareStandard.AccessHandler(connection); var uid = await mfStdAccess.GetUidAsync(); LogMessage("UID: " + BitConverter.ToString(uid)); ushort maxAddress = 0; switch (cardIdentification.PcscCardName) { case Pcsc.CardName.MifareStandard1K: maxAddress = 0x3f; break; case Pcsc.CardName.MifareStandard4K: maxAddress = 0xff; break; } await mfStdAccess.LoadKeyAsync(MifareStandard.DefaultKeys.FactoryDefault); for (ushort address = 0; address <= maxAddress; address++) { var response = await mfStdAccess.ReadAsync(address, Pcsc.GeneralAuthenticate.GeneralAuthenticateKeyType.MifareKeyA); LogMessage("Block " + address.ToString() + " " + BitConverter.ToString(response)); } } else if (cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass && (cardIdentification.PcscCardName == Pcsc.CardName.ICODE1 || cardIdentification.PcscCardName == Pcsc.CardName.ICODESLI || cardIdentification.PcscCardName == Pcsc.CardName.iCodeSL2)) { // Handle ISO15693 LogMessage("ISO15693 card detected"); var iso15693Access = new Iso15693.AccessHandler(connection); var uid = await iso15693Access.GetUidAsync(); LogMessage("UID: " + BitConverter.ToString(uid)); } else { // Unknown card type // Note that when using the XDE emulator the card's ATR and type is not passed through, so we'll // end up here even for known card types if using the XDE emulator // Some cards might still let us query their UID with the PC/SC command, so let's try: var apduRes = await connection.TransceiveAsync(new Pcsc.GetUid()); if (!apduRes.Succeeded) { LogMessage("Failure getting UID of card, " + apduRes.ToString()); } else { LogMessage("UID: " + BitConverter.ToString(apduRes.ResponseData)); } } } } catch (Exception ex) { LogMessage("Exception handling card: " + ex.ToString(), NotifyType.ErrorMessage); } }
private async Task AuthenticateWithSmartCardAsync(SmartCard card) { var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; String m_selectedDeviceId = localSettings.Values["SelectedDevice"] as String; string m_selectedDeviceFriendlyName = string.Empty; string m_selectedDeviceAddDate = string.Empty; string deviceConfigString = string.Empty; char[] deviceConfigCharArray; byte[] deviceIdArray = new byte[16]; byte[] deviceDlockState = new byte[1]; bool foundCompanionDevice = false; byte[] response = { 0 }; string sw1sw2 = null; SecondaryAuthenticationFactorAuthenticationStageInfo authStageInfo = await SecondaryAuthenticationFactorAuthentication.GetAuthenticationStageInfoAsync(); if ((authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.CollectingCredential) && (authStageInfo.Stage != SecondaryAuthenticationFactorAuthenticationStage.WaitingForUserConfirmation)) { throw new Exception("Unexpected! Stage: " + authStageInfo.Stage); } //ShowToastNotification("Post Collecting Credential"); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Post Collecting Credential"); IReadOnlyList <SecondaryAuthenticationFactorInfo> deviceList = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync( SecondaryAuthenticationFactorDeviceFindScope.AllUsers); if (deviceList.Count == 0) { //ShowToastNotification("Unexpected exception, device list = 0"); throw new Exception("Unexpected exception, device list = 0"); } SmartCardConnection connection = await card.ConnectAsync(); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Connection"); response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceIdArray = response; string deviceId = BitConverter.ToString(response).Replace("-", ""); response = await Apdu.TransmitApduAsync(connection, Apdu.getDlockStateCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceDlockState = response; //string deviceFriendlyName = null; byte[] deviceConfigDataArray = new byte[18]; //16 bytes for GUID and 1 byte for dLockstate IBuffer deviceConfigData; byte[] deviceConfigurationDataArray; //List<byte[]> deviceConfigList = new List<byte[]>(); foreach (SecondaryAuthenticationFactorInfo device in deviceList) { CryptographicBuffer.CopyToByteArray(device.DeviceConfigurationData, out deviceConfigurationDataArray); //deviceConfigList.Add(deviceConfigurationDataArray); //deviceFriendlyName = device.DeviceFriendlyName; if (device.DeviceId == deviceId) { m_selectedDeviceId = deviceId; m_selectedDeviceFriendlyName = device.DeviceFriendlyName; deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); //deviceConfigCharArray = new char[deviceConfigString.Count()]; //deviceConfigCharArray = deviceConfigString.ToCharArray(); int count = device.DeviceFriendlyName.Count(); m_selectedDeviceAddDate = deviceConfigString.Substring(35 + 1 + count + 1 + 1); foundCompanionDevice = true; //continue; } } //Debugger.Break(); if (!foundCompanionDevice) { throw new CompanionDeviceNotFoundException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Start Nonce APDU sending"); response = await Apdu.TransmitApduAsync(connection, Apdu.getNonceCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); if (sw1sw2 != "9000") { throw new UnableTogetNonceFromDeviceException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Nonce APDU recieved without error"); string nonce = BitConverter.ToString(response).Replace("-", ""); IBuffer svcNonce = CryptographicBuffer.DecodeFromHexString(nonce); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Start Authentication"); SecondaryAuthenticationFactorAuthenticationResult authResult = await SecondaryAuthenticationFactorAuthentication.StartAuthenticationAsync( m_selectedDeviceId, svcNonce); if (authResult.Status != SecondaryAuthenticationFactorAuthenticationStatus.Started) { //ShowToastNotification("Unexpected! Could not start authentication!"); throw new Exception("Unexpected! Could not start authentication! Status: " + authResult.Status); } byte[] devNonce = { 0 }; byte[] svcHmac = { 0 }; byte[] sessNonce = { 0 }; CryptographicBuffer.CopyToByteArray(authResult.Authentication.ServiceAuthenticationHmac, out svcHmac); CryptographicBuffer.CopyToByteArray(authResult.Authentication.SessionNonce, out sessNonce); CryptographicBuffer.CopyToByteArray(authResult.Authentication.DeviceNonce, out devNonce); byte[] cmd = new byte[Apdu.challengeCmdApdu.Length + svcHmac.Length + sessNonce.Length + devNonce.Length]; System.Buffer.BlockCopy(Apdu.challengeCmdApdu, 0, cmd, 0, Apdu.challengeCmdApdu.Length); System.Buffer.BlockCopy(svcHmac, 0, cmd, Apdu.challengeCmdApdu.Length, svcHmac.Length); System.Buffer.BlockCopy(sessNonce, 0, cmd, Apdu.challengeCmdApdu.Length + svcHmac.Length, sessNonce.Length); System.Buffer.BlockCopy(devNonce, 0, cmd, Apdu.challengeCmdApdu.Length + svcHmac.Length + sessNonce.Length, devNonce.Length); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Send Challenge"); string str = "\"" + m_selectedDeviceFriendlyName + "\""; await SecondaryAuthenticationFactorAuthentication.ShowNotificationMessageAsync( str, SecondaryAuthenticationFactorAuthenticationMessage.DeviceNeedsAttention); response = await Apdu.TransmitApduAsync(connection, cmd); sw1sw2 = Apdu.ApduResponseParser(response, out response); if (sw1sw2 == "6985") { throw new UnauthorizedUserException(); } else if (sw1sw2 == "6984") { //ShowToastNotification("Log-in denied by user"); throw new LogInDeniedByUserException(); } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Response recieved"); byte[] HMACdk = new byte[32]; byte[] HMACsk = new byte[32]; System.Buffer.BlockCopy(response, 0, HMACdk, 0, 32); System.Buffer.BlockCopy(response, 32, HMACsk, 0, 32); IBuffer deviceHmac = CryptographicBuffer.CreateFromByteArray(HMACdk); IBuffer sessionHmac = CryptographicBuffer.CreateFromByteArray(HMACsk); SecondaryAuthenticationFactorFinishAuthenticationStatus authStatus = await authResult.Authentication.FinishAuthenticationAsync(deviceHmac, sessionHmac); if (authStatus != SecondaryAuthenticationFactorFinishAuthenticationStatus.Completed) { //ShowToastNotification("Unable to complete authentication!"); System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Unable to complete authentication"); throw new Exception("Unable to complete authentication!"); } deviceConfigString = ""; if (deviceDlockState[0] == 0) { deviceConfigString = deviceId + "-0-1-" + m_selectedDeviceFriendlyName + "-" + m_selectedDeviceAddDate; } else { deviceConfigString = deviceId + "-1-1-" + m_selectedDeviceFriendlyName + "-" + m_selectedDeviceAddDate; } deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigString.CopyTo(0, deviceConfigCharArray, 0, deviceConfigString.Count()); // because deviceConfigString is readonly deviceConfigCharArray[35] = '1'; // to indicate that device was not used for last login string deviceConfigStringNew = new string(deviceConfigCharArray); //Debugger.Break(); deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigStringNew, 0); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(deviceId, deviceConfigData); //update deviceConfigData foreach (SecondaryAuthenticationFactorInfo device in deviceList) { if (device.DeviceId != deviceId) { deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigString.CopyTo(0, deviceConfigCharArray, 0, deviceConfigString.Count()); // decause deviceConfigString is readonly deviceConfigCharArray[35] = '0'; // to indicate that device was not used for last login deviceConfigStringNew = new string(deviceConfigCharArray); deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigStringNew, 0); //Debugger.Break(); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(device.DeviceId, deviceConfigData); //update deviceConfigData } } System.Diagnostics.Debug.WriteLine("[AuthenticateWithSmartCardAsync] Auth completed"); connection.Dispose(); }
private async Task <List <SecondaryAuthenticationFactorInfo> > getConnectedRegisteredDeviceList(IReadOnlyList <SecondaryAuthenticationFactorInfo> devicesToCheck) { //byte[] deviceConfigurationDataArray; string selector = SmartCardReader.GetDeviceSelector(); selector += " AND System.Devices.DeviceInstanceId:~~\"Ledger\""; byte[] response = { 0 }; string sw1sw2 = null; string NanosATR = "3b00"; byte[] deviceDlockState = new byte[1]; byte[] deviceIdArray = new byte[16]; List <SecondaryAuthenticationFactorInfo> outList = new List <SecondaryAuthenticationFactorInfo>(); DeviceInformationCollection readers = await DeviceInformation.FindAllAsync(selector); foreach (SecondaryAuthenticationFactorInfo device in devicesToCheck) { //CryptographicBuffer.CopyToByteArray(device.DeviceConfigurationData, out deviceConfigurationDataArray); foreach (DeviceInformation smartcardreader in readers) { SmartCardReader reader = await SmartCardReader.FromIdAsync(smartcardreader.Id); SmartCardReaderStatus readerstatus = await reader.GetStatusAsync(); IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync(); foreach (SmartCard card in cards) { try { IBuffer ATR = await card.GetAnswerToResetAsync(); string ATR_str = CryptographicBuffer.EncodeToHexString(ATR); if (ATR_str.Equals(NanosATR)) { SmartCardConnection connection = await card.ConnectAsync(); response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceIdArray = response; string deviceId = BitConverter.ToString(response).Replace("-", ""); if (deviceId == device.DeviceId) //update config data with dLockState and increment counter { outList.Add(device); } connection.Dispose(); } } catch { } } } } return(outList); }
private async Task writeConnectedRegisteredDevices() { string NanosATR = "3b00"; string selector = SmartCardReader.GetDeviceSelector(); selector += " AND System.Devices.DeviceInstanceId:~~\"Ledger\""; byte[] response = { 0 }; string sw1sw2 = null; byte[] deviceDlockState = new byte[1]; byte[] deviceIdArray = new byte[16]; string txt = ""; DeviceInformationCollection readers = await DeviceInformation.FindAllAsync(selector); IReadOnlyList <SecondaryAuthenticationFactorInfo> RegisteredDeviceList_addEvent = await SecondaryAuthenticationFactorRegistration.FindAllRegisteredDeviceInfoAsync( SecondaryAuthenticationFactorDeviceFindScope.User); List <SecondaryAuthenticationFactorInfo> ConnectedRegisteredDeviceList = await getConnectedRegisteredDeviceList(RegisteredDeviceList_addEvent); foreach (SecondaryAuthenticationFactorInfo device in ConnectedRegisteredDeviceList) { foreach (DeviceInformation smartcardreader in readers) { SmartCardReader reader = await SmartCardReader.FromIdAsync(smartcardreader.Id); SmartCardReaderStatus readerstatus = await reader.GetStatusAsync(); IReadOnlyList <SmartCard> cards = await reader.FindAllCardsAsync(); foreach (SmartCard card in cards) { try { IBuffer ATR = await card.GetAnswerToResetAsync(); string ATR_str = CryptographicBuffer.EncodeToHexString(ATR); if (ATR_str.Equals(NanosATR)) { SmartCardConnection connection = await card.ConnectAsync(); response = await Apdu.TransmitApduAsync(connection, Apdu.getDeviceGuidCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceIdArray = response; string deviceId = BitConverter.ToString(response).Replace("-", ""); if (deviceId == device.DeviceId) //update config data with dLockState { if (device.PresenceMonitoringMode != SecondaryAuthenticationFactorDevicePresenceMonitoringMode.AppManaged) { // Skip the device which doesn't need to be monitored in the background task continue; } await device.UpdateDevicePresenceAsync(SecondaryAuthenticationFactorDevicePresence.Present); response = await Apdu.TransmitApduAsync(connection, Apdu.getDlockStateCmdApdu); sw1sw2 = Apdu.ApduResponseParser(response, out response); deviceDlockState = response; string deviceConfigString = CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData); char[] deviceConfigCharArray = new char[deviceConfigString.Count()]; deviceConfigCharArray = deviceConfigString.ToCharArray(); string deviceConfigStringNew = ""; int count = device.DeviceFriendlyName.Count(); if (deviceDlockState[0] == 0) { if (deviceConfigCharArray[35] == '0') // Indicates if device was used for last login { deviceConfigStringNew = device.DeviceId + "-0-0-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } else { deviceConfigStringNew = device.DeviceId + "-0-1-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } } else { if (deviceConfigCharArray[35] == '0') { deviceConfigStringNew = device.DeviceId + "-1-0-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } else { deviceConfigStringNew = device.DeviceId + "-1-1-" + device.DeviceFriendlyName + "-" + deviceConfigString.Substring(35 + 1 + count + 1 + 1); } } // Get a Ibuffer from combinedDataArray IBuffer deviceConfigData = CryptographicBuffer.ConvertStringToBinary(deviceConfigString, 0); await SecondaryAuthenticationFactorRegistration.UpdateDeviceConfigurationDataAsync(device.DeviceId, deviceConfigData); } connection.Dispose(); } } catch (Exception e) { } } } txt += CryptographicBuffer.ConvertBinaryToString(0, device.DeviceConfigurationData) + Environment.NewLine; } StorageFolder folder = ApplicationData.Current.LocalFolder; StorageFile ConnectedRegisteredDeviceListFile = await folder.CreateFileAsync("connectedRegisteredDeviceList.txt", CreationCollisionOption.ReplaceExisting); await FileIO.WriteTextAsync(ConnectedRegisteredDeviceListFile, txt); }
private async Task Initialize() { connection = await smartCard.ConnectAsync(); }
/// <summary> /// Class constructor /// </summary> /// <param name="ScConnection"> /// connection object to a MifareUL ICC /// </param> public AccessHandler(SmartCardConnection ScConnection) { connectionObject = ScConnection; }
private async Task HandleCard(SmartCard card) { try { connection = await card.ConnectAsync(); IccDetection cardIdentification = new IccDetection(card, connection); await cardIdentification.DetectCardTypeAync(); LogMessage("Connected to card\r\nPC/SC device class: " + cardIdentification.PcscDeviceClass.ToString()); LogMessage("Card name: " + cardIdentification.PcscCardName.ToString()); LogMessage("ATR: " + BitConverter.ToString(cardIdentification.Atr)); if ((cardIdentification.PcscDeviceClass == Pcsc.Common.DeviceClass.StorageClass) && (cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightC || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralight || cardIdentification.PcscCardName == Pcsc.CardName.MifareUltralightEV1)) { MifareUltralight.AccessHandler mifareULAccess = new MifareUltralight.AccessHandler(connection); byte[] responseUid = await mifareULAccess.GetUidAsync(); LogMessage("UID: " + BitConverter.ToString(responseUid)); if (!BinaryDump && !ByteArrayEqual(responseUid, AmiiboUID)) //I used this because for some reasons responseUid == AmiiboUID was always false { MessageDialog dialog = new MessageDialog("The dump UID and the amiibo UID don't match"); LogMessage("Amiibo UID: " + BitConverter.ToString(responseUid) + " != Dump UID: " + BitConverter.ToString(AmiiboUID)); await dialog.ShowAsync(); return; } LogMessage("Using key: " + BitConverter.ToString(AmiiboPass)); byte[] Authresponse = await mifareULAccess.TransparentExchangeAsync(new byte[] { 0x1B, AmiiboPass[0], AmiiboPass[1], AmiiboPass[2], AmiiboPass[3] }); //PWD_AUTH LogMessage("Auth sent !"); LogMessage("Auth Response length: " + Authresponse.Length.ToString()); if (Authresponse.Length == 0) { LogMessage("No response from Amiibo, can't restore dump !"); MessageDialog dlg = new MessageDialog("No response from Amiibo, wrong password ?"); await dlg.ShowAsync(); return; } LogMessage("Auth response: " + BitConverter.ToString(Authresponse)); //Using page layout from: https://www.3dbrew.org/wiki/Amiibo#Page_layout #region WritePages mifareULAccess.WriteAsync(0x4, getNBytes(AmiiboDump,0x10)); LogMessage("Page 0x4 wrote !"); mifareULAccess.WriteAsync(0x5, getNBytes(AmiiboDump, 0x14)); LogMessage("Page 0x5 wrote !"); mifareULAccess.WriteAsync(0x6, getNBytes(AmiiboDump, 0x18)); LogMessage("Page 0x6 wrote !"); mifareULAccess.WriteAsync(0x7, getNBytes(AmiiboDump, 0x1C)); LogMessage("Page 0x7 wrote !"); mifareULAccess.WriteAsync(0x8, getNBytes(AmiiboDump, 0x20)); LogMessage("Page 0x8 wrote !"); mifareULAccess.WriteAsync(0x9, getNBytes(AmiiboDump, 0x24)); LogMessage("Page 0x9 wrote !"); mifareULAccess.WriteAsync(0xA, getNBytes(AmiiboDump, 0x28)); LogMessage("Page 0xA wrote !"); mifareULAccess.WriteAsync(0xB, getNBytes(AmiiboDump, 0x2C)); LogMessage("Page 0xB wrote !"); mifareULAccess.WriteAsync(0xC, getNBytes(AmiiboDump, 0x30)); LogMessage("Page 0xC wrote !"); mifareULAccess.WriteAsync(0x20, getNBytes(AmiiboDump, 0x80)); LogMessage("Page 0x20 wrote !"); mifareULAccess.WriteAsync(0x21, getNBytes(AmiiboDump, 0x84)); LogMessage("Page 0x21 wrote !"); mifareULAccess.WriteAsync(0x22, getNBytes(AmiiboDump, 0x88)); LogMessage("Page 0x22 wrote !"); mifareULAccess.WriteAsync(0x23, getNBytes(AmiiboDump, 0x8C)); LogMessage("Page 0x23 wrote !"); mifareULAccess.WriteAsync(0x24, getNBytes(AmiiboDump, 0x90)); LogMessage("Page 0x24 wrote !"); mifareULAccess.WriteAsync(0x25, getNBytes(AmiiboDump, 0x94)); LogMessage("Page 0x25 wrote !"); mifareULAccess.WriteAsync(0x26, getNBytes(AmiiboDump, 0x98)); LogMessage("Page 0x26 wrote !"); mifareULAccess.WriteAsync(0x27, getNBytes(AmiiboDump, 0x9c)); LogMessage("Page 0x27 wrote !");//Until here i manually wrote the write addreses to test if the writing works, but i'm too lazy to replace those arleady working functions with a cycle for (int i = 0; i < 0x5A; i++) mifareULAccess.WriteAsync((byte)(0x28/*Page*/ + i), getNBytes(AmiiboDump, 0xA0 /*ADDR of page 0x28*/ + (i*4))); LogMessage("Page 0x28 to 0x81 wrote !"); #endregion LogMessage("Dump restored :) !"); MessageDialog msg = new MessageDialog("Dump restored !"); await msg.ShowAsync(); } else { LogMessage("This tag is not an Amiibo !"); MessageDialog msg = new MessageDialog("This tag is not an Amiibo !"); await msg.ShowAsync(); var apduRes = await connection.TransceiveAsync(new Pcsc.GetUid()); if (!apduRes.Succeeded) { LogMessage("Failure getting UID of card, " + apduRes.ToString()); } else { LogMessage("UID: " + BitConverter.ToString(apduRes.ResponseData)); } } connection.Dispose(); } catch (Exception ex) { connection.Dispose(); LogMessage("Exception handling card: " + ex.ToString()); MessageDialog msg = new MessageDialog("Exception handling card: " + ex.ToString()); await msg.ShowAsync(); } }