Search in sources :

Example 1 with UnsupportedCurveException

use of io.churchkey.ec.UnsupportedCurveException in project churchkey by tomitribe.

the class BeginPrivateKey method decodeEcKey.

/**
 * EC Keys start out with this wrapper identifying the curve by OID
 *
 *     0:d=0  hl=2 l= 112 cons: SEQUENCE
 *     2:d=1  hl=2 l=   1 prim:  INTEGER           :00
 *     5:d=1  hl=2 l=  20 cons:  SEQUENCE
 *     7:d=2  hl=2 l=   7 prim:   OBJECT            :id-ecPublicKey
 *    16:d=2  hl=2 l=   9 prim:   OBJECT            :brainpoolP192r1
 *    27:d=1  hl=2 l=  85 prim:  OCTET STRING
 *       0000 - 30 53 02 01 01 04 18 88-9f 26 37 f9 f5 1f da 16   0S.......&7.....
 *       0010 - 1c b0 4c ce 79 09 36 b0-b6 8f 22 80 4d a0 ff a1   ..L.y.6...".M...
 *       0020 - 34 03 32 00 04 46 c1 7d-10 61 08 39 73 14 45 d0   4.2..F.}.a.9s.E.
 *       0030 - 8d 3b ac 12 05 a5 ef 45-d3 fb 33 cf 91 81 e8 43   .;.....E..3....C
 *       0040 - dd ab cb b7 de 04 64 b0-82 a6 59 27 c9 0d b2 25   ......d...Y'...%
 *       0050 - 32 20 c0 d6 38                                    2 ..8
 *
 * The above OCTET STRING at byte 27 (in this example) contains the actual key values
 * and is in the following format once decoded.
 *
 *    0:d=0  hl=2 l=  83 cons: SEQUENCE
 *     2:d=1  hl=2 l=   1 prim:  INTEGER           :01
 *     5:d=1  hl=2 l=  24 prim:  OCTET STRING
 *       0000 - 88 9f 26 37 f9 f5 1f da-16 1c b0 4c ce 79 09 36   ..&7.......L.y.6
 *       0010 - b0 b6 8f 22 80 4d a0 ff-                          ...".M..
 *    31:d=1  hl=2 l=  52 cons:  cont [ 1 ]
 *    33:d=2  hl=2 l=  50 prim:   BIT STRING
 *       0000 - 00 04 46 c1 7d 10 61 08-39 73 14 45 d0 8d 3b ac   ..F.}.a.9s.E..;.
 *       0010 - 12 05 a5 ef 45 d3 fb 33-cf 91 81 e8 43 dd ab cb   ....E..3....C...
 *       0020 - b7 de 04 64 b0 82 a6 59-27 c9 0d b2 25 32 20 c0   ...d...Y'...%2 .
 *       0030 - d6 38                                             .8
 *
 * The above OCTET STRING contains the private key BigInteger.
 * The BIT STRING contains the public key ECPoint (x, y) values.
 */
