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;
 }
Exemple #3
0
        public static async Task <byte[]> TransmitApduAsync(SmartCardConnection connection, byte[] ApduCommand)
        {
            IBuffer command  = CryptographicBuffer.CreateFromByteArray(ApduCommand);
            IBuffer response = await connection.TransmitAsync(command);

            return(response.ToArray());
        }
Exemple #4
0
 /// <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 void Dispose()
 {
     if (this.connection != null)
     {
         this.connection.Dispose();
     }
     this.connection = null;
 }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
0
        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);
        }
Exemple #11
0
        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
Exemple #12
0
        /// <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);
            }
        }
Exemple #14
0
        /// <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);
        }
Exemple #15
0
        /// <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);
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                try
                {
                    connection?.Dispose();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
                
                connection = null;
            }

            base.Dispose(disposing);
        }
Exemple #18
0
        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;
        }
Exemple #19
0
        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;
        }
Exemple #20
0
        /// <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]}";
        }
Exemple #22
0
        } // 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);
        }
Exemple #23
0
        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");
            }
        }
Exemple #24
0
        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());
            }
        }
Exemple #25
0
 public UwpSmartCardConnection(SmartCardConnection backingConnection)
 {
     _backingConnection = backingConnection;
 }
Exemple #26
0
 /// <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)
 {
 }
Exemple #30
0
        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);
 }
 public EDYReader(SmartCardConnection connection)
     : base(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);
        }
Exemple #37
0
        /// <summary>
        /// Class constructor
        /// </summary>
        /// <param name="ScConnection">
        /// connection object to a Desfire ICC
        /// </param>
        public AccessHandler(SmartCardConnection ScConnection)
        {
            connectionObject = ScConnection;

            desfireCommand = new DesfireCommand();
        }
 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;
 }
Exemple #40
0
        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();
            }
        }