Giter VIP home page Giter VIP logo

libpcsc-cpp's Introduction

libpcsc-cpp

European Regional Development Fund

NB! Please note that the libpcsc-cpp code was moved to libelectronic-id repository.
We won't be accepting pull requests or responding to issues in this repository anymore. We are happy to accept your proposals in the libelectronic-id repository: https://github.com/web-eid/libelectronic-id.

C++ library for accessing smart cards using the PC/SC API.

Usage

Example how to list available readers, connect to the smart card in first reader and transmit an APDU:

auto readers = listReaders();
auto card = readers[0].connectToCard();
auto command = CommandApdu::fromBytes({0x2, 0x1, 0x3, 0x4});

auto transactionGuard = card->beginTransaction();
auto response = card->transmit(command);

See more examples in tests.

Building

In Ubuntu:

apt install build-essential pkg-config cmake libgtest-dev valgrind libpcsclite-dev
sudo bash -c 'cd /usr/src/googletest && cmake . && cmake --build . --target install'

cd build
cmake .. # optionally with -DCMAKE_BUILD_TYPE=Debug
cmake --build . # optionally with VERBOSE=1

Testing

Build as described above, then, inside the build directory, run:

ctest # or 'valgrind --leak-check=full ctest'

ctest runs tests that use the libscard-mock library to mock PC/SC API calls.

There are also integration tests that use the real operating system PC/SC service, run them inside build directory with:

./libpcsc-cpp-test-integration

Development guidelines

libpcsc-cpp's People

Contributors

counter178 avatar cyb3r4nt avatar kristelmerilain avatar metsma avatar mrts avatar plaes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libpcsc-cpp's Issues

[possible TODO clarification, not really an issue] +4 bytes when reading the length from ASN1 encoded certificate

libpcsc-cpp/src/utils.cpp

Lines 133 to 142 in 0483f24

// Read 2-byte length field at offset 2 and 3.
// TODO: the +4 comes from EstEID example, won't get the full ASN data without this, dig out the
// reason (probably DER footer)
const auto length = size_t((response.data[2] << 8) + response.data[3] + 4);
if (length < 128 || length > 0x0f00) {
// TODO: more specific exception
THROW(Error,
"readDataLengthFromAsn1(): Unexpected data length in DER header: "s
+ std::to_string(length));
}

In the source code there is comment about digging up the reason why the +4 is included in the computation. I have found out it is most probably included because of the first 4 bytes the code uses to actually read the length.

image

In the next step the program usually uses this length to read whole certificate from the card, so the first 4 bytes need to be included, otherwise it would be 4 bytes shorter.

This is not really an issue, but I have been in contact with @mrts who told me to make a comment about it here. Maybe in the future it might confuse people.

Add reference to Reader to SmartCard and delegate SmartCard::atr() to reader.atr

I originally envisioned that libpcsc-cpp could be used in embedded environments where every byte counts and so didn't want to have a copy of the ATR both in Reader and SmartCard, so I used std::move to move it from Reader. Now I think this was an inadequate premature optimization, and SmartCard takes all data that it uses by copy.

I took a second look and I actually think the best way to have only a single copy of the ATR is to add a reference to Reader to SmartCard so that SmartCard::atr() just does return reader.atr. The trick, though, is to assure that the Reader object remains alive, it was originally meant to live on the stack and possibly have shorter lifetime than SmartCard.

Originally posted by @mrts in #8 (comment)

Exception is thrown when SW1/SW2 = 6CXX

Currently, when the status word from the card is 6CXX, an exception is thrown:

if (response.sw1 == ResponseApdu::WRONG_LE_LENGTH) {
THROW(Error, "Wrong LE length (SW1=0x6C) in response, please set LE");
}

When receiving 6CXX, one is supposed to resend the command APDU with Le=XX. However, since an exception is thrown, the ResponseApdu object is not returned to the caller, and as a result the SW2 value cannot be accessed to determine the correct Le.

I think this can be solved by simply removing the code that throws the exception, and let the caller handle it.

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.