
Bibliothèque Zig pour module de sécurité matérielle pour les jetons PIV, CAC et YubiKey via PC/SC. Prend en charge les certificats, la gestion du code PIN, la signature et le déchiffrement.
Une bibliothèque de module de sécurité matériel (HSM) pour Zig fournissant un accès PC/SC aux jetons PIV, CAC et YubiKey.
| Aspect | Info |
|---|---|
| Stabilité de l'API | Développement |
| Version Zig | 0.16.0 |
| Plateformes | Linux, macOS, Windows |
| Licence | MIT |
Support PIV (NIST SP 800-73-4)
Support CAC (Common Access Card)
Support YubiKey
Sécurité
anyerror)Opérations parallèles (via thread_pool)
-Denable_tp=true) ; désactiver avec -Denable_tp=falselibpcsclite-dev (Debian/Ubuntu) ou pcsc-lite-devel (Fedora)# Debian/Ubuntu
sudo apt-get install libpcsclite-dev pcscd
# Fedora/RHEL
sudo dnf install pcsc-lite-devel pcsc-lite
# Start the PC/SC daemon
sudo systemctl start pcscd
sudo systemctl enable pcscd
# Build and run unit tests
make
# Or using zig directly
zig build test
# Run simulator integration tests
zig build test -Dintegration_sim=true
# Build examples (requires PC/SC library installed)
zig build examples -Dlink_pcsc=true
| Option | Par défaut | Description | Impact sécurité |
|---|---|---|---|
integration_sim | false | Exécuter les tests d'intégration du simulateur | Aucun |
hsm_hil | false | Exécuter des tests matériel en boucle (nécessite un jeton réel) | Aucun |
link_pcsc | false | Lier la bibliothèque PC/SC pour les exemples | Aucun |
include_simulator | Debug: trueRelease: false | Inclure le simulateur PIV avec des clés de test | CWE-321 : Clés de test en production |
allow_pcsc_env_override | false | RISQUE DE SÉCURITÉ : Permettre la variable d'environnement HSM_PCSC_LIB_PATH | CWE-427 : Chargement de bibliothèque non fiable |
fips | false | Acheminer la crypto sécurisée via le fournisseur FIPS-140-3 lié (zéro surcharge lorsque désactivé) | Aucun |
openssl_path | (non défini) | Préfixe d'installation OpenSSL pour les installations non standard (par ex. /usr/local/ssl) | Aucun |
Avec -Dfips=true, chaque primitive cryptographique sensible à la sécurité transite par un fournisseur FIPS OpenSSL 3.x lié et validé via la couture crypto_backend, et le simulateur obtient des opérations de jeton PIV post-quantique (signature ML-DSA-65, encapsulage/désencapsulage ML-KEM-768) disponibles uniquement en mode FIPS. Le drapeau est désactivé par défaut avec zéro surcharge ; la dépendance fips n'est résolue qu'avec -Dfips=true.
# Default build — std.crypto backend, no OpenSSL link
zig build test
# FIPS build — OpenSSL FIPS provider (run `make deps` from fips first)
OPENSSL_CONF=/usr/local/ssl/ssl/openssl.cnf \
zig build test -Dfips=true -Dopenssl_path=/usr/local/ssl
# Both modes in one shot
make test-dual
Voir docs/FIPS.md pour la conception de la couture, la politique d'exemption FIPS et les opérations de jeton PQC.
Note de sécurité : L'option allow_pcsc_env_override est désactivée par défaut pour prévenir les attaques par injection de bibliothèque malveillante (CWE-427). Activez-la uniquement pour le développement/les tests :
# Production build (secure, env var ignored)
zig build
# Development build (allows HSM_PCSC_LIB_PATH)
zig build -Dallow_pcsc_env_override=true
Lorsqu'activée, les bibliothèques sont validées avant le chargement :
const std = @import("std");
const hsm = @import("hsm");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// List available tokens
const tokens = try hsm.listTokens(allocator, false);
defer {
for (tokens) |*t| t.deinit();
allocator.free(tokens);
}
if (tokens.len == 0) {
std.debug.print("No tokens found\n", .{});
return;
}
// Open the first token
var token = try hsm.openToken(allocator, tokens[0].id, .{});
defer token.close();
// Verify PIN
try token.verifyPin("123456");
// Read certificate
const cert = try token.getCertificate(.authentication);
defer allocator.free(cert);
std.debug.print("Certificate: {} bytes\n", .{cert.len});
// Sign a digest
var digest: [32]u8 = undefined;
std.crypto.hash.sha2.Sha256.hash("Hello, PIV!", &digest, .{});
const signature = try token.sign(.authentication, .ecdsa_p256, &digest);
defer allocator.free(signature);
std.debug.print("Signature: {} bytes\n", .{signature.len});
}
| Type | Description |
|---|---|
TokenKind | Type de jeton : .piv, .cac, .yubikey, .unknown |
TokenInfo | Métadonnées du jeton découvert |
Token | Handle de jeton ouvert pour les opérations |
Slot | Slot de clé : .authentication (9A), .signature (9C), .key_management (9D), .card_auth (9E) |
Algorithm | Algorithme cryptographique : .ecdsa_p256, .ecdsa_p384, .rsa2048_pkcs1v15, etc. |
Capabilities | Drapeaux de capacités du jeton |
PcscScope | Portée du contexte PC/SC : .user (par défaut), .system |
| Fonction | Description |
|---|---|
listTokens(allocator, use_sim) | Liste les jetons disponibles |
openToken(allocator, id, opts) | Ouvre un jeton par son ID |
token.reconnect() | Se reconnecte au jeton et réinitialise l'état d'authentification |
token.verifyPin(pin) | Vérifie le PIN |
token.changePin(old, new) | Change le PIN |
token.unblockPin(puk, new_pin) | Débloque le PIN avec le PUK |
token.getCertificate(slot) | Obtient le certificat encodé en DER |
token.sign(slot, alg, digest) | Signe un condensat |
token.decrypt(slot, alg, ciphertext) | Déchiffre des données |
token.capabilities() | Obtient les capacités du jeton |
token.close() | Ferme la connexion au jeton |
Toutes les opérations renvoient des erreurs de HsmError :
PcscUnavailable, ReaderGone, CardRemoved, TimeoutPinIncorrect, PinLocked, PinLengthInvalidNotSupported, SlotNotFound, AlgorithmNotSupportedInvalidTlv, CertificateNotFound, InvalidDigestLengthSecurityConditionNotSatisfied, AuthenticationFailed