Expand description
PIV (Personal Identity Verification — NIST SP 800-73-4 / FIPS 201) byte layer.
A pure, I/O-free APDU builder + parser layer for the PIV smartcard
application, the same shape as [keyroost_oath] and [keyroost_openpgp]: it
turns intentions into APDU byte vectors and response bytes into typed values,
and performs no card I/O (that lives in keyroost-transport’s
PivSession). PIV is a CCID/APDU applet on YubiKeys (and other PIV cards),
reachable over the same PC/SC layer keyroost already uses.
§Scope
Covers the full management surface: SELECT, GET DATA, the Yubico
version/serial/metadata extensions, PIN-retry querying (the read path), plus
GENERAL AUTHENTICATE (management-key mutual auth and key-slot signing),
GENERATE ASYMMETRIC KEY PAIR, PUT DATA (certificate import), CHANGE
REFERENCE DATA / RESET RETRY COUNTER (PIN/PUK), and the Yubico SET MANAGEMENT
KEY / SET PIN RETRIES / RESET extensions. The block-cipher math for the
management-key challenge/response lives in keyroost-transport (where the
cipher dependency is); this layer stays pure and I/O-free.
Modules§
- spki
- Build a DER
SubjectPublicKeyInfofrom a card-returnedPublicKey. - x509
- Minimal X.509 / PKCS#10 DER assembly for card-signed certificates.
- x509_
parse - Minimal X.509 Subject-DN reader (the inverse of the DER builder in
crate::x509).
Structs§
- Metadata
- Parsed GET METADATA response for a key/PIN reference.
Enums§
- Instruction
- PIV / Yubico-PIV instruction bytes.
- KeyAlg
- Asymmetric key algorithm for GENERATE ASYMMETRIC KEY PAIR.
- MgmtAlg
- Management-key (9B) cipher algorithm. The card stores one of these; auth uses a witness/challenge round whose block size this dictates.
- Parse
Error - Errors from parsing PIV responses.
- PinPolicy
- PIN policy for a generated key (when the slot’s private key may be used).
- Public
Key - A public key returned by GENERATE ASYMMETRIC KEY PAIR.
- Slot
- The four PIV asymmetric key slots, identified by their key reference and the certificate data object that holds the slot’s X.509 certificate.
- Touch
Policy - Touch policy for a generated key (whether the key requires a physical touch).
Constants§
- AID
- PIV card-application AID (the 5-byte RID/PIX prefix; the card matches on it).
Full PIV AID is
A0 00 00 03 08 00 00 10 00 01 00; selecting by the prefix is whatyubikey-piv-tool/ykmando and the card resolves it. - KEY_
REF_ MANAGEMENT - Key reference (P2) for the card-management (9B) key.
- OBJECT_
CHUID - CHUID (Card Holder Unique Identifier) data-object tag.
- PIN_
REF_ APPLICATION - PIN reference (P2) for the PIV application PIN.
- PIN_
REF_ PUK - PIN reference (P2) for the PUK.
- SW_
AUTH_ BLOCKED - Authentication method blocked (PIN/PUK exhausted, or RESET preconditions unmet).
- SW_
MORE_ DATA - First byte of a
61xx“more data available” status word. - SW_
NOT_ FOUND - File/application or object not found (e.g. an empty certificate slot).
- SW_OK
- Status word: success.
- SW_
REFERENCE_ NOT_ FOUND - Reference data (key/PIN) not found.
- SW_
SECURITY_ NOT_ SATISFIED - Security status not satisfied (a write needed an auth/PIN that wasn’t done).
Functions§
- change_
reference - CHANGE REFERENCE DATA: change the PIN (
PIN_REF_APPLICATION) or PUK (PIN_REF_PUK) fromoldtonew. Both are padded to 8 bytes. - encode_
certificate - Wrap a DER X.509 certificate in the PIV cert data-object value:
70 <der> 71 01 <certinfo> FE 00.certinfois 0 for an uncompressed cert. - find_
tlv - Find the value of the first top-level TLV with single-byte
taginbuf. Public so the transport layer can reuse it instead of growing its own BER-TLV walker. - general_
auth_ mutual - GENERAL AUTHENTICATE step 2: return the decrypted witness and present our own
challenge. The card replies with
7C L 82 <bs> <enc(challenge)>, which the host verifies to complete mutual authentication. - general_
auth_ request_ witness - GENERAL AUTHENTICATE step 1: request a witness from the management key. The
card replies with
7C L 80 <bs> <ciphertext>— the witness encrypted under the stored key. - general_
auth_ sign - GENERAL AUTHENTICATE in signing mode: ask a key slot to sign/decrypt
payload(a PKCS#1 block for RSA, or a raw hash for ECC). The card replies with7C L 82 <l> <result>.key_algis the slot’s algorithm (P1),key_refits slot (P2). - generate_
key - GENERATE ASYMMETRIC KEY PAIR in
slot. The card creates a fresh private key and returns its public key (7F49template). Requires prior management-key authentication. - get_
data - GET DATA for the 3-byte object
tag(e.g. a slot’sSlot::cert_object_tagorOBJECT_CHUID). Case 4 — a certificate response is large and arrives via the61xx/ GET RESPONSE loop. - get_
metadata - Yubico GET METADATA for a key/PIN reference (
0x9B,0x80,0x81, or a slot key ref). Requires firmware 5.3+. - get_
response - GET RESPONSE for the
61xxcontinuation loop. - get_
serial - Yubico GET SERIAL (case 2): 4-byte big-endian serial (firmware 5+).
- get_
version - Yubico GET VERSION (case 2): 3-byte
major.minor.patch. - parse_
general_ auth - Extract one inner TLV value (
inner_tag) from a0x7CGENERAL AUTHENTICATE response template — the witness (0x80) from step 1, or the encrypted challenge / signature (0x82) from step 2 / signing. - parse_
metadata - Parse a Yubico GET METADATA response (a flat list of
tag len valueTLVs). - parse_
public_ key - Parse a
0x7F49generated-public-key template into aPublicKey. RSA carries81(modulus) and82(exponent); EC/EdDSA carry86(point). - parse_
serial - Parse a Yubico GET SERIAL reply (4-byte big-endian).
- parse_
version - Parse a Yubico GET VERSION reply (exactly 3 bytes) into
(major, minor, patch). - put_
data - PUT DATA for the 3-byte object
tag, writingvaluewrapped in the0x53template. Used to import a slot certificate (seeencode_certificate). Requires management-key authentication. - read_
ber_ len - Read a BER-TLV length field, returning
(length, header_byte_count). Handles the short form and the0x81/0x82long forms (a PIV cert easily exceeds 255 bytes, so the 2-byte form is required). Indefinite (0x80) and longer forms are deliberately rejected — no PIV object needs them. - reset
- Yubico RESET: wipe the PIV application back to factory defaults. Only succeeds when both the PIN and PUK are blocked.
- select
- SELECT the PIV application by AID (case 4: a trailing
Lerequests the application property template the card returns on success). - set_
management_ key - Yubico SET MANAGEMENT KEY: replace the 9B card-management key.
require_touchgates every future management-key auth on a physical touch. Requires prior management-key authentication. - set_
pin_ retries - Yubico SET PIN RETRIES: set the PIN and PUK retry counts. Resets both to their defaults. Requires management-key auth and a verified PIN.
- unblock_
pin - RESET RETRY COUNTER: unblock the PIN using the PUK, setting a new PIN. Both
pukandnew_pinare padded to 8 bytes. - unwrap_
data_ object - Unwrap a GET DATA response: strip the outer
0x53template and return the inner value bytes (for a certificate object, the70/71/FEcert TLVs). - verify_
pin - VERIFY the application PIN. The PIN is padded to 8 bytes with
0xFFper SP 800-73. The PIN bytes come from the caller and are never logged. - verify_
pin_ status - VERIFY with an empty body — queries the PIN retry counter without consuming a
try. The card answers
63Cx(x tries left),9000(already verified), or6983(blocked). Case 1 (noLc, noLe).