예제 #1
0
        internal PCSCIso7816Protocol(byte[] atr, PCSCCard card)
        {
            // Reference the reader
            myCard = card;

            // Get the ATR value
            this.Atr = Atr.Parse(atr);

            // Map the PC/SC comms protocol to the appropriate CardFramework protocol
            switch (myCard.CommsProtocol)
            {
            case SCardProtocol.T0:
                CommsProtocol = Iso7816CommsProtocol.T0;
                break;

            case SCardProtocol.T1:
                CommsProtocol = Iso7816CommsProtocol.T1;
                break;

            case SCardProtocol.Raw:
                CommsProtocol = Iso7816CommsProtocol.Raw;
                break;

            default:
                throw PCSCException.ThrowUnsupportedProtocol();
            }
        }
예제 #2
0
        public static IntPtr GetGlobalPci(SCardProtocol protocol)
        {
            string globalPath = @"";

            switch (protocol)
            {
            case SCardProtocol.T0:
                globalPath = "g_rgSCardT0Pci";
                break;

            case SCardProtocol.T1:
                globalPath = "g_rgSCardT1Pci";
                break;

            case SCardProtocol.Raw:
                globalPath = "g_rgSCardRawPci";
                break;

            default:
                throw PCSCException.ThrowByResult(PCSCResult.ProtocolMismatch);
            }

            IntPtr handle = NativeMethods.LoadLibrary("Winscard.dll");
            IntPtr pci    = NativeMethods.GetProcAddress(handle, globalPath);

            NativeMethods.FreeLibrary(handle);
            return(pci);
        }
예제 #3
0
        public void Reconnect(SCardDisposition initialisation)
        {
            PCSCResult result = NativeMethods.SCardReconnect(myHandle, DefaultShareMode, DefaultRequestedProtocols, initialisation, ref myCommsProtocol);

            if (result != PCSCResult.None)
            {
                // Disconnect from the card
                Disconnect();
                throw PCSCException.ThrowByResult(result);
            }
        }
예제 #4
0
        public override RApdu Transceive(CApdu command)
        {
            IntPtr requestPci;

            switch (myCard.CommsProtocol)
            {
            case SCardProtocol.T0:
                requestPci = PCSCApi.SCardPciT0;
                break;

            case SCardProtocol.T1:
                requestPci = PCSCApi.SCardPciT1;
                break;

            default:
                throw PCSCException.ThrowUnsupportedProtocol();
            }

            int responseLength = 1024;

            byte[]     responseBuffer = new byte[responseLength];
            byte[]     cmdBuffer      = command.ToArray();
            PCSCResult result         = NativeMethods.SCardTransmit(myCard.Handle, requestPci, cmdBuffer, cmdBuffer.Length, IntPtr.Zero, responseBuffer, ref responseLength);

            if (PCSCResult.None == result)
            {
                byte[] response = new byte[responseLength];
                Array.Copy(responseBuffer, response, responseLength);

#if DEBUG
                RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer));
                RaiseOnTranscieve("RAPDU> " + Converters.ByteArrayToString(response));
#endif

                return(RApdu.Parse(response));
            }
            else
            {
#if DEBUG
                RaiseOnTranscieve("CAPDU> " + Converters.ByteArrayToString(cmdBuffer));
                RaiseOnTranscieve("RAPDU> Error condition (HRESULT = " + EnumHelper.GetDescription(result) + ")");
#endif
                throw new PCSCException("Communications error.");
            }
        }
예제 #5
0
        internal byte[] GetAttribute(uint attribute)
        {
            PCSCResult result = 0;
            IntPtr     len    = IntPtr.Zero;

            // Get the length required
            result = NativeMethods.SCardGetAttrib(myCard.Handle, attribute, null, ref len);
            if (result != PCSCResult.None)
            {
                throw PCSCException.ThrowByResult(result);
            }

            // Get the value
            byte[] buffer = new byte[len.ToInt32()];
            result = NativeMethods.SCardGetAttrib(myCard.Handle, attribute, buffer, ref len);
            if (result != PCSCResult.None)
            {
                throw PCSCException.ThrowByResult(result);
            }

            return(buffer);
        }
예제 #6
0
        public void Connect(SCardShareMode shareMode = SCardShareMode.Shared)
        {
            PCSCResult result;

            // Are we already connected?
            if (myHandle != IntPtr.Zero)
            {
                return;
            }

            // Establish a new session context for this card
            result = NativeMethods.SCardEstablishContext(SCardScope.User, IntPtr.Zero, IntPtr.Zero, out myContext);
            if (PCSCResult.None != result)
            {
                throw PCSCException.ThrowByResult(result);
            }

            // Connect to the card
            result = NativeMethods.SCardConnect(myContext, myReaderName, shareMode, DefaultRequestedProtocols, ref myHandle, ref myCommsProtocol);

            if (PCSCResult.None != result)
            {
                // Disconnect (this will gracefully handle the context release)
                Disconnect();
                throw PCSCException.ThrowByResult(result);
            }

            // Retrieve our ATR
            byte[]        readerName   = new byte[255];
            uint          readerLen    = 255;
            SCardState    state        = 0;
            SCardProtocol cardProtocol = 0;
            uint          atrLen       = NativeMethods.SCARD_ATR_LENGTH;

            byte[] atr = new byte[atrLen];

            result = NativeMethods.SCardStatus(myHandle, readerName, ref readerLen, out state, out cardProtocol, atr, ref atrLen);
            if (result != PCSCResult.None)
            {
                // Disconnect from the card
                Disconnect();
                throw PCSCException.ThrowByResult(result);
            }


            //
            // Protocol Enumeration
            //
            try
            {
                // Add the default 7816 protocol
                Protocols.Add(new PCSCIso7816Protocol(atr, this));

                // Determine whether this card is contactless or not
                if (SupportsIso14443)
                {
                    // Replace the 7816 protocol with 14443
                    Protocols.Clear();

                    var protocol = new PCSCIso14443AProtocol(atr, this);
                    Protocols.Add(protocol);

                    // Create our OptionalCommands object
                    OptionalCommands = new PCSCOptionalCommands(protocol);

                    //
                    // HACK: Adding a PCSCMifareProtocol to all ISO14443 cards, what
                    //       we should be doing is somehow determining if this card
                    //       supports Mifare or Mifare emulation
                    //
                    Protocols.Add(new PCSCMifareProtocol(this));
                }
            }
            catch (Exception)
            {
                // Disconnect from the card
                Disconnect();
                throw PCSCException.ThrowUnsupportedProtocol();
            }
        }