Example #1
0
        public bool WaitEvent(ref byte evtcode, ref byte evtflags, ushort timeout_ms)
        {
            CardBuffer RESP;

            byte[] _ctrl = new byte[4];

            _ctrl[0] = 0x83;
            _ctrl[1] = 0x00;
            _ctrl[2] = (byte)(timeout_ms / 0x0100);
            _ctrl[3] = (byte)(timeout_ms % 0x0100);

            CardBuffer CTRL = new CardBuffer(_ctrl);

            RESP = ReaderChannel.Control(CTRL);
            if ((RESP == null) || (RESP.Length < 3) || (RESP.GetByte(0) != 0x00))
            {
                Trace.WriteLine("Control(" + CTRL.AsString() + ") failed");

                if (RESP == null)
                {
                    Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                }
                else
                {
                    Trace.WriteLine("\tResp= " + RESP.AsString());
                }

                return(false);
            }

            evtcode  = RESP.GetByte(1);
            evtflags = RESP.GetByte(2);

            return(true);
        }
Example #2
0
        public CardBuffer Process(CardBuffer inBuffer)
        {
            CardBuffer outBuffer;

            if (UseApdus)
            {
                try
                {
                    /* Transform incoming frame into an APDU */
                    CAPDU capdu = new CAPDU(inBuffer.GetBytes());
                    /* Process the APDU */
                    outBuffer = OnApdu(new CAPDU(inBuffer.GetBytes()));
                } catch (Exception)
                {
                    /* Incoming frame is not a valid APDU, return 6700 */
                    outBuffer = new RAPDU(0x67, 0x00);
                }
            }
            else
            {
                /* Process the frame */
                outBuffer = OnFrame(inBuffer);
            }

            IsFirstCommand = false;

            return(outBuffer);
        }
Example #3
0
        private bool PeekCommand(ref CardBuffer inBuffer)
        {
            CardBuffer RESP;
            CardBuffer CTRL = new CardBuffer("84");

            RESP = ReaderChannel.Control(CTRL);
            if ((RESP == null) || (RESP.Length <= 1) || (RESP.GetByte(0) != 0x00))
            {
                Trace.WriteLine("Control(" + CTRL.AsString() + ") failed");

                if (RESP == null)
                {
                    Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                }
                else
                {
                    Trace.WriteLine("\tResp= " + RESP.AsString());
                }

                return(false);
            }

            byte[] buffer = new byte[RESP.Length - 1];

            for (int i = 0; i < RESP.Length - 1; i++)
            {
                buffer[i] = RESP.GetByte(i + 1);
            }

            inBuffer = new CardBuffer(buffer);
            return(true);
        }
Example #4
0
        private bool DriveBuzzer(bool active)
        {
            if (ReaderChannel == null)
            {
                return(false);
            }

            CardBuffer RESP;
            CardBuffer CTRL;

            if (active)
            {
                CTRL = new CardBuffer("581C0040");
            }
            else
            {
                CTRL = new CardBuffer("581C0200");
            }

            RESP = ReaderChannel.Control(CTRL);

            if ((RESP == null) || (RESP.Length < 1) || (RESP.GetByte(0) != 0x00))
            {
                return(false);
            }

            return(true);
        }
Example #5
0
        public bool GetEvent(ref byte evtcode, ref byte evtflags)
        {
            if (ReaderChannel == null)
            {
                return(false);
            }

            CardBuffer RESP;
            CardBuffer CTRL = new CardBuffer("8300");

            RESP = ReaderChannel.Control(CTRL);
            if ((RESP == null) || (RESP.Length < 3) || (RESP.GetByte(0) != 0x00))
            {
                Trace.WriteLine("Control(" + CTRL.AsString() + ") failed");

                if (RESP == null)
                {
                    Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                }
                else
                {
                    Trace.WriteLine("\tResp= " + RESP.AsString());
                }

                return(false);
            }

            evtcode  = RESP.GetByte(1);
            evtflags = RESP.GetByte(2);

            return(true);
        }
