|
cryptnox-sdk-arduino 1.0.0
Arduino library for Cryptnox Hardware Wallet
|
High-level interface for interacting with a Cryptnox Hardware Wallet over NFC. More...
#include <CryptnoxWallet.h>
Public Member Functions | |
| CryptnoxWallet (CW_NfcTransport &driver, CW_Logger &logger, CW_CryptoProvider &crypto, CW_Platform &platform) | |
| Construct a CryptnoxWallet. | |
| CryptnoxWallet (const CryptnoxWallet &)=delete | |
| CryptnoxWallet & | operator= (const CryptnoxWallet &)=delete |
| bool | begin () |
| Initialize the NFC module via the underlying transport driver. | |
| bool | connect (CW_SecureSession &session) |
| Connect to the Cryptnox card and establish a secure channel. | |
| bool | establishSecureChannel (CW_SecureSession &session) |
| Establish a secure channel (SELECT → certificate → ECDH → mutual auth). | |
| void | disconnect (CW_SecureSession &session) |
| Disconnect and securely clear the session. | |
| bool | getCardInfo (CW_SecureSession &session, CW_CardInfo *info=NULL) |
| Send a secured GET CARD INFO APDU (0x80FA0000) and optionally decode the owner name/email from the response. | |
| bool | verifyPin (CW_SecureSession &session, const uint8_t *pin, uint8_t pinLength) |
| Verify the PIN code on the card. | |
| CW_SignResult | sign (CW_SignRequest &request) |
| Sign a 32-byte digest using a card-resident key. | |
| bool | writeUserData (CW_SecureSession &session, uint8_t slot, const uint8_t *data, uint16_t dataLength) |
| Write data to a user memory slot, paginating in CW_USER_DATA_PAGE_SIZE chunks. | |
Static Public Member Functions | |
| static bool | parseDerSignature (const uint8_t *der, uint8_t derLength, uint8_t *r, uint8_t &rLength, uint8_t *s, uint8_t &sLength) |
| Parse a DER-encoded ECDSA signature to extract raw r and s values. | |
Private Member Functions | |
| bool | isSecureChannelOpen (const CW_SecureSession &session) const |
| bool | printPN532FirmwareVersion () |
| bool | validateSignRequest (const CW_SignRequest &request, CW_SignResult &result) |
| void | buildSignPayload (const CW_SignRequest &request, uint8_t *data, uint16_t &dataLength) |
| bool | sendSignApdu (CW_SignRequest &request, const uint8_t *data, uint16_t dataLength, uint8_t *derResponse, uint16_t &derLength, CW_SignResult &result) |
| bool | extractRawSignature (const uint8_t *derResponse, uint16_t derLength, CW_SignResult &result) |
| void | debugPrintSignature (const uint8_t *signature) |
Private Attributes | |
| CW_Logger & | _logger |
| Logging interface. | |
| CW_Platform & | _platform |
| Platform abstraction (sleep_ms). | |
| CW_SecureChannel | _secure |
| Owned secure channel. | |
High-level interface for interacting with a Cryptnox Hardware Wallet over NFC.
Manages card connection, secure channel establishment (delegated to CW_SecureChannel), PIN verification, transaction signing, user-data writing, and card-info retrieval.
Dependencies are injected by the caller via the constructor. The class itself only talks to the four abstract adapters, keeping the implementation platform-independent.
Definition at line 160 of file CryptnoxWallet.h.
| CryptnoxWallet::CryptnoxWallet | ( | CW_NfcTransport & | driver, |
| CW_Logger & | logger, | ||
| CW_CryptoProvider & | crypto, | ||
| CW_Platform & | platform ) |
Construct a CryptnoxWallet.
| driver | Reference to the NFC transport implementation. |
| logger | Reference to the logging implementation. |
| crypto | Reference to the crypto provider implementation. |
| platform | Reference to the platform abstraction (for sleep_ms). |
Definition at line 27 of file CryptnoxWallet.cpp.
References _logger, _platform, _secure, and platform.
Referenced by CryptnoxWallet(), and operator=().
|
delete |
References CryptnoxWallet().
| bool CryptnoxWallet::begin | ( | ) |
Initialize the NFC module via the underlying transport driver.
Definition at line 36 of file CryptnoxWallet.cpp.
References _secure, and printPN532FirmwareVersion().
|
private |
Definition at line 431 of file CryptnoxWallet.cpp.
References CW_HASH_SIZE, CW_MAX_DERIVE_PATH_LENGTH, CW_MAX_PIN_LENGTH, CW_SIGN_DERIVE_K1, CW_SIGN_DERIVE_R1, CW_SignRequest::derivePath, CW_SignRequest::derivePathLength, CW_SignRequest::hash, CW_SignRequest::hashLength, CW_SignRequest::keyType, CW_SignRequest::pin, CW_SignRequest::pinLessMode, and CW_Utils::safe_memcpy().
Referenced by sign().
| bool CryptnoxWallet::connect | ( | CW_SecureSession & | session | ) |
Connect to the Cryptnox card and establish a secure channel.
Retries the full card activation sequence up to CW_CONNECT_MAX_ATTEMPTS times. On any failure (including transient transport errors) the session is securely wiped before the next attempt so no partial key material can survive a retry (CRIT-04).
| [out] | session | Secure session to populate with derived keys and IV on success; left zero-wiped on failure. |
session is ready for use, false otherwise.session holds valid Kenc / Kmac / IV. session is zero-wiped. Definition at line 44 of file CryptnoxWallet.cpp.
References _logger, _platform, _secure, CW_SecureSession::clear(), CW_CONNECT_MAX_ATTEMPTS, establishSecureChannel(), and F.
|
private |
Definition at line 543 of file CryptnoxWallet.cpp.
References _logger, CW_RAW_SIGNATURE_SIZE, F, and HEX.
Referenced by sign().
| void CryptnoxWallet::disconnect | ( | CW_SecureSession & | session | ) |
Disconnect and securely clear the session.
Wipes any session keys and resets the NFC reader so the next card detection cycle starts from a clean state.
| [in,out] | session | Session to clear. Safe to pass a never-connected or partially-connected session. |
Definition at line 158 of file CryptnoxWallet.cpp.
References _secure, CW_SecureSession::clear(), and isSecureChannelOpen().
| bool CryptnoxWallet::establishSecureChannel | ( | CW_SecureSession & | session | ) |
Establish a secure channel (SELECT → certificate → ECDH → mutual auth).
Lower-level than connect(): runs the full activation sequence once, without the retry loop. Used internally by connect(); exposed for advanced callers that handle retry policy themselves.
| [out] | session | Secure session to populate. |
Definition at line 75 of file CryptnoxWallet.cpp.
References _logger, _secure, CW_CERT_OK, CW_CURVE_SECP256R1, F, HEX, and CW_Utils::secure_wipe().
Referenced by connect().
|
private |
Definition at line 480 of file CryptnoxWallet.cpp.
References _logger, CW_DER_TAG_SEQUENCE, CW_NOK, CW_RAW_SIGNATURE_SIZE, CW_SignResult::errorCode, F, parseDerSignature(), CW_Utils::safe_memcpy(), CW_Utils::secure_wipe(), and CW_SignResult::signature.
Referenced by sign().
| bool CryptnoxWallet::getCardInfo | ( | CW_SecureSession & | session, |
| CW_CardInfo * | info = NULL ) |
Send a secured GET CARD INFO APDU (0x80FA0000) and optionally decode the owner name/email from the response.
| [in,out] | session | Valid secure session. |
| [out] | info | Optional output. When non-NULL and the call succeeds, populated with the card's owner name and email (ASCII, NUL-terminated). |
info is non-NULL) parsing the name/email fields succeeded. Definition at line 165 of file CryptnoxWallet.cpp.
References _logger, _secure, CW_CARD_EMAIL_MAX_LEN, CW_CARD_NAME_MAX_LEN, CW_CardInfo::email, F, isSecureChannelOpen(), CW_CardInfo::name, CW_Utils::safe_memcpy(), and CW_Utils::secure_wipe().
|
private |
Definition at line 370 of file CryptnoxWallet.cpp.
References CW_SecureSession::aesKey, and CW_AESKEY_SIZE.
Referenced by disconnect(), getCardInfo(), validateSignRequest(), verifyPin(), and writeUserData().
|
delete |
References CryptnoxWallet().
|
static |
Parse a DER-encoded ECDSA signature to extract raw r and s values.
| [in] | der | DER-encoded signature bytes. |
| [in] | derLength | DER length. |
| [out] | r | Buffer for r (at least 33 bytes). |
| [out] | rLength | Actual r length written. |
| [out] | s | Buffer for s (at least 33 bytes). |
| [out] | sLength | Actual s length written. |
Definition at line 322 of file CryptnoxWallet.cpp.
References CW_DER_TAG_INTEGER, CW_DER_TAG_SEQUENCE, and CW_Utils::safe_memcpy().
Referenced by extractRawSignature().
|
private |
|
private |
Definition at line 456 of file CryptnoxWallet.cpp.
References _logger, _secure, CW_SIGN_NO_KEY_LOADED, CW_SignResult::errorCode, F, CW_SignRequest::keyType, CW_SignRequest::session, and CW_SignRequest::signatureType.
Referenced by sign().
| CW_SignResult CryptnoxWallet::sign | ( | CW_SignRequest & | request | ) |
Sign a 32-byte digest using a card-resident key.
Builds the SIGN payload (hash || optional BIP32 path || optional PIN), sends it through the secure channel, parses the DER signature returned by the card, and unpacks it into the canonical 64-byte raw form (r[32] || s[32]).
| [in] | request | Sign parameters — must reference a valid secure session, a 32-byte hash, the desired key/signature type, and the PIN (unless pinLessMode is set). |
errorCode is CW_OK and signature holds the 64-byte raw signature. On failure the signature is zeroed and errorCode indicates the cause:| CW_OK | Signature valid. |
| CW_INVALID_SESSION | Secure channel not open. |
| CW_SIGN_KEY_TOO_SHORT | Bad hash buffer / length. |
| CW_SIGN_NO_KEY_LOADED | Card rejected the SIGN APDU. |
| CW_SIGN_PIN_INCORRECT | PIN length out of range. |
| CW_SIGN_KEY_TOO_SHORT_WITH_PINLESS_MODE | PIN-less mode requested but keyType is not CW_SIGN_PINLESS_K1. |
pinLessMode is false the request.pin field must be populated. The destructor of CW_SignRequest securely wipes the PIN, but the caller must zero any other copy. Definition at line 293 of file CryptnoxWallet.cpp.
References buildSignPayload(), CW_HASH_SIZE, CW_MAX_DERIVE_PATH_LENGTH, CW_MAX_PIN_LENGTH, CW_OK, debugPrintSignature(), CW_SignResult::errorCode, extractRawSignature(), CW_Utils::secure_wipe(), sendSignApdu(), CW_SignResult::signature, and validateSignRequest().
|
private |
Definition at line 382 of file CryptnoxWallet.cpp.
References _logger, CW_HASH_SIZE, CW_INVALID_SESSION, CW_MAX_PIN_LENGTH, CW_MIN_PIN_LENGTH, CW_SIGN_KEY_TOO_SHORT, CW_SIGN_KEY_TOO_SHORT_WITH_PINLESS_MODE, CW_SIGN_PIN_INCORRECT, CW_SIGN_PINLESS_K1, CW_SignResult::errorCode, F, CW_SignRequest::hash, CW_SignRequest::hashLength, isSecureChannelOpen(), CW_SignRequest::keyType, CW_SignRequest::pin, CW_SignRequest::pinLessMode, and CW_SignRequest::session.
Referenced by sign().
| bool CryptnoxWallet::verifyPin | ( | CW_SecureSession & | session, |
| const uint8_t * | pin, | ||
| uint8_t | pinLength ) |
Verify the PIN code on the card.
Sends an encrypted VERIFY PIN APDU. The card maintains a try counter: every wrong attempt decrements it, and reaching zero locks the PIN permanently until a successful PUK / re-initialisation flow.
| [in,out] | session | Valid secure session. |
| [in] | pin | PIN bytes (ASCII digits, 4–9 characters). |
| [in] | pinLength | Length of the PIN (must be in [CW_MIN_PIN_LENGTH, CW_MAX_PIN_LENGTH]). |
Definition at line 219 of file CryptnoxWallet.cpp.
References _logger, _secure, CW_MAX_PIN_LENGTH, CW_MIN_PIN_LENGTH, F, isSecureChannelOpen(), CW_Utils::safe_memcpy(), and CW_Utils::secure_wipe().
| bool CryptnoxWallet::writeUserData | ( | CW_SecureSession & | session, |
| uint8_t | slot, | ||
| const uint8_t * | data, | ||
| uint16_t | dataLength ) |
Write data to a user memory slot, paginating in CW_USER_DATA_PAGE_SIZE chunks.
| [in,out] | session | Valid secure session. |
| [in] | slot | User data slot index. |
| [in] | data | Data to write. |
| [in] | dataLength | Total bytes to write. |
Definition at line 241 of file CryptnoxWallet.cpp.
References _logger, _secure, CW_USER_DATA_PAGE_SIZE, F, and isSecureChannelOpen().
|
private |
Logging interface.
Definition at line 328 of file CryptnoxWallet.h.
Referenced by connect(), CryptnoxWallet(), debugPrintSignature(), establishSecureChannel(), extractRawSignature(), getCardInfo(), sendSignApdu(), validateSignRequest(), verifyPin(), and writeUserData().
|
private |
Platform abstraction (sleep_ms).
Definition at line 329 of file CryptnoxWallet.h.
Referenced by connect(), and CryptnoxWallet().
|
private |
Owned secure channel.
Definition at line 330 of file CryptnoxWallet.h.
Referenced by begin(), connect(), CryptnoxWallet(), disconnect(), establishSecureChannel(), getCardInfo(), printPN532FirmwareVersion(), sendSignApdu(), verifyPin(), and writeUserData().