claim169-core
Alpha Software: This library is under active development. APIs may change without notice. Not recommended for production use without thorough testing.
A Rust library for encoding and decoding MOSIP Claim 169 QR codes.
Features
- Encode Claim 169 identity credentials to QR codes (Ed25519, ECDSA P-256)
- Decode Claim 169 identity credentials from QR codes
- Sign with Ed25519 or ECDSA P-256
- Verify signatures (Ed25519, ECDSA P-256)
- Encrypt/Decrypt with AES-GCM (128 or 256 bit)
- Pluggable crypto backends for HSM integration
- Comprehensive security: weak key rejection, decompression limits, timestamp validation
Installation
Add to your Cargo.toml:
[]
= "0.1.0-alpha.3"
Feature Flags
| Feature | Default | Description |
|---|---|---|
software-crypto |
Yes | Software implementations of Ed25519, ECDSA P-256, AES-GCM |
Disable default features to use only custom crypto backends:
[]
= { = "0.1.0-alpha.3", = false }
Encoding (Creating QR Codes)
Ed25519 Signed (Recommended)
use ;
// Assume you already have a 32-byte Ed25519 private key
let private_key: = ;
let claim = default
.with_id
.with_full_name
.with_date_of_birth;
let meta = new
.with_issuer
.with_expires_at;
let qr_data = new
.sign_with_ed25519?
.encode?;
// qr_data is a Base45 string ready for QR code generation
ECDSA P-256 Signed
use Encoder;
// Assume you already have a 32-byte ECDSA P-256 private key
let private_key: = ;
let qr_data = new
.sign_with_ecdsa_p256?
.encode?;
Signed and Encrypted
use Encoder;
// Assume you already have keys
let private_key: = ;
let aes_key: = ;
// Sign first, then encrypt (order enforced by library)
let qr_data = new
.sign_with_ed25519?
.encrypt_with_aes256?
.encode?;
Unsigned (Testing Only)
// Requires explicit opt-in - INSECURE
let qr_data = new
.allow_unsigned
.encode?;
Custom Signer (HSM Integration)
use ;
use iana;
let qr_data = new
.sign_with
.encode?;
Decoding (Reading QR Codes)
With Ed25519 Verification (Recommended)
use Decoder;
let result = new
.verify_with_ed25519?
.decode?;
println!;
println!;
println!;
With ECDSA P-256 Verification
let result = new
.verify_with_ecdsa_p256?
.decode?;
Decrypting Encrypted Credentials
let result = new
.decrypt_with_aes256?
.verify_with_ed25519?
.decode?;
Without Verification (Testing Only)
// Requires explicit opt-in - INSECURE
let result = new
.allow_unverified
.decode?;
With Options
let result = new
.skip_biometrics // Don't parse biometric data
.max_decompressed_bytes // 32KB limit (default: 64KB)
.clock_skew_tolerance // 60 seconds tolerance
.without_timestamp_validation // Disable exp/nbf validation
.verify_with_ed25519?
.decode?;
Custom Verifier (HSM Integration)
use ;
use iana;
let result = new
.verify_with
.decode?;
Data Model
Claim169
The main identity data structure containing:
- Demographics: id, name, date of birth, gender, address, etc.
- Biometrics: fingerprints, iris scans, face images, voice samples
- Unknown fields: Forward-compatible storage for new spec fields
let claim = result.claim169;
// Demographics
println!;
println!;
println!;
// Biometrics
if claim.has_biometrics
CwtMeta
CWT (CBOR Web Token) metadata:
let meta = result.cwt_meta;
println!;
println!;
// Check validity
if meta.is_expired
Error Handling
use ;
match new.allow_unverified.decode
Security
- Always verify signatures in production
- Always sign credentials when encoding
- Weak keys are rejected (all-zeros, small-order points)
- Decompression is limited to prevent zip bomb attacks
- Timestamps are validated by default
- Signing keys are zeroized on drop (where supported)
See SECURITY.md for detailed security information.
Key Generation (Optional Convenience)
You will need cryptographic keys, but in production those are typically provisioned and managed externally (HSM/KMS or secure key management). The examples below are provided for local development and testing convenience; for production, prefer integrating your existing key management and using the Signer/SignatureVerifier traits.
Ed25519 Keys
use Ed25519Signer;
// Generate a new random Ed25519 signing key
let signer = generate;
// Get the public key for verification (32 bytes)
let public_key = signer.public_key_bytes;
// Or get a verifier directly
let verifier = signer.verifying_key;
// You can also create a signer from existing private key bytes (32 bytes)
let private_key_bytes: = ;
let signer = from_bytes?;
ECDSA P-256 Keys
use EcdsaP256Signer;
// Generate a new random ECDSA P-256 signing key
let signer = generate;
// Get the public key in uncompressed SEC1 format (65 bytes)
let public_key = signer.public_key_uncompressed;
// Or get a verifier directly
let verifier = signer.verifying_key;
// You can also create a signer from existing private key bytes (32 bytes)
let private_key_bytes: = ;
let signer = from_bytes?;
AES-GCM Keys
AES keys must be generated using a secure random number generator. The library doesn't provide a key generation method, so use the rand crate:
use RngCore;
// Generate a 32-byte key for AES-256-GCM
let mut aes256_key = ;
thread_rng.fill_bytes;
// Generate a 16-byte key for AES-128-GCM
let mut aes128_key = ;
thread_rng.fill_bytes;
Note: In production, use a cryptographically secure random number generator. The rand crate with OsRng is recommended:
use ;
let mut aes_key = ;
OsRng.fill_bytes;
Building
# Build
# Run tests
# Generate documentation
# Run clippy
License
MIT License - See LICENSE for details.