Example #6
0
        private bool PokeResponse(CardBuffer outBuffer)
        {
            CardBuffer RESP;
            CardBuffer CTRL;

            byte[] buffer = new byte[outBuffer.Length + 1];
            buffer[0] = 0x84;
            for (int i = 0; i < outBuffer.Length; i++)
            {
                buffer[i + 1] = outBuffer.GetByte(i);
            }

            CTRL = new CardBuffer(buffer);

            RESP = ReaderChannel.Control(CTRL);
            if ((RESP == null) || (RESP.Length < 1) || (RESP.GetByte(0) != 0x00))
            {
                Trace.WriteLine("Control(" + CTRL.AsString() + ") failed");

                if (RESP == null)
                {
                    Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                }
                else
                {
                    Trace.WriteLine("\tResp= " + RESP.AsString());
                }

                return(false);
            }

            return(true);
        }
 public bool Write(byte address, CardBuffer buffer)
 {
     _last_error = SCARD.MifUlC_Write4(hCard, address, buffer.GetBytes());
     if (_last_error != 0)
     {
         return(false);
     }
     return(true);
 }
 public bool Authenticate(CardBuffer key)
 {
     _last_error = SCARD.MifUlC_Authenticate(hCard, key.GetBytes());
     if (_last_error != 0)
     {
         return(false);
     }
     return(true);
 }
 public bool ChangeKey(CardBuffer key)
 {
     _last_error = SCARD.MifUlC_ChangeKey(hCard, key.GetBytes());
     if (_last_error != 0)
     {
         return(false);
     }
     return(true);
 }
Example #10
0
        public RAPDU Control(CAPDU cctrl)
        {
            _cctrl = cctrl;

            if (!Control())
            {
                return(null);
            }

            return(new RAPDU(_rctrl));
        }
Example #11
0
        public string[] Descriptions(string sAtr)
        {
            CardBuffer abAtr = new CardBuffer(sAtr);

            if ((abAtr == null) || (abAtr.Length == 0))
            {
                return(null);
            }

            return(Descriptions(abAtr));
        }
Example #12
0
        public CardBuffer Control(CardBuffer cctrl)
        {
            CardBuffer _rctrl;

            if (!Control(cctrl, out _rctrl))
            {
                return(null);
            }

            return(_rctrl);
        }
Example #13
0
        public CardBuffer Control(CardBuffer cctrl)
        {
            _cctrl = cctrl;

            if (!Control())
            {
                return(null);
            }

            return(_rctrl);
        }
Example #14
0
        public string SerialNumber()
        {
            /* Serial number */
            CardBuffer r = Control(new CardBuffer("582003"));

            if ((r != null) && (r.Length >= 1) && (r.GetByte(0) == 0x00))
            {
                string s = new String(r.GetChars(1, -1));
                return(s);
            }
            return("");
        }
        protected override void StatusChangeMonitor()
        {
            uint state = 0;

            while (_status_change_running)
            {
                uint rc;

                try {
                    rc = ParentReaderList.GetStatusChange(ReaderSlot, ref state, 250);
                }
                catch (ThreadInterruptedException) {
                    break;
                }

                if (!_status_change_running)
                {
                    break;
                }

                if (rc == SCARD.E_TIMEOUT)
                {
                    continue;
                }

                if (rc != SCARD.S_SUCCESS)
                {
                    _last_error = rc;
                    if (_status_change_callback != null)
                    {
                        _status_change_callback(0, null);
                    }
                    break;
                }

                if ((state & SCARD.STATE_CHANGED) != 0)
                {
                    state = state & ~SCARD.STATE_CHANGED;

                    if (_status_change_callback != null)
                    {
                        CardBuffer card_atr = null;

                        if ((state & SCARD.STATE_PRESENT) != 0)
                        {
                            card_atr = new CardBuffer(ParentReaderList.GetAtr(ReaderSlot));
                        }

                        _status_change_callback(state, card_atr);
                    }
                }
            }
        }
Example #16
0
        public bool Control(CAPDU cctrl, out RAPDU rctrl)
        {
            rctrl  = null;
            _cctrl = cctrl;

            if (!Control())
            {
                return(false);
            }

            rctrl = new RAPDU(_rctrl);
            return(true);
        }
 protected override void UpdateState()
 {
     _reader_state = ReaderDevice.State(Slot);
     Logger.Debug("UpdateState:" + BinConvert.ToHex(_reader_state));
     if ((_reader_state & SCARD.STATE_PRESENT) != 0)
     {
         _card_atr = new CardBuffer(ReaderDevice.GetAtr(Slot));
     }
     else
     {
         _card_atr = null;
     }
 }
