use of io.churchkey.ec.Curve in project churchkey by tomitribe.
the class OpenSslEcCurvesTest method oid.
/**
* Oakley-EC2N-3 and Oakley-EC2N-4 are ignored because
* they have no OID according to OpenSSL
*/
@Test
@Skip({ "Oakley-EC2N-3", "Oakley-EC2N-4" })
public void oid() throws Exception {
final byte[] bytes = resource.bytes(openSslCurveName + "-oid.pem");
final Oid oid = (Oid) BeginEcParameters.decode(bytes);
final Curve actual = Curve.resolve(oid);
assertNotNull("OID could not be resolved " + oid, actual);
if (!curve.equals(actual) && !curve.getAliases().contains(actual) && !actual.getAliases().contains(curve)) {
fail("Expected: " + curve + ", found: " + actual);
}
}
use of io.churchkey.ec.Curve in project churchkey by tomitribe.
the class BeginEcPrivateKey method decode.
public static Key decode(final byte[] bytes) {
try {
final Ecdsa.Private.Builder ec = 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.OCTET_STRING);
final Asn1Object d2o3 = d2.readObject().assertType(Asn1Type.ANY);
{
final DerParser d3 = new DerParser(d2o3.getValue());
final Asn1Object d3o1 = d3.readObject();
if (d3o1.isType(Asn1Type.OBJECT_IDENTIFIER)) {
final Oid oid = d3o1.asOID();
final Curve curve = Curve.resolve(oid);
ec.curve(curve);
} else if (d3o1.isType(Asn1Type.SEQUENCE)) {
ec.spec(EcCurveParams.parseSequence(d3o1));
}
ec.d(d2o2.toInteger());
}
final Asn1Object d2o4 = d2.readObject();
if (d2o4 != null && d2o4.isType(Asn1Type.BOOLEAN)) {
final DerParser d3 = new DerParser(d2o4.getValue());
final Asn1Object d3o1 = d3.readObject().assertType(Asn1Type.BIT_STRING);
final byte[] value = Bytes.trim(d3o1.getValue());
final ECPoint ecPoint = EcPoints.fromBytes(value);
ec.x(ecPoint.getAffineX());
ec.y(ecPoint.getAffineY());
}
final Ecdsa.Private build = ec.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);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
use of io.churchkey.ec.Curve in project churchkey by tomitribe.
the class BeginPrivateKey method encodeEc.
/**
* 0:d=0 hl=2 l= 84 cons: SEQUENCE
* 2:d=1 hl=2 l= 1 prim: INTEGER :00
* 5:d=1 hl=2 l= 16 cons: SEQUENCE
* 7:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey
* 16:d=2 hl=2 l= 5 prim: OBJECT :secp128r1
* 23:d=1 hl=2 l= 61 prim: OCTET STRING
* 0000 - 30 3b 02 01 01 04 10 12-d9 68 7a e0 21 c4 b4 ee 0;.......hz.!...
* 0010 - cd e2 46 27 e4 55 10 a1-24 03 22 00 04 19 ef 1d ..F'.U..$.".....
* 0020 - d1 8e 15 82 f0 fb a9 a8-e7 3f 79 f8 79 d4 ab 9e .........?y.y...
* 0030 - 5d 6d 40 33 d8 d0 fe 6d-43 71 fb bc e5 ]m@3...mCq...
*
* The OCTET STRING is formatted as follows
*
* 0:d=0 hl=2 l= 59 cons: SEQUENCE
* 2:d=1 hl=2 l= 1 prim: INTEGER :01
* 5:d=1 hl=2 l= 16 prim: OCTET STRING
* 0000 - 12 d9 68 7a e0 21 c4 b4-ee cd e2 46 27 e4 55 10 ..hz.!.....F'.U.
* 23:d=1 hl=2 l= 36 cons: cont [ 1 ]
* 25:d=2 hl=2 l= 34 prim: BIT STRING
* 0000 - 00 04 19 ef 1d d1 8e 15-82 f0 fb a9 a8 e7 3f 79 ..............?y
* 0010 - f8 79 d4 ab 9e 5d 6d 40-33 d8 d0 fe 6d 43 71 fb .y...]m@3...mCq.
* 0020 - bc e5 ..
*/
private static byte[] encodeEc(final Key key) {
final ECPrivateKey privateKey = (ECPrivateKey) key.getKey();
final ECParameterSpec params = privateKey.getParams();
final Curve curve = Arrays.stream(Curve.values()).filter(c -> c.isEqual(params)).findFirst().orElseThrow(() -> new IllegalStateException("Unable to resolve OID for ECParameterSpec"));
if (key.getPublicKey() != null) {
final ECPublicKey publicKey = (ECPublicKey) key.getPublicKey().getKey();
return write().sequence(write().integer(ZERO).sequence(write().objectIdentifier(ecKey).objectIdentifier(curve.getOid())).octetString(write().sequence(write().integer(ONE).octetString(privateKey.getS()).bolean(write().bitString(EcPoints.toBytes(publicKey.getW())))))).bytes();
} else {
return write().sequence(write().integer(ZERO).sequence(write().objectIdentifier(ecKey).objectIdentifier(curve.getOid())).octetString(write().sequence(write().integer(ONE).octetString(privateKey.getS())))).bytes();
}
}
use of io.churchkey.ec.Curve 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);
}
}
}
}
use of io.churchkey.ec.Curve in project churchkey by tomitribe.
the class JwkParser method asEcKey.
/**
* {
* "kty": "EC",
* "crv": "P-256",
* "x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
* "y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
* "d": "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE",
* "use": "enc",
* "kid": "1"
* }
*/
private Key asEcKey(final JsonObject jsonObject) {
final Jwk jwk = new Jwk(jsonObject);
final String crv = jwk.getString("crv");
final BigInteger d = jwk.getBigInteger("d");
final BigInteger x = jwk.getBigInteger("x");
final BigInteger y = jwk.getBigInteger("y");
if (crv == null)
throw new InvalidJwkKeySpecException("EC", "crv");
final Curve curve = Curve.resolve(crv);
if (d != null) {
final Ecdsa.Private build = Ecdsa.Private.builder().curve(curve).d(d).x(x).y(y).build();
final ECPrivateKey privateKey = build.toKey();
final ECPublicKey publicKey = build.getX() != null && build.getY() != null ? build.toPublic().toKey() : null;
final Map<String, String> attributes = getAttributes(jsonObject, "kty", "crv", "d");
return new Key(privateKey, publicKey, Key.Type.PRIVATE, Key.Algorithm.EC, Key.Format.JWK, attributes);
}
final List<String> missing = new ArrayList<String>();
if (y == null)
missing.add("y");
if (x == null)
missing.add("x");
if (missing.size() != 0) {
throw new InvalidJwkKeySpecException("EC", missing);
}
final ECPublicKey publicKey = Ecdsa.Public.builder().curve(curve).x(x).y(y).build().toKey();
final Map<String, String> attributes = getAttributes(jsonObject, "kty", "crv", "x", "y");
return new Key(publicKey, Key.Type.PUBLIC, Key.Algorithm.EC, Key.Format.JWK, attributes);
}
Aggregations