Details
-
Type:
Bug
-
Status: Closed
-
Priority:
Blocker
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: EJBCA 7.3.1.3, EJBCA 7.4.0
-
Component/s: None
-
Labels:
-
Issue discovered during:Customer
-
Sprint:EJBCA Team Alice -2020 w10
Description
Public EC keys stored by a Pkcs11NgCryptoToken are always using explicit EC parameters.
Explicit EC parameters which should only be used for CSCA and DS certificates. To illustrate, this is what it looks like with explicit EC parameters:
dumpasn1 BRCA6SignKey.der ons 18 mar 2020 10:41:01 0 437: SEQUENCE { 4 333: SEQUENCE { 8 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) 17 320: SEQUENCE { 21 1: INTEGER 1 24 60: SEQUENCE { 26 7: OBJECT IDENTIFIER prime-field (1 2 840 10045 1 1) 35 49: INTEGER : 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF : FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF : FE FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF : FF : } 86 100: SEQUENCE { 88 48: OCTET STRING : FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF : FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE : FF FF FF FF 00 00 00 00 00 00 00 00 FF FF FF FC 138 48: OCTET STRING : B3 31 2F A7 E2 3E E7 E4 98 8E 05 6B E3 F8 2D 19 : 18 1D 9C 6E FE 81 41 12 03 14 08 8F 50 13 87 5A : C6 56 39 8D 8A 2E D1 9D 2A 85 C8 ED D3 EC 2A EF : } 188 97: OCTET STRING : 04 AA 87 CA 22 BE 8B 05 37 8E B1 C7 1E F3 20 AD : 74 6E 1D 3B 62 8B A7 9B 98 59 F7 41 E0 82 54 2A : 38 55 02 F2 5D BF 55 29 6C 3A 54 5E 38 72 76 0A : B7 36 17 DE 4A 96 26 2C 6F 5D 9E 98 BF 92 92 DC : 29 F8 F4 1D BD 28 9A 14 7C E9 DA 31 13 B5 F0 B8 : C0 0A 60 B1 CE 1D 7E 81 9D 7A 43 1D 7C 90 EA 0E : 5F 287 49: INTEGER : 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF : FF FF FF FF FF FF FF FF FF C7 63 4D 81 F4 37 2D : DF 58 1A 0D B2 48 B0 A7 7A EC EC 19 6A CC C5 29 : 73 338 1: INTEGER 1 : } : } 341 98: BIT STRING : 04 43 B5 90 A8 88 E2 72 41 A2 40 71 1A 44 7D 8D : 95 3E 2E A0 52 33 77 E3 77 4F E4 35 63 66 1B 2C : 5E 32 A8 B2 CE 37 0B 68 9B 70 C6 9E C5 EA 59 4F : 95 41 3A 20 38 9F C7 15 29 7B CC BD 56 CD 2C 2F : 3D 23 09 F4 CB A6 77 8E 7C 45 D3 60 6D C0 E1 A5 : CF D4 DE E2 E8 45 16 4D 05 DB 2B 73 E6 F7 2D E1 : 5F : } 0 warnings, 0 errors.
This is another key using the same curve, but without explicit EC parameters:
0 118: SEQUENCE { 2 16: SEQUENCE { 4 7: OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) 13 5: OBJECT IDENTIFIER secp384r1 (1 3 132 0 34) : } 20 98: BIT STRING : 04 BB 68 24 0A 4B E6 FA A9 08 4C 98 68 3A 31 BE : C8 85 59 F0 21 EC 58 69 22 7A D5 F3 11 2C 1B B2 : D6 33 81 0E 2D 56 49 21 CD DE ED 4A F9 5B CD 80 : 1C 9F 2E 87 DE 56 3E 42 5D 28 C1 13 EB D4 36 64 : F5 FF 98 EE 02 CA B8 32 24 64 17 82 0A 8C 35 8E : DF BB EC F4 A0 AC A1 10 AF FB DB BE B7 BD BE EE : C9 : } 0 warnings, 0 errors.
I think the problem boils down to some Bouncy Castle logic when creating the PublicKey object.
We fetch Q and the OID of the curve from the HSM and then create a PublicKey object like this (some lines redacted for readability):
final CKA ckaQ = c.GetAttributeValue(session, publicKeyRef, CKA.EC_POINT); final CKA ckaParams = c.GetAttributeValue(session, publicKeyRef, CKA.EC_PARAMS) [...] final ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(ckaParams.getValue()); [...] final ECParameterSpec params = AlgorithmTools.getEcParameterSpecFromOid(oid); [...] final java.security.spec.EllipticCurve ellipticCurve = EC5Util.convertCurve(params.getCurve(), params.getSeed()); final java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, ASN1OctetString.getInstance(ckaQ.getValue()).getOctets()); final java.security.spec.ECParameterSpec parameterSpec = EC5Util.convertSpec(ellipticCurve, params); final java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(ecPoint, parameterSpec); return KeyFactory.getInstance("EC", "BC").generatePublic(keySpec);
Change the code to honour the checkbox "Use explicit ECC parameters (ICAO CSCA and DS certificates)". Attach the solution as a patch file to be able to backport.
Got advice from David how to do this:
You want to use:
final java.security.spec.ECPublicKeySpec keySpec = new java.security.spec.ECPublicKeySpec(((java.security.interfaces.ECPublicKey)kp.getPublic()).getW(), new ECNamedCurveSpec(oid.getId(), parameterSpec.getCurve(), parameterSpec.getGenerator(), parameterSpec.getOrder(), BigInteger.valueOf(parameterSpec.getCofactor()))); PublicKey k = KeyFactory.getInstance("EC", "BC").generatePublic(keySpec);You might be able to simplify the code below further, but the trick is to tell BC you want to associate a name with the parameters.
Attachments
Issue Links
- split to
-
ECA-8975 Code cleanup: Encode EC keys generated by a Pkcs11NgCryptoToken without explicit params first
-
- Closed
-