mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
Merge branch 'master' into development-eddsa
This commit is contained in:
commit
016cf61ce0
31 changed files with 359 additions and 109 deletions
50
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
50
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
## Summary
|
||||
|
||||
Describe in plain language what this PR does and why.
|
||||
|
||||
- What problem does it solve?
|
||||
- Is it a bug fix, a new feature, a cleanup/refactor…?
|
||||
|
||||
|
||||
## Details / Impact
|
||||
|
||||
Please include any relevant details:
|
||||
|
||||
- Hardware / board(s) tested:
|
||||
- Firmware / commit/base version:
|
||||
- Security impact (if any):
|
||||
- e.g. changes PIN handling, touches key storage, affects attestation, etc.
|
||||
- Behavior changes:
|
||||
- e.g. new command, new API surface, different defaults, etc.
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
How did you test this change?
|
||||
|
||||
- Steps to reproduce / validate:
|
||||
- Expected vs actual results:
|
||||
- Any logs / traces (please remove secrets):
|
||||
|
||||
|
||||
## Licensing confirmation (required)
|
||||
|
||||
By checking the box below, you confirm ALL of the following:
|
||||
|
||||
- You are the author of this contribution, or you have the right to contribute it.
|
||||
- You have read `CONTRIBUTING.md`.
|
||||
- You agree that this contribution may be merged, used, modified, and redistributed:
|
||||
- under the AGPLv3 Community Edition, **and**
|
||||
- under any proprietary / commercial / Enterprise editions of this project,
|
||||
now or in the future.
|
||||
- You understand that submitting this PR does not create any support obligation,
|
||||
SLA, or guarantee of merge.
|
||||
|
||||
**I confirm the above licensing terms:**
|
||||
|
||||
- [ ] Yes, I agree
|
||||
|
||||
|
||||
## Anything else?
|
||||
|
||||
Optional: mention known limitations, follow-ups, or if this is related to an existing Issue.
|
||||
105
CONTRIBUTING.md
Normal file
105
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Contributing
|
||||
|
||||
Thank you for your interest in contributing to this project.
|
||||
|
||||
This repository is published in two forms:
|
||||
- a Community Edition released under AGPLv3, and
|
||||
- a proprietary / commercial / Enterprise Edition offered to organizations.
|
||||
|
||||
To keep that model legally clean, we need to be explicit about how contributions can be used.
|
||||
|
||||
By opening a pull request, you agree to all of the following:
|
||||
|
||||
1. **You have the right to contribute this code.**
|
||||
You are either the original author of the contribution, or you have obtained the necessary rights/permissions to contribute it under these terms.
|
||||
|
||||
2. **Dual licensing permission.**
|
||||
You agree that your contribution may be:
|
||||
- merged into this repository, and
|
||||
- used, copied, modified, sublicensed, and redistributed
|
||||
- under the AGPLv3 Community Edition, and
|
||||
- under any proprietary / commercial / Enterprise editions of this project,
|
||||
now or in the future.
|
||||
|
||||
In other words: you are granting the project maintainer(s) the right to include
|
||||
your contribution in both the open-source (AGPLv3) codebase and in closed-source /
|
||||
commercially licensed builds, without any additional approval or payment.
|
||||
|
||||
3. **Attribution.**
|
||||
The maintainers may keep or add attribution lines such as
|
||||
`Copyright (c) <your name>` or an AUTHORS / CONTRIBUTORS list.
|
||||
The maintainers may also make changes for clarity, style, security, refactoring,
|
||||
or integration reasons.
|
||||
|
||||
4. **No automatic SLA.**
|
||||
Submitting a pull request does *not* create any support obligation,
|
||||
service-level agreement, warranty, or guarantee that the contribution
|
||||
will be reviewed, merged, or maintained.
|
||||
|
||||
5. **Potential rejection for business reasons.**
|
||||
Features that fall under "Enterprise / Commercial" functionality
|
||||
(e.g. multi-tenant provisioning at scale, centralized audit trails,
|
||||
corporate policy enforcement, attestation/branding flows, key escrow / dual-control,
|
||||
etc.) may be declined for the public AGPLv3 tree even if technically valid.
|
||||
That is normal: some functionality is intentionally offered only
|
||||
under commercial terms.
|
||||
|
||||
If you are not comfortable with these terms, **do not open a pull request yet.**
|
||||
Instead, please open an Issue to start a discussion.
|
||||
|
||||
## How to contribute (technical side)
|
||||
|
||||
### 1. Bug reports / issues
|
||||
- Please include:
|
||||
- hardware / board revision
|
||||
- firmware / commit hash
|
||||
- exact steps to reproduce
|
||||
- expected vs actual behavior
|
||||
- logs / traces if available (strip secrets)
|
||||
|
||||
Security-sensitive findings: do **not** post publicly.
|
||||
Send a short report by email instead so it can be triaged responsibly.
|
||||
|
||||
### 2. Small fixes / minor improvements
|
||||
- You can open a PR directly for:
|
||||
- bug fixes
|
||||
- portability fixes / new board definitions
|
||||
- clarifications in code comments
|
||||
- build / tooling cleanup
|
||||
- documentation of existing behavior
|
||||
|
||||
Please keep PRs focused (one logical change per PR if possible).
|
||||
|
||||
### 3. Larger features / behavior changes
|
||||
- Please open an Issue first and describe:
|
||||
- what problem you're solving (not just "add feature X")
|
||||
- impact on existing flows / security model
|
||||
- any new dependencies
|
||||
|
||||
This helps avoid doing a bunch of work on something that won't be accepted
|
||||
in the Community Edition.
|
||||
|
||||
### 4. Coding style / security posture
|
||||
- Aim for clarity and small, auditable changes. This code runs in places
|
||||
where secrets live.
|
||||
- No debug backdoors, no "just for testing" shortcuts left enabled.
|
||||
- Keep external dependencies minimal and license-compatible
|
||||
(MIT / Apache 2.0 / similarly permissive is usually fine).
|
||||
|
||||
### 5. Commit / PR format
|
||||
- Use descriptive commit messages ("Fix PIN retry counter wrap" is better than "fix stuff").
|
||||
- In the PR description, please include a short summary of what was changed and why.
|
||||
- At the bottom of the PR description, **copy/paste and confirm the licensing line below**:
|
||||
|
||||
> I confirm that I have read `CONTRIBUTING.md` and I agree that this contribution may be used under both the AGPLv3 Community Edition and any proprietary / commercial / Enterprise editions of this project, now or in the future.
|
||||
|
||||
A PR without that confirmation may be delayed or closed without merge.
|
||||
|
||||
## Thank you
|
||||
|
||||
This project exists because people build on it, break it, fix it,
|
||||
and push it into places it wasn't originally designed to go.
|
||||
|
||||
Whether you are here for research, hacking on hardware,
|
||||
rolling out secure keys for a team, or building a commercial product:
|
||||
thank you for helping improve it.
|
||||
116
ENTERPRISE.md
Normal file
116
ENTERPRISE.md
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# Enterprise / Commercial Edition
|
||||
|
||||
This project is offered under two editions:
|
||||
|
||||
## 1. Community Edition (FOSS)
|
||||
|
||||
The Community Edition is released under the GNU Affero General Public License v3 (AGPLv3).
|
||||
|
||||
Intended for:
|
||||
- individual users and researchers
|
||||
- evaluation / prototyping
|
||||
- internal lab / security testing
|
||||
|
||||
You are allowed to:
|
||||
- read and study the source code
|
||||
- modify it
|
||||
- run it internally
|
||||
|
||||
Obligations under AGPLv3:
|
||||
- If you distribute modified firmware/binaries/libraries to third parties, you must provide the corresponding source code of your modifications.
|
||||
- If you run a modified version of this project as a network-accessible service (internal or external), you must offer the source code of those modifications to the users of that service.
|
||||
- No warranty, no support, no SLA.
|
||||
- Enterprise features (bulk provisioning, multi-user policy enforcement, device inventory / revocation, corporate PIN rules, custom attestation/identity, etc.) are NOT included.
|
||||
|
||||
The Community Edition will continue to exist.
|
||||
|
||||
## 2. Enterprise / Commercial Edition
|
||||
|
||||
The Enterprise / Commercial Edition is a proprietary license for organizations that need to:
|
||||
|
||||
- deploy this in production at scale (multiple devices / multiple users / multiple teams)
|
||||
- integrate it into their own physical product or appliance
|
||||
- run it as an internal service (VM / container / private cloud "HSM / auth backend") for multiple internal teams or tenants
|
||||
- enforce internal security policy (admin vs user roles, mandatory PIN rules, secure offboarding / revocation)
|
||||
- avoid any AGPLv3 disclosure obligations for their own modifications and integration code
|
||||
|
||||
### What the Enterprise Edition provides
|
||||
|
||||
**Base license package (always included):**
|
||||
- **Commercial license (proprietary).**
|
||||
You may run and integrate the software/firmware in production — including virtualized / internal-cloud style deployments — without being required to disclose derivative source code under AGPLv3.
|
||||
- **Official signed builds.**
|
||||
You receive signed builds from the original developer so you can prove integrity and provenance.
|
||||
- **Onboarding call (up to 1 hour).**
|
||||
A live remote session to get you from "we have it" to "it’s actually running in our environment" with minimal guesswork.
|
||||
|
||||
**Optional enterprise components (available on demand, scoped and priced per customer):**
|
||||
- **Production / multi-user readiness.**
|
||||
Permission to operate the system with multiple users, multiple devices and multiple teams in real environments.
|
||||
- **Bulk / fleet provisioning.**
|
||||
Automated enrollment for many tokens/devices/users at once (CSV / directory import), scripted onboarding of new users, initial PIN assignment / reset workflows, and role-based access (admin vs user).
|
||||
- **Policy & lifecycle tooling.**
|
||||
Corporate PIN policy enforcement, per-user / per-team access control, device inventory / traceability, and secure revocation / retirement when someone leaves.
|
||||
- **Custom attestation / per-organization identity.**
|
||||
Per-company certificate chains and attestation keys so devices can prove "this token/HSM is officially ours," including anti-cloning / unique device identity for OEM and fleet use.
|
||||
- **Virtualization / internal cloud deployment support.**
|
||||
Guidance and components to run this as an internal service (VM, container, private-cloud HSM/auth backend) serving multiple internal teams or tenants under your brand.
|
||||
- **Post-quantum (PQC) key material handling.**
|
||||
Integration/roadmap support for PQC algorithms (auth / signing) and secure PQC key storage inside the device or service.
|
||||
- **Hierarchical deterministic key derivation (HD).**
|
||||
Wallet-style hierarchical key trees (BIP32-like concepts adapted to this platform) for issuing per-user / per-tenant / per-purpose subkeys without exporting the root secret — e.g. embedded wallet logic, tenant isolation, firmware signing trees, large fleets.
|
||||
- **Cryptographically signed audit trail / tamper-evident event logging.**
|
||||
High-assurance logging of sensitive actions (key use, provisioning, PIN resets, revocations) with integrity protection for forensic / compliance needs.
|
||||
- **Dual-control / two-person approval ("four-eyes").**
|
||||
Require multi-party authorization for high-risk actions such as firmware signing, key export, or critical configuration changes — standard in high-assurance / regulated environments.
|
||||
- **Secure key escrow / disaster recovery design.**
|
||||
Split-secret or escrowed backup strategies so you don’t lose critical signing keys if a single admin disappears or hardware is lost.
|
||||
- **Release-signing / supply-chain hardening pipeline.**
|
||||
Reference tooling and process so every production firmware/binary is signed with hardware-backed keys, proving origin and preventing tampering in transit or at manufacturing.
|
||||
- **Policy-locked hardened mode ("FIPS-style profile").**
|
||||
Restricted algorithms, debug disabled, no raw key export, tamper-evident configuration for regulated / high-assurance deployments.
|
||||
- **Priority support / security response SLA.**
|
||||
A direct line and guaranteed response window for production-impacting security issues.
|
||||
- **White-label demo / pre-sales bundle.**
|
||||
Branded demo firmware + safe onboarding script so you can show "your product" to your own customers without exposing real production secrets.
|
||||
|
||||
These components are NOT automatically bundled. They are available case-by-case depending on your use case and are priced separately.
|
||||
|
||||
### Licensing models
|
||||
|
||||
- **Internal Use License**
|
||||
Internal production use within one legal entity (your company), including internal private cloud / virtualized deployments for multiple internal teams.
|
||||
Optional enterprise components can be added as needed.
|
||||
|
||||
- **OEM / Redistribution / Service License**
|
||||
Integration into a product/appliance you ship to customers, OR operating this as a managed service / hosted feature for external clients or third parties.
|
||||
Optional enterprise components (attestation branding, PQC support, HD key derivation, multi-tenant service hardening, audit trail, etc.) can be added as required.
|
||||
|
||||
Pricing depends on scope, fleet size, number of users/tenants, regulatory requirements, and which optional components you select.
|
||||
|
||||
### Request a quote
|
||||
|
||||
Email: pol@henarejos.me
|
||||
Subject: `ENTERPRISE LICENSE <your company name>`
|
||||
|
||||
Please include:
|
||||
- Company name and country
|
||||
- Intended use:
|
||||
- Internal private deployment
|
||||
- OEM / external service to third parties
|
||||
- Approximate scale (number of devices/tokens, number of users/tenants)
|
||||
- Which optional components you are interested in (bulk provisioning, policy & lifecycle tooling, attestation branding / anti-cloning, virtualization/cloud, PQC, HD key derivation, audit trail, dual-control, key escrow, supply-chain signing, hardened mode, SLA, white-label demo)
|
||||
|
||||
You will receive:
|
||||
1. A short commercial license agreement naming your company.
|
||||
2. Access to the base package (and any optional components agreed).
|
||||
3. Scheduling of the onboarding call.
|
||||
|
||||
## Why Enterprise exists
|
||||
|
||||
- Companies often need hardware-backed security (HSM, FIDO2, OpenPGP, etc.) under their own control, but cannot or will not open-source their internal security workflows.
|
||||
- They also need multi-user / fleet-management features that hobby users do not.
|
||||
- The commercial license funds continued development, maintenance and new hardware support.
|
||||
|
||||
The Community Edition remains AGPLv3.
|
||||
The Enterprise Edition is for production, scale, and legal clarity.
|
||||
26
README.md
26
README.md
|
|
@ -366,12 +366,32 @@ This project is available under two editions:
|
|||
- run this in production with multiple users/devices,
|
||||
- integrate it into their own product/appliance,
|
||||
- enforce corporate policies (PIN policy, admin/user roles, revocation),
|
||||
- deploy it as an internal virtualized / cloud-style service,
|
||||
- and *not* be required to publish derivative source code.
|
||||
- Includes access to enterprise-only features (bulk provisioning, multi-user policy controls, device inventory & revocation, custom attestation/identity), official signed builds, and an onboarding call.
|
||||
- Base package includes:
|
||||
- commercial license (no AGPLv3 disclosure obligation for your modifications / integration)
|
||||
- onboarding call
|
||||
- access to officially signed builds
|
||||
- Optional / on-demand enterprise components that can be added case-by-case:
|
||||
- ability to operate in multi-user / multi-device environments
|
||||
- device inventory, traceability and secure revocation/offboarding
|
||||
- custom attestation, per-organization device identity / anti-cloning
|
||||
- virtualization / internal "HSM or auth backend" service for multiple teams or tenants
|
||||
- post-quantum (PQC) key material handling and secure PQC credential storage
|
||||
- hierarchical deterministic key derivation (HD wallet–style key trees for per-user / per-tenant keys, firmware signing trees, etc.)
|
||||
- cryptographically signed audit trail / tamper-evident logging
|
||||
- dual-control / two-person approval for high-risk operations
|
||||
- secure key escrow / disaster recovery strategy
|
||||
- release-signing / supply-chain hardening toolchain
|
||||
- policy-locked hardened mode ("FIPS-style profile")
|
||||
- priority security-response SLA
|
||||
- white-label demo / pre-sales bundle
|
||||
|
||||
Typical licensing models:
|
||||
- Internal use (within one legal entity).
|
||||
- Redistribution / OEM (shipping this as part of your product).
|
||||
- Internal use (single legal entity, including internal private cloud / virtualized deployments).
|
||||
- OEM / Redistribution / Service (ship in your product OR offer it as a service to third parties).
|
||||
|
||||
These options are scoped and priced individually depending on which components you actually need.
|
||||
|
||||
For commercial licensing and enterprise features, email pol@henarejos.me
|
||||
Subject: `ENTERPRISE LICENSE <your company name>`
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
VERSION_MAJOR="5"
|
||||
VERSION_MINOR="6"
|
||||
VERSION_MAJOR="6"
|
||||
VERSION_MINOR="0"
|
||||
NO_EDDSA=0
|
||||
SUFFIX="${VERSION_MAJOR}.${VERSION_MINOR}"
|
||||
#if ! [[ -z "${GITHUB_SHA}" ]]; then
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 8f907b25ba28cea4f8312e627862352fc012a8a2
|
||||
Subproject commit c1cc33fd9d6b4c2c8fb18f0254130e37f978724b
|
||||
|
|
@ -10,6 +10,8 @@ CONFIG_PARTITION_TABLE_CUSTOM=y
|
|||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv"
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||
CONFIG_WL_SECTOR_SIZE_512=y
|
||||
CONFIG_WL_SECTOR_MODE_PERF=y
|
||||
COMPILER_OPTIMIZATION="Performance"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "pico_keys.h"
|
||||
#include "usb.h"
|
||||
#include "random.h"
|
||||
#include "version.h"
|
||||
|
||||
const uint8_t sc_hsm_aid[] = {
|
||||
11,
|
||||
|
|
@ -44,6 +45,8 @@ const uint8_t *dev_name = NULL;
|
|||
uint16_t dev_name_len = 0;
|
||||
|
||||
uint8_t PICO_PRODUCT = 1;
|
||||
uint8_t PICO_VERSION_MAJOR = HSM_VERSION_MAJOR;
|
||||
uint8_t PICO_VERSION_MINOR = HSM_VERSION_MINOR;
|
||||
|
||||
static int sc_hsm_process_apdu();
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef __VERSION_H_
|
||||
#define __VERSION_H_
|
||||
|
||||
#define HSM_VERSION 0x0506
|
||||
#define HSM_VERSION 0x0600
|
||||
|
||||
#define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff)
|
||||
#define HSM_VERSION_MINOR (HSM_VERSION & 0xff)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@ from binascii import unhexlify
|
|||
|
||||
DEFAULT_DKEK = [0x1] * 32
|
||||
|
||||
TERM_CERT = unhexlify('7F2181E57F4E819E5F290100421045535049434F48534D445630303030317F494F060A04007F00070202020203864104F571E53AA8E75C929D925081CF0F893CB5991D48BD546C1A3F22199F037E4B12D601ACD91C67C88D3C5B3D04C08EC0A372485F7A248E080EE0C6237C1B075E1C5F201045535049434F48534D54525A474E50327F4C0E060904007F0007030102025301005F25060203000300055F24060204000300045F374041BF5E970739135770DBCC5DDA81FFD8B13419A9257D44CAF8404267C644E8F435B43F5E57EB2A8CF4B198045ACD094E0CB34E6217D9C8922CFB9BBEFD4088AD')
|
||||
DICA_CERT = unhexlify('7F2181E97F4E81A25F290100421045535049434F48534D434130303030317F494F060A04007F0007020202020386410421EE4A21C16A10F737F12E78E5091B266612038CDABEBB722B15BF6D41B877FBF64D9AB69C39B9831B1AE00BEF2A4E81976F7688D45189BB232A24703D8A96A55F201045535049434F48534D445630303030317F4C12060904007F000703010202530580000000005F25060202000801085F24060203000601045F37403F75C08FFFC9186B56E6147199E82BFC327CEEF72495BC567961CD54D702F13E3C2766FCD1D11BD6A9D1F4A229B76B248CEB9AF88D59A74D0AB149448705159B')
|
||||
TERM_CERT = unhexlify('7f2181e57f4e819e5f290100421045535049434f48534d445630303030327f494f060a04007f000702020202038641043400e4f42ea8b78b2ab58d24c8297a4b1c13a73a631b531e58d0efb60d70dd6666c8fce4130e9b15ffa4ad29708d32764ac4b0cc0e5301898522f4c735f5a90d5f201045535049434f48534d54524c524134437f4c0e060904007f0007030102025301005f25060205010102085f24060206010102085f3740569f6fe91796f95fa77ecdb680468417eed7b4e00ccc2e091a6b56389213f913c4cf91da96fbcb12d363fead30a5598f737975d58b5170b7f45e9e87ec546883')
|
||||
DICA_CERT = unhexlify('7f2181e97f4e81a25f290100421045535049434f48534d434130303030327f494f060a04007f00070202020203864104e66b473ec328caf39eaed840f9c7a4ba237e1dd19004861fa3f4f134bd2d5ea5f71c6c2e6321add4c8a7793ba41119c5783f48a5d9dfc0898d9ae9e7b14da8d65f201045535049434f48534d445630303030327f4c12060904007f000703010202530580000000045f25060205000400065f24060206000400065f3740a645594c6c338cd6bda6cad039cee54fd822b1011c0af1e4e3a2a6d03d43bdbb8be68a66a8757e7b1f963589bdd80d8e65de5055b722609041ec63f0498ddc8b')
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ RUN apt install -y libccid \
|
|||
cmake \
|
||||
vsmartcard-vpcd \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN pip3 install pytest pycvc cryptography pyscard==2.2.1 base58
|
||||
RUN pip3 install pytest pycvc cryptography base58
|
||||
WORKDIR /
|
||||
RUN git clone https://github.com/OpenSC/OpenSC
|
||||
WORKDIR /OpenSC
|
||||
RUN git checkout tags/0.25.1
|
||||
RUN git checkout tags/0.26.1
|
||||
RUN ./bootstrap
|
||||
RUN ./configure --enable-openssl
|
||||
RUN make -j `nproc`
|
||||
|
|
@ -37,7 +37,9 @@ RUN make clean
|
|||
RUN ldconfig
|
||||
WORKDIR /
|
||||
RUN git clone https://github.com/polhenarejos/pypicohsm.git
|
||||
RUN pip3 install -e pypicohsm
|
||||
WORKDIR /pypicohsm
|
||||
RUN pip3 install .
|
||||
WORKDIR /
|
||||
RUN git clone https://github.com/CardContact/sc-hsm-embedded
|
||||
WORKDIR /sc-hsm-embedded
|
||||
RUN autoreconf -fi
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ def test_select(device):
|
|||
device.select_applet()
|
||||
|
||||
def test_initialization(device):
|
||||
device.initialize()
|
||||
device.initialize(no_dev_cert=True)
|
||||
|
||||
def test_termca(device):
|
||||
data = device.get_termca()
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@
|
|||
import pytest
|
||||
import hashlib
|
||||
from const import DEFAULT_DKEK
|
||||
from picohsm import APDUResponse, SWCodes
|
||||
from picokey import APDUResponse, SWCodes
|
||||
from picohsm.const import DEFAULT_DKEK_SHARES
|
||||
|
||||
KEY_DOMAINS = 3
|
||||
TEST_KEY_DOMAIN = 1
|
||||
|
||||
def test_key_domains(device):
|
||||
device.initialize(key_domains=KEY_DOMAINS)
|
||||
device.initialize(key_domains=KEY_DOMAINS, no_dev_cert=True)
|
||||
for k in range(KEY_DOMAINS):
|
||||
kd = device.get_key_domain(key_domain=k)
|
||||
assert('error' in kd)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from picohsm.const import DEFAULT_DKEK_SHARES, DEFAULT_PIN, DEFAULT_RETRIES
|
|||
from const import DEFAULT_DKEK
|
||||
|
||||
def test_dkek(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
device.login(DEFAULT_PIN)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
assert('dkek' in resp)
|
||||
|
|
|
|||
|
|
@ -18,22 +18,22 @@
|
|||
"""
|
||||
|
||||
import pytest
|
||||
from picohsm import APDUResponse, SWCodes
|
||||
from picokey import APDUResponse, SWCodes
|
||||
from picohsm.const import DEFAULT_PIN, DEFAULT_RETRIES
|
||||
|
||||
WRONG_PIN = '112233'
|
||||
|
||||
def test_pin_init_retries(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, no_dev_cert=True)
|
||||
retries = device.get_login_retries()
|
||||
assert(retries == DEFAULT_RETRIES)
|
||||
|
||||
def test_pin_login(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, no_dev_cert=True)
|
||||
device.login(DEFAULT_PIN)
|
||||
|
||||
def test_pin_retries(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, no_dev_cert=True)
|
||||
device.login(DEFAULT_PIN)
|
||||
|
||||
for ret in range(DEFAULT_RETRIES-1):
|
||||
|
|
@ -45,7 +45,7 @@ def test_pin_retries(device):
|
|||
device.login(WRONG_PIN)
|
||||
assert(e.value.sw == SWCodes.SW_PIN_BLOCKED)
|
||||
|
||||
device.initialize(retries=DEFAULT_RETRIES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, no_dev_cert=True)
|
||||
retries = device.get_login_retries()
|
||||
assert(retries == DEFAULT_RETRIES)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import pytest
|
|||
from picohsm import KeyType, DOPrefixes
|
||||
|
||||
def test_gen_initialize(device):
|
||||
device.initialize()
|
||||
device.initialize(no_dev_cert=True)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"curve", ['secp192r1', 'secp256r1', 'secp384r1', 'secp521r1', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1', 'secp192k1', 'secp256k1', 'curve25519', 'curve448', 'ed25519', 'ed448']
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
|||
from const import DEFAULT_DKEK
|
||||
|
||||
def test_prepare_dkek(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
kcv = hashlib.sha256(b'\x00'*32).digest()[:8]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ from picohsm.const import DEFAULT_RETRIES, DEFAULT_DKEK_SHARES
|
|||
from const import DEFAULT_DKEK
|
||||
|
||||
def test_prepare_dkek(device):
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
kcv = hashlib.sha256(b'\x00'*32).digest()[:8]
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
"""
|
||||
|
||||
import pytest
|
||||
from picohsm import KeyType, DOPrefixes, APDUResponse, SWCodes
|
||||
from picohsm import KeyType, DOPrefixes
|
||||
from picokey import APDUResponse, SWCodes
|
||||
from binascii import hexlify
|
||||
import hashlib
|
||||
from const import DEFAULT_DKEK
|
||||
|
|
@ -28,7 +29,7 @@ from cryptography.hazmat.primitives.asymmetric import ec
|
|||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
def test_initialize(device):
|
||||
device.initialize(key_domains=1)
|
||||
device.initialize(key_domains=1, no_dev_cert=True)
|
||||
assert(device.get_key_domains() == 1)
|
||||
|
||||
device.set_key_domain(key_domain=0, total=2)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from const import DEFAULT_DKEK
|
|||
MESSAGE = b'a secret message'
|
||||
|
||||
def test_prepare_aes(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ import pytest
|
|||
import os
|
||||
from cryptography.hazmat.primitives.ciphers import aead
|
||||
import cryptography.exceptions
|
||||
from picohsm import APDUResponse, DOPrefixes, EncryptionMode, SWCodes
|
||||
from picohsm import DOPrefixes, EncryptionMode
|
||||
from picokey import APDUResponse, SWCodes
|
||||
from picohsm.const import DEFAULT_DKEK_SHARES
|
||||
from const import DEFAULT_DKEK
|
||||
from binascii import hexlify
|
||||
|
|
@ -30,7 +31,7 @@ MESSAGE = b'a secret message'
|
|||
AAD = b'this is a tag for AAD'
|
||||
|
||||
def test_prepare_chachapoly(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@
|
|||
import pytest
|
||||
import os
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes, aead
|
||||
import cryptography.exceptions
|
||||
from picohsm import APDUResponse, DOPrefixes, EncryptionMode, SWCodes, AES
|
||||
from picohsm import EncryptionMode, AES
|
||||
from picohsm.const import DEFAULT_DKEK_SHARES
|
||||
from const import DEFAULT_DKEK
|
||||
from binascii import hexlify
|
||||
|
|
@ -30,7 +29,7 @@ MESSAGE = b'a secret message'
|
|||
AAD = b'this is a tag for AAD'
|
||||
|
||||
def test_prepare_aes(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ from const import DEFAULT_DKEK
|
|||
MESSAGE = b'a secret message'
|
||||
|
||||
def test_prepare_aes(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from picohsm import DOPrefixes
|
|||
INFO = b'info message'
|
||||
|
||||
def test_prepare_kd(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from picohsm import DOPrefixes
|
|||
INFO = b'info message'
|
||||
|
||||
def test_prepare_kd(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from picohsm import DOPrefixes
|
|||
INFO = b'shared message'
|
||||
|
||||
def test_prepare_kd(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,20 +21,20 @@ import pytest
|
|||
from binascii import unhexlify, hexlify
|
||||
from cvc.certificates import CVC
|
||||
from picohsm.utils import int_to_bytes
|
||||
from picohsm import APDUResponse, SWCodes
|
||||
from picokey import APDUResponse, SWCodes
|
||||
from const import TERM_CERT, DICA_CERT
|
||||
from cryptography.hazmat.primitives.asymmetric import ec, utils
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
||||
AUT_KEY = unhexlify('0A40E11E672C28C558B72C25D93BCF28C08D39AFDD5A1A2FD3BAF7A6B27F0C2E')
|
||||
AUT_KEY = unhexlify('579A995BD7BA35AD3D3968940FA4CDA34116E121A8AC01396234DAFB132B3FD7')
|
||||
aut_pk = ec.derive_private_key(int.from_bytes(AUT_KEY, 'big'), ec.BrainpoolP256R1())
|
||||
AUT_PUK = unhexlify('678201ed7f218201937f4e82014b5f290100421045535049434f48534d54525a474e50327f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a78641040cc18ce246da678239af0913a1579dda58c07be404da4a65327794fac93f57a333267979905b5d046da7020226cc4e5fc477e8fc651a0cf87095259aafa88e648701015f201045535049434f48534d54525a474e50325f37401fc90bdab2a58c3cd25f18a90baa2c21d3d087002ba240fb274ff066759297f79e130053d902d637a448c8cdcd0670fe8ebcc06d8a3ee82079f08d1ff8660393421045535049434f48534d54525a474e50325f3740e24e7e23eae3c78f9fa88391004369a293c43ef99e2279170983e1dbe707fbf0382d09de3e60ef1addd2f055947c3efcef17926065ddb7a031f4905da474ed1d')
|
||||
AUT_PUK = unhexlify('678201ed7f218201937f4e82014b5f290100421045535049434f48534d54524c524134437f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7864104a8217de2cec275cdf9dcda68128aff6061199291532545ab394e2554015962e16d568012a9d01b3da60d062aeed11356467fa3af9ebf9aad3d2933ebb9d86e0f8701015f201045535049434f48534d54524c524134435f374022d9f4480995e8370f8377e8bd4a63547be7740f7836456de5196839c6689540889acd573338d68bdea3db2e31c8dd00e670a4bcccdef497a156c39170d3c837421045535049434f48534d54524c524134435f374014445d219facb3bb745867d945e46526a2a6d03441dba52911d8f9483abbe4272a0beee7cecc69c661f3459c9b5431719ebf7e11f93d903a2cf705899eb4b631')
|
||||
|
||||
|
||||
term_chr = CVC().decode(TERM_CERT).chr()
|
||||
|
||||
def test_initialize(device):
|
||||
device.initialize(puk_auts=1, puk_min_auts=1)
|
||||
device.initialize(puk_auts=1, puk_min_auts=1, no_dev_cert=False)
|
||||
device.logout()
|
||||
|
||||
def test_register_puk(device):
|
||||
|
|
@ -102,7 +102,7 @@ def test_enumerate_puk_1(device):
|
|||
assert(puks[0]['status'] == 0)
|
||||
|
||||
def test_enumerate_puk_2(device):
|
||||
device.initialize(puk_auts=2, puk_min_auts=1)
|
||||
device.initialize(puk_auts=2, puk_min_auts=1, no_dev_cert=True)
|
||||
puks = device.enumerate_puk()
|
||||
assert(len(puks) == 2)
|
||||
assert(puks[0]['status'] == -1)
|
||||
|
|
@ -115,7 +115,7 @@ def test_enumerate_puk_2(device):
|
|||
assert(puks[1]['status'] == -1)
|
||||
|
||||
def test_register_more_puks(device):
|
||||
device.initialize(puk_auts=2, puk_min_auts=1)
|
||||
device.initialize(puk_auts=2, puk_min_auts=1, no_dev_cert=True)
|
||||
status = device.get_puk_status()
|
||||
assert(status == bytes([2,2,1,0]))
|
||||
|
||||
|
|
@ -123,14 +123,14 @@ def test_register_more_puks(device):
|
|||
assert(status == bytes([2,1,1,0]))
|
||||
|
||||
def test_is_pku(device):
|
||||
device.initialize(puk_auts=1, puk_min_auts=1)
|
||||
device.initialize(puk_auts=1, puk_min_auts=1, no_dev_cert=True)
|
||||
assert(device.is_puk() == True)
|
||||
|
||||
device.initialize()
|
||||
device.initialize(no_dev_cert=True)
|
||||
assert(device.is_puk() == False)
|
||||
|
||||
def test_check_puk_key(device):
|
||||
device.initialize(puk_auts=1, puk_min_auts=1)
|
||||
device.initialize(puk_auts=1, puk_min_auts=1, no_dev_cert=True)
|
||||
status = device.check_puk_key(term_chr)
|
||||
assert(status == -1)
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ def test_check_puk_key(device):
|
|||
|
||||
|
||||
def test_register_puk_with_no_puk(device):
|
||||
device.initialize()
|
||||
device.initialize(no_dev_cert=True)
|
||||
with pytest.raises(APDUResponse) as e:
|
||||
device.register_puk(AUT_PUK, TERM_CERT, DICA_CERT)
|
||||
assert(e.value.sw == SWCodes.SW_FILE_NOT_FOUND)
|
||||
|
|
|
|||
|
|
@ -25,12 +25,13 @@ from cvc.asn1 import ASN1
|
|||
from cvc.certificates import CVC
|
||||
from cvc import oid
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from picohsm import DOPrefixes, APDUResponse, SWCodes
|
||||
from picohsm import DOPrefixes
|
||||
from picokey import APDUResponse, SWCodes
|
||||
|
||||
KDM = unhexlify(b'30820420060B2B0601040181C31F0402016181ED7F2181E97F4E81A25F290100421045535049434F48534D434130303030317F494F060A04007F0007020202020386410421EE4A21C16A10F737F12E78E5091B266612038CDABEBB722B15BF6D41B877FBF64D9AB69C39B9831B1AE00BEF2A4E81976F7688D45189BB232A24703D8A96A55F201045535049434F48534D445630303030317F4C12060904007F000703010202530580000000005F25060202000801085F24060203000601045F37403F75C08FFFC9186B56E6147199E82BFC327CEEF72495BC567961CD54D702F13E3C2766FCD1D11BD6A9D1F4A229B76B248CEB9AF88D59A74D0AB149448705159B6281E97F2181E57F4E819E5F290100421045535049434F48534D445630303030317F494F060A04007F000702020202038641043359F5234CE62E0EB80460046D8FD1AAE018CC8B9E687B40AA2C047E352409B45153D1AD888E4E7E780A3B1FA8C69CA8998BD271C8849137149142E96816A5A45F201045535049434F48534D54524A5A58314A7F4C0E060904007F0007030102025301005F25060205000100085F24060206000100085F374016F155B01CDE7FB902C8A631FCB6938458CB570EAB088DEFE1FFACD3AEFF069020256EECCF8E962461534ED682DB87BB9801E25556F87BF524385C536D19A7D1638201F1678201ED7F218201937F4E82014B5F290100421045535049434F48534D54524A5A58314A7F4982011D060A04007F000702020202038120A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E537782207D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9832026DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B68441048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F0469978520A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A786410443F0BAB3EB271E1B762BDB81C2CC10C21CF9E8A73241B86C9552614A8842DA00A556C20BC4250C275981FE196F8D2E8766DE06C609BA07AC3E6E1468EAC451408701015F201045535049434F48534D54524A5A58314A5F37402E79A552EA5ABE1B4244841CC55515F31CACFE9B3E0A3FC3FC178DFD5ED6ADC67E03FCC65C24A8A65658768A1A522F372E9897B87058E453A647FC58E089D30D421045535049434F48534D54524A5A58314A5F37400B54434EF57C6DD55D26B44F63940E9F15C10FBC8FC013528F76ACF917D74EF41D635D630F778862ADBD3EE8574F4ABC28B9A6044DFCB9C30D83C1A4DBE6437054400964DBAED86825DBA4E5BCEFF66DAF5739A71D4B2677FB1F53ABA23B3D1D1A686A06478C3CF7FF797FE7C8A4D090D881319BD15AABE709D3EA74A48C88E4387F')
|
||||
KDM = unhexlify(b'30820420060b2b0601040181c31f0402016181ed7f2181e97f4e81a25f290100421045535049434f48534d434130303030327f494f060a04007f00070202020203864104e66b473ec328caf39eaed840f9c7a4ba237e1dd19004861fa3f4f134bd2d5ea5f71c6c2e6321add4c8a7793ba41119c5783f48a5d9dfc0898d9ae9e7b14da8d65f201045535049434f48534d445630303030327f4c12060904007f000703010202530580000000045f25060205000400065f24060206000400065f3740a645594c6c338cd6bda6cad039cee54fd822b1011c0af1e4e3a2a6d03d43bdbb8be68a66a8757e7b1f963589bdd80d8e65de5055b722609041ec63f0498ddc8b6281e97f2181e57f4e819e5f290100421045535049434f48534d445630303030327f494f060a04007f000702020202038641043359f5234ce62e0eb80460046d8fd1aae018cc8b9e687b40aa2c047e352409b45153d1ad888e4e7e780a3b1fa8c69ca8998bd271c8849137149142e96816a5a45f201045535049434f48534d54524a5a58314a7f4c0e060904007f0007030102025301005f25060205010102085f24060206010102085f37409add1c1c8a05e7bc56a8bd846c9122d9214cc43c86b6952a961dce525d830a58130cbb275e9408af38dc16160f958d2b9ac6ac4f0f1b9b863284f00121d447ce638201f1678201ed7f218201937f4e82014b5f290100421045535049434f48534d54524a5a58314a7f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a78641049de55b50b921de72bbf740d3518905ff893e8208cfe8d144de34d79da3645d1c0cb551a19d6e6a5fee050e479a65d36fdf638af741e52dad4df9960b8ed443d18701015f201045535049434f48534d54524a5a58314a5f374099dede270b9a2def89a4d12dc0314e6289bd565808683f362e9f9ac9554ec5113bf7e412ecc386af12d2a9b43f27e54e10dfc6d8f2d6b618b1776459c13c0bec421045535049434f48534d54524a5a58314a5f3740459f6385f28a84f1c57f421a7f6cb4f1177084497321be94c87998c2e01af0202bab6984411cde1aab34e4e59cc27961b85855bae6340305281ff838253b0f3554404b6a2fe6947faa91f6ffa0d707cd4cbb43192935f561be137f4b3680304fc28b41210b671b8b033e06b4ad720010bcd36b92282844616261f944f3c4f67bfda5')
|
||||
|
||||
def test_initialize(device):
|
||||
device.initialize(key_domains=1)
|
||||
device.initialize(key_domains=1, no_dev_cert=True)
|
||||
device.logout()
|
||||
|
||||
def test_create_xkek(device):
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ from cvc.certificates import CVC
|
|||
from cvc import oid
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from picohsm import EncryptionMode, APDUResponse, SWCodes, PicoHSM
|
||||
from picohsm import EncryptionMode, PicoHSM
|
||||
from picokey import APDUResponse, SWCodes
|
||||
import hashlib
|
||||
|
||||
TEST_STRING = b'Pico Keys are awesome!'
|
||||
|
|
@ -36,7 +37,7 @@ def sha256_sha256(data):
|
|||
return hashlib.sha256(hashlib.sha256(data).digest()).digest()
|
||||
|
||||
def test_initialize(device):
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES)
|
||||
device.initialize(dkek_shares=DEFAULT_DKEK_SHARES, no_dev_cert=True)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
resp = device.import_dkek(DEFAULT_DKEK)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ test $? -eq 0 || exit $?
|
|||
rsa_encrypt_decrypt() {
|
||||
openssl pkeyutl -encrypt -pubin -inkey 1.pub $2 -in $1 -out data.crypt
|
||||
test $? -eq 0 && echo -n "." || exit $?
|
||||
TDATA=$(tr -d '\0' < <(pkcs11-tool --id 1 --pin 648219 --decrypt $3 -i data.crypt 2>/dev/null))
|
||||
TDATA=$(pkcs11-tool --id 1 --pin 648219 --decrypt $3 -i data.crypt 2>/dev/null | sed '/^OAEP parameters:/d' | tr -d '\0')
|
||||
test $? -eq 0 && echo -n "." || exit $?
|
||||
if [[ ${TEST_STRING} != "$TDATA" ]]; then
|
||||
if [[ "$TEST_STRING" != "$TDATA" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
test $? -eq 0 && echo -n "." || exit $?
|
||||
|
|
@ -36,7 +36,7 @@ rsa_encrypt_decrypt data_pad "-pkeyopt rsa_padding_mode:none" "--mechanism RSA-X
|
|||
test $? -eq 0 && echo -e ".\t${OK}" || exit $?
|
||||
|
||||
echo -n " Test RSA-PKCS-OAEP ciphering..."
|
||||
rsa_encrypt_decrypt data "-pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256" "--mechanism RSA-PKCS-OAEP"
|
||||
rsa_encrypt_decrypt data "-pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256" "--mechanism RSA-PKCS-OAEP --hash-algorithm SHA256 --mgf MGF1-SHA256"
|
||||
test $? -eq 0 && echo -e ".\t${OK}" || exit $?
|
||||
|
||||
rm -rf data* 1.*
|
||||
|
|
|
|||
|
|
@ -39,13 +39,13 @@ except ModuleNotFoundError:
|
|||
sys.exit(-1)
|
||||
|
||||
try:
|
||||
from picohsm import PicoHSM, PinType, DOPrefixes, KeyType, EncryptionMode, utils, APDUResponse, SWCodes, AES, Platform
|
||||
from picohsm import PicoHSM, PinType, DOPrefixes, KeyType, EncryptionMode, AES
|
||||
from picohsm.utils import get_pki_data
|
||||
from picokey import APDUResponse, Platform
|
||||
except ModuleNotFoundError:
|
||||
print('ERROR: picohsm module not found! Install picohsm package.\nTry with `pip install pypicohsm`')
|
||||
sys.exit(-1)
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
import base64
|
||||
from binascii import hexlify, unhexlify
|
||||
import sys
|
||||
|
|
@ -175,21 +175,6 @@ def parse_args():
|
|||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
def get_pki_data(url, data=None, method='GET'):
|
||||
user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; '
|
||||
'rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
|
||||
method = 'GET'
|
||||
if (data is not None):
|
||||
method = 'POST'
|
||||
req = urllib.request.Request(f"https://www.picokeys.com/pico/pico-hsm/{url}/",
|
||||
method=method,
|
||||
data=data,
|
||||
headers={'User-Agent': user_agent, })
|
||||
response = urllib.request.urlopen(req)
|
||||
resp = response.read().decode('utf-8')
|
||||
j = json.loads(resp)
|
||||
return j
|
||||
|
||||
def get_pki_certs(certs_dir='certs', force=False):
|
||||
certs = get_pki_data('certs')
|
||||
if (os.path.exists(certs_dir) is False):
|
||||
|
|
@ -222,45 +207,9 @@ def initialize(picohsm, args):
|
|||
print('Are you sure?')
|
||||
_ = input('[Press enter to confirm]')
|
||||
|
||||
if (args.pin):
|
||||
try:
|
||||
picohsm.login(args.pin)
|
||||
except APDUResponse:
|
||||
pass
|
||||
pin = args.pin
|
||||
else:
|
||||
pin = '648219'
|
||||
picohsm.initialize(pin=args.pin, sopin=args.so_pin, no_dev_cert=args.no_dev_cert)
|
||||
|
||||
if (args.so_pin):
|
||||
try:
|
||||
picohsm.login(args.so_pin, who=PinType.SO_PIN)
|
||||
except APDUResponse:
|
||||
pass
|
||||
so_pin = args.so_pin
|
||||
else:
|
||||
so_pin = '57621880'
|
||||
|
||||
picohsm.initialize(pin=pin, sopin=so_pin)
|
||||
if (not args.no_dev_cert):
|
||||
response = picohsm.get_contents(DOPrefixes.EE_CERTIFICATE_PREFIX, 0x00)
|
||||
|
||||
cert = bytearray(response)
|
||||
Y = CVC().decode(cert).pubkey().find(0x86).data()
|
||||
print(f'Public Point: {hexlify(Y).decode()}')
|
||||
|
||||
pbk = base64.urlsafe_b64encode(Y)
|
||||
params = {'pubkey': pbk}
|
||||
if (picohsm.platform in (Platform.RP2350, Platform.ESP32, Platform.EMULATION)):
|
||||
params['curve'] = 'secp256k1'
|
||||
data = urllib.parse.urlencode(params).encode()
|
||||
j = get_pki_data('cvc', data=data)
|
||||
print('Device name: '+j['devname'])
|
||||
dataef = base64.urlsafe_b64decode(
|
||||
j['cvcert']) + base64.urlsafe_b64decode(j['dvcert']) + base64.urlsafe_b64decode(j['cacert'])
|
||||
|
||||
picohsm.select_file(0x2f02)
|
||||
response = picohsm.put_contents(0x0000, data=dataef)
|
||||
|
||||
print('Certificate uploaded successfully!')
|
||||
print('')
|
||||
print('Note that the device is initialized with a default PIN and '
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue