jcecard
A virtual OpenPGP smart card implementation that connects to pcscd via local TCP server, made for testing johnnycanencrypt and related desktop applications.
Available/tested features for OpenPGP
- Import RSA4096 and CV25519 keys/subkeys
- Signing operation
- Encryption / decryption operation
- On card CV25519 generation
- On card RSA4096 key generaion
Written but not tested yet in OpenPGP
- Authention (for SSH)
Available/tested features for PIV (via yubico-piv-tool 2.7.2)
- Card status and version information
- PIN verification and PIN change
- Management key authentication (TDES mutual auth)
- Set CHUID (Card Holder Unique Identifier) data object
- Set CCC (Card Capability Container) data object
- On-card ECC P-256 key generation for all slots:
- Slot 9a (PIV Authentication)
- Slot 9c (Digital Signature)
- Slot 9d (Key Management)
- Slot 9e (Card Authentication)
- Self-signed certificate generation
- Certificate import
- Certificate read
- ECDSA signature operations
- ECDH key agreement (key derivation)
- Full ECC workflow (key generation → certificate → signing)
Default credentials
- PIN:
123456 - PUK:
12345678 - Management Key:
010203040506070801020304050607080102030405060708
Using jcecard in CI (GitHub Actions)
Below is an example of how to set up the virtual OpenPGP card in GitHub Actions for testing.
Required System Dependencies
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
pcscd \
libpcsclite-dev \
libpcsclite1 \
pcsc-tools \
gnupg \
gnupg-agent \
scdaemon \
libclang-dev \
nettle-dev \
pkg-config \
build-essential
Install yubico-piv-tool 2.7.2 for PIV related operations/tests
You will need yubico-piv-tool version 2.7.2 for testing the PIV operations.
I have built the package for ubuntu-latest on Github.
- name: Install yubico-piv-tool from kushal's build
run: |
wget https://kushaldas.in/yubico.tar.gz
echo "222b9deb97dcd2ad03f216ac42caea91bd875d6f3e838d3f4a9ab0d01c433c4c yubico.tar.gz" | sha256sum -c -
tar xvf yubico.tar.gz
sudo apt install ./yubico/*.deb
Install Rust and Just
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install just
uses: extractions/setup-just@v2
- name: Make just available for root
run: |
sudo ln -sf $(which just) /usr/local/bin/just
Build the IFD Handler
- name: Build Rust IFD handler
run: |
cd ifd-jcecard
cargo build --release
Set Up Python Environment
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Create Python virtualenv and install dependencies
run: |
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m pip install pexpect pyscard
Install IFD Handler to pcscd
- name: Install IFD handler to pcscd
run: |
just install-ifd
Configure gnupg for Loopback Pinentry
This is required if you want to use gnupg with the virtual card in CI:
- name: Configure gpg-agent for loopback pinentry
run: |
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
echo "disable-ccid" >> ~/.gnupg/scdaemon.conf
gpgconf --kill all || true
Start the Virtual Card Services
- name: Start TCP server and pcscd
run: |
source .venv/bin/activate
# Start TCP server in background
nohup python -m jcecard.tcp_server --debug > /tmp/tcp_server.log 2>&1 &
sleep 2
# Start pcscd in debug mode
sudo /usr/sbin/pcscd --foreground --debug --apdu > /tmp/pcscd_debug.log 2>&1 &
sleep 3
# Verify services are running
pgrep -f tcp_server && echo "TCP server is running"
pgrep pcscd && echo "pcscd is running"
Run Your Tests
- name: Run tests
run: |
source .venv/bin/activate
timeout 600 pytest tests/ -v
Upload Debug Logs on Failure (Optional)
- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: debug-logs
path: |
/tmp/tcp_server.log
/tmp/pcscd_debug.log
retention-days: 5
Default PINs for OpenPGP card
- User PIN:
123456 - Admin PIN:
12345678
Metadata
Release files for jcecard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| jcecard-0.1.0.tar.gz | 54.8 kB | Without provenance | Details for jcecard-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| jcecard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for jcecard-0.1.0-py3-none-any.whl |
Total release size: 114.0 kB
Release files / jcecard-0.1.0.tar.gz
| Download URL | jcecard-0.1.0.tar.gz |
|---|---|
| Size | 54.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b0c932dc50fdcefbf160996e67b63429d038e8dcff4ba8ef58b6281516ea0d17
|
|
BLAKE2b-256 checksum How to use checksums |
02163412a639a4f522e7f7a9d696d00a59844455a246d676be611a516a637531
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / jcecard-0.1.0-py3-none-any.whl
| Download URL | jcecard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 59.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
271adb1cb02a6caf6a2ec13ea6a88432d1acf0c78ec262f9970daf7d7ea3bc46
|
|
BLAKE2b-256 checksum How to use checksums |
b22f2b0112794847a3568efc835640a63c5c59c0753a1a98b3795170e77063ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for jcecard 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.