Uploaded image for project: 'EJBCA'
  1. EJBCA
  2. ECA-8959

Public EC keys generated by a Pkcs11NgCryptoToken are always using explicit EC parameters

    Details

    • 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

            Activity

              People

              Assignee:
              bastianf Bastian Fredriksson
              Reporter:
              bastianf Bastian Fredriksson
              Verified by:
              Henrik Sunmark, Tomas Gustavsson
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - 4 hours Original Estimate - 4 hours
                  4h
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 5 hours, 30 minutes
                  5h 30m