Example #18
0
        public bool Control(CardBuffer cctrl, out CardBuffer rctrl)
        {
            rctrl  = null;
            _cctrl = cctrl;

            if (!Control())
            {
                return(false);
            }

            rctrl = _rctrl;
            return(true);
        }
Example #19
0
        private void UpdateState()
        {
            uint rc;

            IntPtr hContext = IntPtr.Zero;

            _reader_state = SCARD.STATE_UNAWARE;
            _card_atr     = null;

            rc =
                SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref hContext);
            if (rc != SCARD.S_SUCCESS)
            {
                _last_error = rc;
                return;
            }

            SCARD.READERSTATE[] states = new SCARD.READERSTATE[1];

            states[0]                = new SCARD.READERSTATE();
            states[0].szReader       = _reader_name;
            states[0].pvUserData     = IntPtr.Zero;
            states[0].dwCurrentState = 0;
            states[0].dwEventState   = 0;
            states[0].cbAtr          = 0;
            states[0].rgbAtr         = null;

            try
            {
                rc = SCARD.GetStatusChange(hContext, 0, states, 1);
            }
            catch (ThreadInterruptedException)
            {
                rc = SCARD.E_CANCELLED;
            }

            if (rc != SCARD.S_SUCCESS)
            {
                SCARD.ReleaseContext(hContext);
                return;
            }

            SCARD.ReleaseContext(hContext);

            _reader_state = states[0].dwEventState;

            if ((_reader_state & SCARD.STATE_PRESENT) != 0)
            {
                _card_atr = new CardBuffer(states[0].rgbAtr, (int)states[0].cbAtr);
            }
        }
Example #20
0
        public bool Control(CardBuffer cctrl, out CardBuffer rctrl)
        {
            rctrl = null;
            SCardChannel channel = new SCardChannel(this);

            if (!channel.ConnectDirect())
            {
                return(false);
            }
            bool rc = channel.Control(cctrl, out rctrl);

            channel.DisconnectLeave();
            return(rc);
        }
Example #21
0
        public string[] Descriptions(CardBuffer abAtr)
        {
            string sAtr = abAtr.AsString(" ");

            foreach (KeyValuePair <string, List <string> > entry in AtrDescriptionList)
            {
                if (Regex.IsMatch(sAtr, entry.Key))
                {
                    return(entry.Value.ToArray());
                }
            }

            return(null);
        }
Example #22
0
        public bool Control()
        {
            byte[] r = Control(_cctrl.GetBytes());

            if (r == null)
            {
                return(false);
            }

            _rctrl = null;

            if (r.Length > 0)
            {
                _rctrl = new CardBuffer(r);
            }

            return(true);
        }
Example #23
0
        private bool EmulStop()
        {
            if (ReaderChannel == null)
            {
                return(false);
            }

            if (trace)
            {
                Trace.WriteLine("Stopping NFC card emulation");
            }

            CardBuffer RESP;
            CardBuffer CTRL_LED = new CardBuffer("581E");
            CardBuffer CTRL_BUZ = new CardBuffer("581C");
            CardBuffer CTRL_NFC = new CardBuffer("83100000");

            RESP = ReaderChannel.Control(CTRL_NFC);
            if ((RESP == null) || (RESP.Length < 1) || ((RESP.GetByte(0) != 0x00) && (RESP.GetByte(0) != 0x1D)))
            {
                if (trace)
                {
                    Trace.WriteLine("Control(" + CTRL_NFC.AsString() + ") failed");
                    if (RESP == null)
                    {
                        Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                    }
                    else
                    {
                        Trace.WriteLine("\tResp= " + RESP.AsString());
                    }
                }

                return(false);
            }

            ReaderChannel.Control(CTRL_LED);
            ReaderChannel.Control(CTRL_BUZ);

            return(true);
        }
