Exemple #1
0
        internal ContactlessCard(Card card)
        {
            Id = BitConverter.ToString(card.IdBytes);

            Card = card;

            CardreaderName = card.CardreaderName;
        }
        public void GetCardId()
        {
            // arrange
            _card = _reader.Connect(GetCardreaderName()).ConnectedCard;

            // act
            var getCardIdResult = _reader.GetCardId(_card);

            Assert.That(getCardIdResult.Bytes.Length, Is.GreaterThan(0));
        }
        public void GetCardState()
        {
            // arrange
            _card = _reader.Connect(GetCardreaderName()).ConnectedCard;

            // act
            var stateResult = _reader.GetCardState(_card);

            Assert.That(stateResult, Is.True);
            Assert.That(_card.State.CardStateType, Is.EqualTo(CardStateType.CardSpecific));
        }
        public void DisableDefaultBuzzer()
        {
            // arrange
            if (_card == null)
                _card = _reader.Connect(GetCardreaderName()).ConnectedCard;

            // act
            var operationResult = _reader.SetBuzzerOutputForCardDetection(_card, false);

            Assert.IsTrue(operationResult.IsCompletelySuccessful);
        }
Exemple #5
0
        public OperationResult DisconnectCard(Card cardForDisconnect)
        {
            if (cardForDisconnect == null) throw new ArgumentNullException("cardForDisconnect");

            if (cardForDisconnect.ConnectionHandle != IntPtr.Zero)
            {
                var result = DisconnectCardMultiHandlesAware(cardForDisconnect);

                return result;
            }

            return OperationResult.Successful;
        }
Exemple #6
0
        /// <summary>
        /// Establishing a connection to smart card contained by a specific reader.
        /// <param name="cardreaderName">Card reader name to connection.</param>
        /// </summary>
        public ConnectResult Connect(string cardreaderName, Guid? idOverride = null)
        {
            var resourceManagerContext = EstablishContextIfNotEstablished();

            IntPtr cardConnectionHandle;
            int connectionProtocolType;

            int returnCode = WinscardWrapper.SCardConnect(
                resourceManagerContext,
                cardreaderName,
                WinscardWrapper.SCARD_SHARE_SHARED,
                WinscardWrapper.SCARD_PROTOCOL_T0 | WinscardWrapper.SCARD_PROTOCOL_T1,
                out cardConnectionHandle,
                out connectionProtocolType);

            var operationResult = ReturnCodeManager.GetErrorMessage(returnCode);
            var connectResult = new ConnectResult(operationResult);

            if (operationResult.IsSuccessful)
            {
                var newCard = new Card(
                    Thread.CurrentThread.ManagedThreadId,
                    cardConnectionHandle,
                    cardreaderName,
                    connectionProtocolType);

                _cardConnectionManager.AddConnection(
                    idOverride ?? newCard.InternalUid,
                    Thread.CurrentThread.ManagedThreadId,
                    cardConnectionHandle);

                connectResult.ConnectedCard = newCard;
            }

            return connectResult;
        }
Exemple #7
0
        private ApduResponse SendAPDU(Card card, byte[] bytesToSend, int expectedRequestLength)
        {
            Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU started");
            Logger.TraceEvent(TraceEventType.Verbose, 0, "bytesToSend: {0}", BitConverter.ToString(bytesToSend));
            Logger.TraceEvent(TraceEventType.Verbose, 0, "card connection handle: {0}", card.ConnectionHandle);
            Logger.Flush();

            IntPtr cardConnectionHandle = card.ConnectionHandle;

            // establish a new temporary connection in case of context mismatch
            if (card.ThreadId != Thread.CurrentThread.ManagedThreadId)
            {
                Logger.TraceEvent(TraceEventType.Verbose, 0,
                    string.Format("Card context mismatch. Original thread: {0}. Current thread: {1}",
                    card.ThreadId,
                    Thread.CurrentThread.ManagedThreadId));
                Logger.Flush();

                if (!_cardConnectionManager.IsConnectionExist(card.InternalUid, Thread.CurrentThread.ManagedThreadId))
                {
                    // establish a new connection
                    var connectionResult = Connect(card.CardreaderName, card.InternalUid);
                    if (!connectionResult.IsSuccessful)
                    {
                        return new ApduResponse
                                    {
                                        ReturnCode = connectionResult.StatusCode,
                                        RecvBuff = new byte[0],
                                        ResponseLength = 0
                                    };
                    }

                    // use a handle of a new connection
                    cardConnectionHandle = connectionResult.ConnectedCard.ConnectionHandle;

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: new connection established. Handle: "
                                                                    + cardConnectionHandle);
                }
                else
                {
                    cardConnectionHandle = _cardConnectionManager
                        .GetConnection(card.InternalUid, Thread.CurrentThread.ManagedThreadId);

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU: existed card context found. Handle: "
                                                                    + cardConnectionHandle);
                }
            }

            var recvBuff = new byte[500];

            WinscardWrapper.SCARD_IO_REQUEST pioSendRequest;
            pioSendRequest.dwProtocol = card.Protocol;
            pioSendRequest.cbPciLength = PciLength;

            int returnCode = WinscardWrapper.SCardTransmit(
                cardConnectionHandle, ref pioSendRequest,
                ref bytesToSend[0], bytesToSend.Length,
                ref pioSendRequest, ref recvBuff[0],
                ref expectedRequestLength);

            Logger.TraceEvent(TraceEventType.Verbose, 0, "SendAPDU ended. Return code: " + returnCode);
            Logger.Flush();

            //http://msdn.microsoft.com/en-us/library/windows/desktop/aa379804(v=vs.85).aspx
            //The pcbRecvLength should be at least n+2 and will be set to n+2 upon return.

            var result = new ApduResponse
            {
                RecvBuff = recvBuff,
                ResponseLength = expectedRequestLength,
                ReturnCode = returnCode
            };

            return result;
        }
Exemple #8
0
        /// <summary>
        /// Terminates all connections for given card.
        /// </summary>
        /// <remarks>
        /// The card very likely is not attached to the cardreader at the moment of execution,
        /// so SCARD_LEAVE_CARD is used here to avoid error log messages from underlying winscard api.
        /// </remarks>
        private OperationResult DisconnectCardMultiHandlesAware(Card cardForDisconnect)
        {
            var currentHandle = cardForDisconnect.ConnectionHandle;

            // disconnect first (current) handle
            var mainReturnCode = WinscardWrapper.SCardDisconnect(cardForDisconnect.ConnectionHandle, WinscardWrapper.SCARD_LEAVE_CARD);
            var mainDisconnectResult = ReturnCodeManager.GetErrorMessage(mainReturnCode);

            Logger.TraceEvent(TraceEventType.Verbose, 0, "First handler disconnect result: {0}", mainDisconnectResult.StatusDescription);

            // disconnect the rest handles
            if (mainDisconnectResult.IsSuccessful)
            {
                var restHandlers = _cardConnectionManager.GetConnections(cardForDisconnect.InternalUid);

                Logger.TraceEvent(TraceEventType.Verbose, 0, "Card has {0} handlers", restHandlers.Length);

                foreach (var handleToDisconnect in restHandlers.Where(x => x != currentHandle))
                {
                    var returnCode = WinscardWrapper.SCardDisconnect(handleToDisconnect, WinscardWrapper.SCARD_LEAVE_CARD);
                    var result = ReturnCodeManager.GetErrorMessage(returnCode);

                    Logger.TraceEvent(TraceEventType.Verbose, 0, "Card handler disconnect result: {0}", result.StatusDescription);
                }

                _cardConnectionManager.CardDisconnected(cardForDisconnect.InternalUid);
            }

            cardForDisconnect.ConnectionHandle = IntPtr.Zero;

            return mainDisconnectResult;
        }
Exemple #9
0
        public ApduOperationResult UpdateLedAndBuzzer(Card card, byte ledState, byte t1, byte t2, byte repetitionNumber, byte buzzer)
        {
            var bytesToSend = new byte[9];
            bytesToSend[0] = 0xFF;
            bytesToSend[1] = 0x00;
            bytesToSend[2] = 0x40;
            bytesToSend[3] = ledState;
            bytesToSend[4] = 0x04;
            bytesToSend[5] = t1;
            bytesToSend[6] = t2;
            bytesToSend[7] = repetitionNumber;
            bytesToSend[8] = buzzer;

            const int responseCodeLength = 2;

            ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength);

            return ReturnCodeManager.IsApduSuccessful(response);
        }
Exemple #10
0
        public ApduOperationResult SetBuzzerOutputForCardDetection(Card card, bool shouldBuzzWhenCardDetected)
        {
            var bytesToSend = new byte[5];
            bytesToSend[0] = 0xFF;
            bytesToSend[1] = 0x00;
            bytesToSend[2] = 0x52;
            bytesToSend[3] = shouldBuzzWhenCardDetected ? (byte)0xFF : (byte)0x00;
            bytesToSend[4] = 0x00;

            const int responseCodeLength = 2;

            ApduResponse response = SendAPDU(card, bytesToSend, responseCodeLength);

            return ReturnCodeManager.IsApduSuccessful(response);
        }
Exemple #11
0
        /// <summary>
        /// The function provides the current status of a smart card in a reader.
        /// </summary>
        public OperationResult GetCardState(Card cardToRead)
        {
            if (cardToRead == null) throw new ArgumentNullException("cardToRead");

            var sizeOfReadersListStructure = 0;
            var cardStateStatus = 0;
            var dwActProtocol = 0;
            var tmpAtrBytes = new byte[257];
            var tmpAtrLen = 32;

            var returnCode = WinscardWrapper.SCardStatus(cardToRead.ConnectionHandle, cardToRead.CardreaderName, ref sizeOfReadersListStructure, ref cardStateStatus, ref dwActProtocol, ref tmpAtrBytes[0], ref tmpAtrLen);

            OperationResult result = ReturnCodeManager.GetErrorMessage(returnCode);

            if (result.IsSuccessful)
            {
                cardToRead.State = new CardState(cardStateStatus);
                cardToRead.Atr = tmpAtrBytes.Take(tmpAtrLen).ToArray();
                cardToRead.Protocol = dwActProtocol;
            }

            return result;
        }
Exemple #12
0
        /// <summary>
        /// Returns a card's UID.
        /// </summary>
        public ReceiveCardIdResult GetCardId(Card cardToRead)
        {
            if (cardToRead == null) throw new ArgumentNullException("cardToRead");

            var bytesToSend = new byte[5];
            bytesToSend[0] = 0xFF; // Class
            bytesToSend[1] = 0xCA; // INS
            bytesToSend[2] = 0x00; // P1
            bytesToSend[3] = 0x00; // P2
            bytesToSend[4] = 0x00; // LE:Full Length

            ApduResponse response = SendAPDU(cardToRead, bytesToSend, 10);

            const int responseCodeLength = 2;
            var responseLengthWithoutResponseCodes = response.ResponseLength - responseCodeLength;

            var receiveCardIdResult = new ReceiveCardIdResult(ReturnCodeManager.IsApduSuccessful(response));

            if (receiveCardIdResult.IsCompletelySuccessful)
            {
                //read UID bytes from apdu response
                receiveCardIdResult.Bytes = response.RecvBuff.Take(responseLengthWithoutResponseCodes).ToArray();
            }

            return receiveCardIdResult;
        }
Exemple #13
0
        private void RememberCardreaderHadCard(string readerName, Card connectedCard)
        {
            Logger.TraceEvent(TraceEventType.Verbose, 0, "Marking that cardreader ({0}) had a card", readerName);
            Logger.Flush();

            _attachedCardStatuses.AddOrUpdate(readerName, connectedCard, (key, newValue) => connectedCard);
        }
Exemple #14
0
        private void RaiseCardConnectedEvent(Card connectedLowlevelCard)
        {
            Logger.TraceEvent(TraceEventType.Verbose, 0, "Raising CardConnected event");
            Logger.Flush();

            SendOrPostCallback cb = state => CardConnected(null, new WatcherCardEventArgs(connectedLowlevelCard));
            AsyncOperation.Post(cb, null);
        }
        public void Led()
        {
            // arrange
            if (_card == null)
                _card = _reader.Connect(GetCardreaderName()).ConnectedCard;

            // act
            var getCardIdResult = _reader.GetCardId(_card);
            _reader.UpdateLedAndBuzzer(_card, 0x00, 0x00, 0x00, 0x00, 0x00);

            Assert.That(getCardIdResult.Bytes.Length, Is.GreaterThan(0));
        }
Exemple #16
0
 public WatcherCardEventArgs(Card card)
 {
     Card = card;
 }