Metadata-Version: 2.4
Name: cryptnox_sdk_py
Version: 1.0.4
Summary: Python SDK for managing Cryptnox smart card wallets.
Home-page: https://www.cryptnox.com/
Author: Cryptnox SA
Author-email: info@cryptnox.com
License: LGPL-3.0
Project-URL: Source Code, https://github.com/Cryptnox-Software/cryptnox-sdk-py
Keywords: smartcard,hardware,security,cryptography,nfc
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Hardware :: Universal Serial Bus (USB) :: Smart Card
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp
Requires-Dist: cryptography
Requires-Dist: pyscard
Dynamic: description
Dynamic: description-content-type
Dynamic: license-file
Dynamic: requires-dist

<p align="center">
  <img src="https://github.com/user-attachments/assets/6ce54a27-8fb6-48e6-9d1f-da144f43425a"/>
</p>

<h3 align="center">cryptnox-sdk-py</h3>
<p align="center">Python SDK for managing Cryptnox Hardware Wallet smart cards</p>

<br/>
<br/>
 
[![PyPI version](https://img.shields.io/pypi/v/cryptnox_sdk_py)](https://pypi.org/project/cryptnox_sdk_py)
[![Python versions](https://img.shields.io/pypi/pyversions/cryptnox_sdk_py.svg)](https://pypi.org/project/cryptnox_sdk_py/)
[![License: LGPLv3](https://img.shields.io/badge/License-LGPLv3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
[![Documentation status](https://img.shields.io/badge/docs-latest-blue)](https://cryptnox.github.io/cryptnox-sdk-py/)

`cryptnox_sdk_py` is a Python 3 library used to communicate with the **Cryptnox Smartcard Applet**.
It provides a high-level API to manage **Cryptnox Hardware Wallet** smart cards, including initialization,
secure channel setup, seed management, and cryptographic signing.

---

## Supported hardware

### Cryptnox Hardware Wallet smart cards

Works with Cryptnox Hardware Wallet smart cards running firmware v1.6.0 or later.

| Smart card | Wallet version |
|------|---------------|
| [Crypto Hardware Wallet – Dual Card Set](https://shop.cryptnox.com/product/hardware-wallet-smartcard-dual/) | v1.6.1 |

### Smart card readers

Works with Cryptnox readers and any other standard PC/SC smart card reader:

| Reader | Type | Interface |
|--------|------|-----------|
| [Cryptnox® Smartcard Reader](https://shop.cryptnox.com/product/cryptnox-smartcard-reader/) | Contact (ID-1 + SIM) | USB-A |
| [Compact USB Mini Smartcard Reader](https://shop.cryptnox.com/product/mini-smartcard-reader/) | Contact (ID-1) | USB-A |
| [Cryptnox NFC Contactless Reader](https://shop.cryptnox.com/product/cryptnox-contactless-reader/) | Contactless (NFC/ISO 14443) | USB-C |

---

## Features

- Establish communication with Cryptnox smart cards
- Initialize and manage card lifecycle
- Secure channel authentication and pairing
- Seed generation and restoration (BIP32 / BIP39 compatibility)
- ECDSA secp256k1 signing for blockchain applications

---

## Installation

```bash
pip install cryptnox_sdk_py
```

Or from source:

```bash
git clone https://github.com/cryptnox/cryptnox-sdk-py.git
cd cryptnox-sdk-py
pip install .
```

Requires:
- Python 3.11 – 3.13.7
- PC/SC Smart Card service (`pcscd`) on Linux

On Linux, ensure the PC/SC service is running:

```bash
sudo systemctl start pcscd
sudo systemctl enable pcscd
```

---

## Quick usage examples

### 1. Connect to a Cryptnox Card

```python
import cryptnox_sdk_py
from cryptnox_sdk_py import exceptions

connection = None
try:
    connection = cryptnox_sdk_py.Connection(0)
    card = cryptnox_sdk_py.factory.get_card(connection)
    # Card is loaded and can be used
    print(f"Card serial number: {card.serial_number}")
except exceptions.ReaderException:
    print("Reader not found at index")
except exceptions.CryptnoxException as error:
    # Issue loading the card
    print(error)
finally:
    # Always close the connection when done
    if connection:
        connection.disconnect()

```

### 2. Test PIN code

In the PIN verification example below the card must be initialized before calling verify_pin.

```python
import cryptnox_sdk_py
from cryptnox_sdk_py import exceptions

connection = None
try:
    # Connect to the Cryptnox card first
    connection = cryptnox_sdk_py.Connection(0)  # Connect to card at index 0
    card = cryptnox_sdk_py.factory.get_card(connection)
    
    # Once connected, verify the PIN
    pin_to_test = "1234"  # Example PIN
    card.verify_pin(pin_to_test)
    print("PIN verified successfully. Card is ready for operations.")
except exceptions.ReaderException:
    print("Reader not found at index")
except exceptions.CryptnoxException as error:
    print(f"Error loading card: {error}")
except exceptions.PinException:
    print("Invalid PIN code.")
except exceptions.DataValidationException:
    print("Invalid PIN length or PIN authentication disabled.")
except exceptions.SoftLock:
    print("Card is locked. Please power cycle the card.")
finally:
    # Always close the connection when done
    if connection:
        connection.disconnect()
```

### 3. Generate a new seed

In the example below the card must be init before generating a seed.

```python
import binascii
import cryptnox_sdk_py
from cryptnox_sdk_py import exceptions

PIN = "1234"  # or "" if the card was opened via challenge-response

def main():
    connection = None
    try:
        connection = cryptnox_sdk_py.Connection(0)
        card = cryptnox_sdk_py.factory.get_card(connection)
        
        seed_uid = card.generate_seed(PIN)
        # seed_uid is of type bytes: display in hex for readability
        print("Seed (primary node m) UID:", binascii.hexlify(seed_uid).decode())
    except exceptions.ReaderException:
        print("Reader not found at index")
    except exceptions.CryptnoxException as err:
        print(f"Error loading card: {err}")
    except exceptions.KeyAlreadyGenerated:
        print("A seed is already generated on this card.")
    except exceptions.KeyGenerationException as err:
        print(f"Failed to generate seed: {err}")
    finally:
        # Always close the connection when done
        if connection:
            connection.disconnect()

if __name__ == "__main__":
    main()
```

---

## Documentation

📚 **Full API reference:** https://cryptnox.github.io/cryptnox-sdk-py/

### Building Documentation with Class Diagrams

The project includes automatically generated class diagrams in the documentation.

**Quick Start:**
```bash
# Install dependencies
pip install -r dev-requirements.txt

# Install Graphviz (required for diagrams)
# Windows: Download from https://graphviz.org/download/
# macOS: brew install graphviz
# Linux: sudo apt-get install graphviz

# Build documentation
cd docs
sphinx-build -b html . _build/html
```

**Documentation Guides:**
- **Developer Guide:** [docs/DEVELOPER_GUIDE_DIAGRAMS.md](docs/DEVELOPER_GUIDE_DIAGRAMS.md)

---

## License

`cryptnox-sdk-py` is dual-licensed:

- **LGPL-3.0** for open-source projects and proprietary projects that comply with LGPL requirements  
- **Commercial license** for projects that require a proprietary license without LGPL obligations (see COMMERCIAL.md for details)

For commercial inquiries, contact: contact@cryptnox.com

=========
Changelog
=========

Version 1.0.4 - 2026-04-10
------------------------------------------------------------------------------------------------

Security
^^^^^^^^

- Block ``change_puk()`` when PIN is locked (FINDING-009)
- Pinned vulnerable transitive dev dependencies to safe minimum versions:

  - ``protobuf >= 5.29.6`` (GHSA-7gcm-g887-7qv7, CVSS 8.2)
  - ``python-multipart >= 0.0.22`` (GHSA-59g5-xgcq-4qw3 / GHSA-wp53-j4wj-2cfg, CVSS 8.7/8.6)
  - ``zipp >= 3.19.1`` (GHSA-jfmj-5v4g-7637, CVSS 6.9)

Fixed
^^^^^^^

- Fixed ``verify_pin(None)`` to return 0 when PIN is blocked instead of raising an exception
- Resolved PIN exception handling in BasicG1 card

Changed
^^^^^^^

- Updated ``PinBlockedException`` message for clarity
- Updated ``python_requires`` to ``>=3.11`` (removed upper bound, Python 3.14 now supported)
- Updated README with supported hardware details
- Updated docs configuration with SEO meta tags, favicon, and project details

Added
^^^^^^^

- Added ``examples/README.md`` with overview of available examples and run instructions

CI
^^^

- Fixed OSV-Scanner workflow to scan resolved installed package versions
- Pinned OSV-Scanner action to ``v2.3.5`` for reproducible CI builds

Version 1.0.3 - 2025-12-24
------------------------------------------------------------------------------------------------

Added
^^^^^^^

- Added ``get_manufacturer_certificate()`` method to Base card class with ``hexed`` parameter for flexible certificate retrieval

Changed
^^^^^^^

- Updated ``get_manufacturer_certificate()`` in BasicG1 with multi-page APDU support for full certificate retrieval
- Updated ``manufacturer_certificate()`` function in authenticity module to use the new card-specific method

Version 1.0.2 - 2025-12-08
------------------------------------------------------------------------------------------------

Changes
^^^^^^^

- Updated dependencies to resolve security vulnerabilities
- Improved Python 3 compatibility in cryptographic utilities

Added
^^^^^^^

- Implemented Python code quality scanning CI/CD pipeline using flake8
- Implemented security vulnerability scanning CI/CD pipeline using OSV-Scanner
- Added automated dependency security checks in GitHub Actions workflows

Fixed
^^^^^^^

- Fixed ``AttributeError: module 'cryptnox_sdk_py.cryptos.py2specials' has no attribute 'is_python2'`` error
- Fixed ``TypeError: can't concat str to bytes`` error in ``encode_pubkey()`` function
- Resolved info command issue that prevented retrieving card information
- Fixed Python 3.12 compatibility issues in ``py2specials.py`` module
  - Added proper Python 3 implementation for base 256 encoding/decoding
  - Fixed bytes/string handling in cryptographic operations

Version 1.0.1 - 2025-11-18
------------------------------------------------------------------------------------------------

Changes
^^^^^^^

- Package renamed from ``cryptnoxpy`` to ``cryptnox_sdk_py``
  - All imports must be updated from ``import cryptnoxpy`` to ``import cryptnox_sdk_py``
  - Install using: ``pip install cryptnox-sdk-py``
- Updated README.md with new package name and improved examples
- Updated valid PUK validation logic
- Updated GitHub Actions workflows for documentation and CI/CD
- Modified setup configuration (setup.cfg) for better package management

Added
^^^^^^^

- Added flake8 code quality checks to CI/CD workflow
- Added Sphinx documentation framework
- Implemented ``disconnect()`` method for Connection class to properly close connections
- Added comprehensive exception handling improvements

Fixed
^^^^^^^

- Fixed card not recognized error
- Resolved PUK retries persistence issue
- Fixed flake8 code style errors throughout the codebase

Removed
^^^^^^^

- Removed basic G0 cards references (no longer supported)
- Removed factory hashlib codes