Example #24
0
        private bool EmulStart()
        {
            if (ReaderChannel == null)
            {
                return(false);
            }

            if (trace)
            {
                Trace.WriteLine("Starting NFC card emulation");
            }

            CardBuffer RESP;
            CardBuffer CTRL = new CardBuffer("83100100");

            RESP = ReaderChannel.Control(CTRL);
            if ((RESP == null) || (RESP.Length < 1) || (RESP.GetByte(0) != 0x00))
            {
                if (trace)
                {
                    Trace.WriteLine("Control(" + CTRL.AsString() + ") failed");
                    if (RESP == null)
                    {
                        Trace.WriteLine("\terr." + ReaderChannel.LastError + " : " + ReaderChannel.LastErrorAsString);
                    }
                    else
                    {
                        Trace.WriteLine("\tResp= " + RESP.AsString());
                    }
                }

                return(false);
            }

            if (debug)
            {
                Trace.WriteLine("=");
            }
            return(true);
        }
        private void StatusChangeMonitor()
        {
            try
            {
                _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context);
                if (_last_error != SCARD.S_SUCCESS)
                {
                    _status_change_callback(null, 0, null);
                    return;
                }

                uint global_notification_state = SCARD.STATE_UNAWARE;

                while (_status_change_running)
                {
                    if (_status_change_context == IntPtr.Zero)
                    {
                        _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context);
                        if (_last_error != SCARD.S_SUCCESS)
                        {
                            _status_change_callback(null, 0, null);
                            return;
                        }
                    }

                    /* Construct the list of readers we'll have to monitor */
                    /* --------------------------------------------------- */
                    bool global_notification_fired = false;
                    int  monitor_count             = 0;

                    if (_auto_update_list)
                    {
                        if (_reader_names != null)
                        {
                            monitor_count = _reader_names.Length;
                            if (monitor_count > 10)
                            {
                                Trace.WriteLine("PC/SC: not able to monitor more than 10 readers (Windows limitation)");
                                monitor_count = 10;
                            }
                        }
                        monitor_count += 1;
                    }
                    else
                    {
                        if (_reader_names == null)
                        {
                            SCARD.ReleaseContext(_status_change_context);
                            _status_change_context = IntPtr.Zero;
                            _status_change_callback(null, 0, null);
                            return;
                        }
                        monitor_count = _reader_names.Length;
                        if (monitor_count > 10)
                        {
                            Trace.WriteLine("PC/SC: not able to monitor more than 10 readers (Windows limitation)");
                            monitor_count = 10;
                        }
                    }

                    SCARD.READERSTATE[] states = new SCARD.READERSTATE[monitor_count];

                    for (int i = 0; i < states.Length; i++)
                    {
                        states[i] = new SCARD.READERSTATE();
                        if (_auto_update_list && (i == 0))
                        {
                            /* Magic string to be notified of reader arrival/removal */
                            states[i].szReader       = "\\\\?PNP?\\NOTIFICATION";
                            states[i].dwCurrentState = global_notification_state;
                        }
                        else
                        {
                            /* Reader name */
                            states[i].szReader       = _reader_names[i - 1];
                            states[i].dwCurrentState = SCARD.STATE_UNAWARE;
                        }
                        states[i].dwEventState = 0;
                        states[i].cbAtr        = 0;
                        states[i].rgbAtr       = null;
                        states[i].pvUserData   = IntPtr.Zero;
                    }

                    /* Now wait for an event */
                    /* --------------------- */

                    while (_status_change_running && !global_notification_fired)
                    {
                        uint rc = SCARD.GetStatusChange(_status_change_context, 250, states, (uint)states.Length);

                        if ((rc == SCARD.E_SERVICE_STOPPED) || (rc == SCARD.E_NO_SERVICE))
                        {
                            Trace.WriteLine("PC/SC: no service");
                            SCARD.ReleaseContext(_status_change_context);
                            _status_change_context = IntPtr.Zero;
                            continue;
                        }

                        if (!_status_change_running)
                        {
                            break;
                        }

                        if (rc == SCARD.E_TIMEOUT)
                        {
                            continue;
                        }

                        if (rc != SCARD.S_SUCCESS)
                        {
                            Trace.WriteLine("PC/SC: monitor failed with error " + rc);

                            _last_error = rc;
                            /* Broadcast a message saying we have a problem! */
                            for (int i = 0; i < states.Length; i++)
                            {
                                states[i].dwEventState = 0 | SCARD.STATE_CHANGED;
                            }
                        }

                        for (int i = 0; i < states.Length; i++)
                        {
                            if ((states[i].dwEventState & SCARD.STATE_CHANGED) != 0)
                            {
                                /* This reader has fired an event */
                                /* ------------------------------ */

                                if (_auto_update_list && (i == 0))
                                {
                                    /* Not a reader but \\\\?PNP?\\NOTIFICATION */
                                    /* ---------------------------------------- */

                                    Trace.WriteLine("PC/SC: the list of readers has changed");

                                    global_notification_fired = true;
                                    global_notification_state = states[0].dwEventState;

                                    SCARD.ReleaseContext(_status_change_context);
                                    _last_error = SCARD.EstablishContext(_scope, IntPtr.Zero, IntPtr.Zero, ref _status_change_context);
                                    if (_last_error != SCARD.S_SUCCESS)
                                    {
                                        _status_change_callback(null, 0, null);
                                        return;
                                    }

                                    /* Refresh the list of readers */
                                    _reader_names = SCARD.GetReaderList(_status_change_context, _groups);

                                    /* Notify the application that the list of readers has changed */
                                    try
                                    {
                                        _status_change_callback(null, global_notification_state & ~SCARD.STATE_CHANGED, null);
                                    }
                                    catch {}
                                }
                                else
                                {
                                    /* This is a reader */
                                    /* ---------------- */

                                    Trace.WriteLine("PC/SC: status of reader " + states[i].szReader + " has changed");

                                    states[i].dwCurrentState = states[i].dwEventState;
                                    if ((states[i].dwCurrentState & SCARD.STATE_IGNORE) != 0)
                                    {
                                        states[i].dwCurrentState = SCARD.STATE_UNAVAILABLE;
                                    }

                                    CardBuffer card_atr = null;

                                    /* Is there a card involved ? */
                                    if ((states[i].dwEventState & SCARD.STATE_PRESENT) != 0)
                                    {
                                        try
                                        {
                                            card_atr = new CardBuffer(states[i].rgbAtr, (int)states[i].cbAtr);
                                        }
                                        catch {}
                                    }

                                    try
                                    {
                                        _status_change_callback(states[i].szReader, states[i].dwEventState & ~SCARD.STATE_CHANGED, card_atr);
                                    }
                                    catch {}
                                }
                            }
                        }
                    }
                }

                SCARD.ReleaseContext(_status_change_context);
                _status_change_context = IntPtr.Zero;
            }
            catch (ThreadInterruptedException) { }             /* Hide Interrupt */
        }
