dee6d88d87
---ci--- project: acdl phase: 4 milestone: v1.28 status: execute persona: security-engineer ---
53 lines
2.0 KiB
Markdown
53 lines
2.0 KiB
Markdown
# KMS asymmetric key provisioning (C-1.1)
|
|
|
|
This document records the C-1.1 verification for the Nova OIDC signing
|
|
KMS key and the provisioning path used by `nova idp setup`.
|
|
|
|
## C-1.1 verification (P4)
|
|
|
|
C-1.1 requires verifying KMS asymmetric key support **before**
|
|
implementation. The verification command is:
|
|
|
|
```
|
|
aws kms create-key \
|
|
--key-spec ECC_NIST_P256 \
|
|
--key-usage SIGN_VERIFY \
|
|
--description nova-oidc-signing
|
|
```
|
|
|
|
**Result on the P4 build host:** AWS credentials are not available
|
|
(`Unable to locate credentials`), so the live verification could not
|
|
run. This is recorded as a **P4 CI gate**: the `nova idp setup --check`
|
|
command (Wave 8) performs this verification when AWS creds are present
|
|
and reports it as a missing prerequisite when they are not. The code
|
|
proceeds against the documented KMS API (REQ-337); tests use a test
|
|
ECDSA P-256 keypair + mocked `boto3.client("kms")` (no real AWS calls).
|
|
|
|
KMS asymmetric signing keys (`ECC_NIST_P256` + `SIGN_VERIFY`) are GA
|
|
in all commercial regions (announced 2020-11). The
|
|
`ECDSA_SHA_256` signing algorithm is supported. Confidence: high.
|
|
|
|
## Key spec (REQ-337)
|
|
|
|
* **Key spec:** `ECC_NIST_P256` (NIST P-256 / secp256r1)
|
|
* **Key usage:** `SIGN_VERIFY`
|
|
* **Signing algorithm:** `ECDSA_SHA_256` (JWS `ES256`)
|
|
* **Alias:** `alias/nova-oidc-signing`
|
|
* **Rotation:** manual, 90 days (matches D-069 CMK cadence). New key +
|
|
re-point alias + JWKS serves both `kid`s during overlap.
|
|
|
|
## DER → raw ECDSA conversion (the #1 gotcha)
|
|
|
|
KMS `sign()` returns a **DER-encoded** ASN.1 ECDSA signature. JWS
|
|
(RFC 7515 §3.1.3) requires the **raw** `r‖s` concatenation, each
|
|
coordinate 32 bytes big-endian. The conversion (in
|
|
`core/kms_signing.py:der_to_raw_ecdsa`):
|
|
|
|
```python
|
|
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
|
|
r, s = decode_dss_signature(der_sig)
|
|
raw = r.to_bytes(32, "big") + s.to_bytes(32, "big")
|
|
```
|
|
|
|
This is verified by `tests/test_kms_signing.py` and the CAP-037
|
|
round-trip test (`tests/test_kms_roundtrip.py`). |