private static Key decodeEcKey(final byte[] bytes) throws IOException {
    final Ecdsa.Private.Builder ecdsa = Ecdsa.Private.builder();
    final DerParser d1 = new DerParser(bytes);
    final Asn1Object d1o1 = d1.readObject().assertType(Asn1Type.SEQUENCE);
    {
        final DerParser d2 = new DerParser(d1o1.getValue());
        final Asn1Object d2o1 = d2.readObject().assertType(Asn1Type.INTEGER);
        final Asn1Object d2o2 = d2.readObject().assertType(Asn1Type.SEQUENCE);
        {
            final DerParser d3 = new DerParser(d2o2.getValue());
            final Asn1Object d3o1 = d3.readObject().assertType(Asn1Type.OBJECT_IDENTIFIER);
            final Asn1Object d3o2 = d3.readObject();
            if (d3o2.isType(Asn1Type.OBJECT_IDENTIFIER)) {
                /*
                     * An OID naming a curve is encoded
                     */
                final Oid oid = d3o2.asOID();
                final Curve curve = Curve.resolve(oid);
                if (curve == null) {
                    throw new UnsupportedCurveException(oid.toString());
                }
                ecdsa.curve(curve);
            } else if (d3o2.isType(Asn1Type.SEQUENCE)) {
                /*
                     * The actual curve parameters are encoded
                     */
                final ECParameterSpec parameterSpec = EcCurveParams.parseSequence(d3o2);
                ecdsa.spec(parameterSpec);
            }
        }
        final Asn1Object d2o3 = d2.readObject().assertType(Asn1Type.OCTET_STRING);
        {
            final DerParser d3 = new DerParser(d2o3.getValue());
            final Asn1Object d3o1 = d3.readObject().assertType(Asn1Type.SEQUENCE);
            {
                final DerParser d4 = new DerParser(d3o1.getValue());
                final Asn1Object d4o1 = d4.readObject().assertType(Asn1Type.INTEGER);
                final Asn1Object d4o2 = d4.readObject().assertType(Asn1Type.OCTET_STRING);
                final Asn1Object d4o3 = d4.readObject();
                if (d4o3 != null && d4o3.isType(Asn1Type.BOOLEAN)) {
                    final DerParser d5 = new DerParser(d4o3.getValue());
                    final Asn1Object d5o1 = d5.readObject().assertType(Asn1Type.BIT_STRING);
                    final byte[] value = Bytes.trim(d5o1.getValue());
                    final ECPoint ecPoint = EcPoints.fromBytes(value);
                    ecdsa.x(ecPoint.getAffineX());
                    ecdsa.y(ecPoint.getAffineY());
                }
                ecdsa.d(new BigInteger(1, Bytes.trim(d4o2.getValue())));
                final Ecdsa.Private build = ecdsa.build();
                final ECPrivateKey privateKey = build.toKey();
                final ECPublicKey publicKey = build.getX() != null && build.getY() != null ? build.toPublic().toKey() : null;
                return new Key(privateKey, publicKey, Key.Type.PRIVATE, EC, Key.Format.PEM);
            }
        }
    }
}
Also used : UnsupportedCurveException(io.churchkey.ec.UnsupportedCurveException) ECPrivateKey(java.security.interfaces.ECPrivateKey) Curve(io.churchkey.ec.Curve) DerParser(io.churchkey.asn1.DerParser) Oid(io.churchkey.asn1.Oid) ECPoint(java.security.spec.ECPoint) Asn1Object(io.churchkey.asn1.Asn1Object) ECPublicKey(java.security.interfaces.ECPublicKey) ECParameterSpec(java.security.spec.ECParameterSpec) BigInteger(java.math.BigInteger) DSAPrivateKey(java.security.interfaces.DSAPrivateKey) Key(io.churchkey.Key) RSAPublicKey(java.security.interfaces.RSAPublicKey) ECPrivateKey(java.security.interfaces.ECPrivateKey) DSAPublicKey(java.security.interfaces.DSAPublicKey) RSAPrivateCrtKey(java.security.interfaces.RSAPrivateCrtKey) ECPublicKey(java.security.interfaces.ECPublicKey)

Aggregations

Key (io.churchkey.Key)1 Asn1Object (io.churchkey.asn1.Asn1Object)1 DerParser (io.churchkey.asn1.DerParser)1 Oid (io.churchkey.asn1.Oid)1 Curve (io.churchkey.ec.Curve)1 UnsupportedCurveException (io.churchkey.ec.UnsupportedCurveException)1 BigInteger (java.math.BigInteger)1 DSAPrivateKey (java.security.interfaces.DSAPrivateKey)1 DSAPublicKey (java.security.interfaces.DSAPublicKey)1 ECPrivateKey (java.security.interfaces.ECPrivateKey)1 ECPublicKey (java.security.interfaces.ECPublicKey)1 RSAPrivateCrtKey (java.security.interfaces.RSAPrivateCrtKey)1 RSAPublicKey (java.security.interfaces.RSAPublicKey)1 ECParameterSpec (java.security.spec.ECParameterSpec)1 ECPoint (java.security.spec.ECPoint)1