Repository navigation
Conversation
No EC private key could be imported through NSS, so pk12util and
Firefox failed on every EC PKCS#12 file and PK11_ImportDERPrivateKeyInfo
failed for EC keys. EC PKCS#12 export failed too.
- NSS creates the private key with the raw X9.63 point (04||X||Y) in
CKA_EC_POINT (pk11pk12.c). EcSetPoint only took a DER OCTET STRING, so
the 0x04 was read as the tag, the first byte of X as the length, and
the key was refused with CKR_ATTRIBUTE_VALUE_INVALID.
- NSS sends an empty CKA_EC_POINT when the PKCS#8 has no public value,
which was refused as well.
- The default encrypted PKCS#12 form imports through C_UnwrapKey and
exports through C_WrapKey, which did not take EC private keys
(CKR_TEMPLATE_INCONSISTENT and CKR_KEY_NOT_WRAPPABLE).
A private key's CKA_EC_POINT now takes the raw point as well as DER.
The two are told apart by length, as softokn does: a value of
2 * field size + 1 bytes starting with 0x04 is raw. The point must
still be on the curve. An empty CKA_EC_POINT on a private key is
treated as not given. Public keys still take DER only.
EC private keys are wrapped and unwrapped as PKCS#8, as RSA keys
already are. An unwrapped key gets the same scalar range and point
checks as C_CreateObject. A CKA_EC_PARAMS in the template naming
another curve returns CKR_TEMPLATE_INCONSISTENT, and data that is not
an EC private key returns CKR_WRAPPED_KEY_INVALID. A key with no
private scalar in software, such as one generated on a TPM, returns
CKR_KEY_NOT_WRAPPABLE.
NSS builds now return the raw point when CKA_EC_POINT is read from a
private key. PK11_ExportPrivKeyInfo copies the attribute into the
PKCS#8 as is, so the DER form made a malformed key on unencrypted
export, the path Firefox WebCrypto exportKey('pkcs8') uses. softokn
returns the value NSS stored, which is the raw point. Other builds
still return DER.
object_template_codes_test expected CKR_TEMPLATE_INCONSISTENT for an
EC private key unwrap. Its data is not a wrapped key, so it now gets
CKR_WRAPPED_KEY_INVALID.
The new ec_private_key_import_test covers raw, DER and empty points on
private keys, the point read back, an off-curve raw point, a raw point
on a public key, a wrap and unwrap round trip with and without the
public point, a curve mismatch and invalid wrapped data.
|
@claude review |
CHECK_WRAPPABLE took EC private keys in every build. Without ECC, C_UnwrapKey then went on to decrypt and failed on the mechanism or the key type, instead of refusing the key type with CKR_TEMPLATE_INCONSISTENT as it did before. EC private keys are now only wrappable when HAVE_ECC is defined. object_template_codes_test now expects CKR_WRAPPED_KEY_INVALID for its EC unwrap only with ECC and AES-CBC, CKR_MECHANISM_INVALID with ECC but no AES-CBC, and CKR_TEMPLATE_INCONSISTENT without ECC. ec_private_key_import_test defined two constants that only the wrap tests use outside the TEST_EC_WRAP guard, which broke the --disable-aescbc build with -Werror.
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. It adds new paths for exporting and importing private key material (C_WrapKey/C_UnwrapKey for EC) and changes how CKA_EC_POINT is parsed, so a human look would still be worthwhile.
What was reviewed:
- The raw-vs-DER split in
EcSetPoint: raw form is accepted only on private keys, only when the length is exactly 2*size+1 and the first byte is 0x04, and it still goes through the on-curve check. WP11_Ec_ParsePrivKey: the curve from the template is saved before the key is reset, then the curve-mismatch, scalar-range and point checks run, and the key is freed on error.AddECPrivateKeyObjectcleans up on failure.WP11_Ec_SerializeKeyPTPKC8: it returns the length first and then fills the buffer, holds the read lock, and returns BAD_STATE_E for keys with no scalar. Also checked that the empty-CKA_EC_POINT skip inSetAttributeValueapplies only to EC private keys.
Extended reasoning...
The change touches src/crypto.c and src/internal.c in wolfPKCS11, about 300 lines of library code plus a 539-line new test. It makes EC private keys wrappable and unwrappable as plain PKCS#8, and it accepts and returns a raw X9.63 point on private keys. That is security-sensitive: it handles private key material and decides when a key may leave the token. No bugs were found, but because this is crypto key import/export code, a human maintainer should confirm the design choice and the behaviour across the many feature-flag builds (FIPS, TPM, NSS).
This review covers commit 85dbd5e, which is no longer the latest commit on this pull request; later commits are not covered by it.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #297
Scan targets checked: wolfpkcs11-src, wolfpkcs11-bugs
Not reviewed (no scan target covers them): tests/include.am
Coverage: 5 of 5 in-scope changed file(s) opened by the reviewer
Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
Review tier: Max
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #297
Scan targets checked: wolfpkcs11-src, wolfpkcs11-bugs
Not reviewed (no scan target covers them): tests/include.am
Coverage: 2 of 3 in-scope changed file(s) opened by the reviewer; not opened: tests/ec_private_key_import_test.c
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Review tier: Lite
Fenrir's latest completed scan found no issues; clearing the prior automated change request.
EC private keys could not be imported through NSS.
pk12utiland Firefox failed on every EC PKCS#12 file,PK11_ImportDERPrivateKeyInfofailed for EC keys (Firefox WebCryptoimportKey('pkcs8'), for example), and EC PKCS#12 export failed. RSA was not affected. This was found by running NSS's pk11_gtests against wolfPKCS11; our CI only runs ssl_gtests, and the pk12util workflows only use RSA keys.There were three causes:
04||X||Y) inCKA_EC_POINT(pk11pk12.c).EcSetPointonly took a DER OCTET STRING, so the0x04was read as the tag, the first byte of X as the length, and the key was refused withCKR_ATTRIBUTE_VALUE_INVALID.CKA_EC_POINTwhen the PKCS#8 has no public value, which was refused as well.C_UnwrapKeyand exports throughC_WrapKey, and neither took EC private keys (CKR_TEMPLATE_INCONSISTENTandCKR_KEY_NOT_WRAPPABLE).PKCS#11 only gives EC private keys
CKA_EC_PARAMSandCKA_VALUE, but softokn acceptsCKA_EC_POINTon them in either form and NSS depends on that.Change.
CKA_EC_POINTnow takes the raw point as well as DER. They are told apart by length, as softokn does: a value of 2 * field size + 1 bytes starting with0x04is raw. The point must still be on the curve. An emptyCKA_EC_POINTon a private key is treated as not given.object_template_codes_testasserts.WP11_Ec_SerializeKeyPTPKC8,WP11_Ec_ParsePrivKey).C_CreateObject.CKA_EC_PARAMSin the template naming another curve returnsCKR_TEMPLATE_INCONSISTENT.CKR_WRAPPED_KEY_INVALID.CKR_KEY_NOT_WRAPPABLE.CKA_EC_POINTis read from a private key.PK11_ExportPrivKeyInfocopies the attribute into the PKCS#8 as is, so the DER form made a malformed key on unencrypted export, the path WebCryptoexportKey('pkcs8')uses. softokn returns the value NSS stored, which is the raw point. Other builds still return DER.object_template_codes_testexpectedCKR_TEMPLATE_INCONSISTENTfor an EC private key unwrap, because EC unwrap was not supported. Its data is not a wrapped key, so it now getsCKR_WRAPPED_KEY_INVALID, orCKR_MECHANISM_INVALIDin builds without AES-CBC. Builds without ECC still refuse the key type withCKR_TEMPLATE_INCONSISTENT.Testing.
New
ec_private_key_import_test(34 checks). It covers:It fails on master and passes here.
make checkpasses in the default build (macOS) and the--enable-nssbuild (Ubuntu 24.04, Docker), and in the--disable-aescbcand--disable-ecc --disable-hkdf --disable-aescbc --disable-concatenatebuilds. The no-store build compiles with-Werror.The new test,
object_template_codes_testandpkcs11testare clean under ASan and UBSan in both builds.Against NSS 3.112 with the osp patches, built as
nss.ymldoes:Not changed. Some pk11_gtest EC tests still fail:
CKM_NSS_PUB_FROM_PRIV, which is not supported.