Example #26
0
 protected virtual CardBuffer OnFrame(CardBuffer cmd)
 {
     return(new RAPDU(0x67, 00));
 }
Example #27
0
        protected virtual void UpdateState()
        {
            uint rc;

            _reader_state = SCARD.STATE_UNAWARE;
            _card_atr     = null;

            if (Connected)
            {
                byte[] atr_buffer = new byte[36];
                uint   atr_length = 36;

                uint dummy = 0;

                rc =
                    SCARD.Status(_hCard, IntPtr.Zero, ref dummy,
                                 ref _reader_state, ref _active_protocol, atr_buffer,
                                 ref atr_length);
                if (rc != SCARD.S_SUCCESS)
                {
                    _last_error = rc;
                    return;
                }

                _card_atr = new CardBuffer(atr_buffer, (int)atr_length);
            }
            else
            {
                SCARD.READERSTATE[] states = new SCARD.READERSTATE[1];

                states[0]                = new SCARD.READERSTATE();
                states[0].szReader       = _reader_name;
                states[0].pvUserData     = IntPtr.Zero;
                states[0].dwCurrentState = 0;
                states[0].dwEventState   = 0;
                states[0].cbAtr          = 0;
                states[0].rgbAtr         = null;

                try
                {
                    rc = SCARD.GetStatusChange(_hContext, 0, states, 1);
                }
                catch (ThreadInterruptedException)
                {
                    rc = SCARD.E_CANCELLED;
                }

                if (rc != SCARD.S_SUCCESS)
                {
                    _last_error = rc;
                    return;
                }

                _reader_state = states[0].dwEventState;

                if ((_reader_state & SCARD.STATE_PRESENT) != 0)
                {
                    _card_atr = new CardBuffer(states[0].rgbAtr, (int)states[0].cbAtr);
                }
            }
        }
Example #28
0
 public void Parse(CardBuffer abAtr)
 {
     this.abAtr = abAtr;
     Parse();
 }
Example #29
0
 public void Parse(string sAtr)
 {
     abAtr = new CardBuffer(sAtr);
     Parse();
 }
Example #30
0
 public CardAtrParser(CardBuffer abAtr)
 {
     Parse(abAtr);
 }