Skip to content

Commit e6173ab

Browse files
authored
Merge pull request #45 from jimsch/master
Need to have the ASN.1 implementations for the keys as well
2 parents 8ac0aa3 + f2f14ed commit e6173ab

File tree

6 files changed

+318
-20
lines changed

6 files changed

+318
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ To add this library to a Maven project, add the following to the `dependencies`
1616
<dependency>
1717
<groupId>com.augustcellars.cose</groupId>
1818
<artifactId>cose-java</artifactId>
19-
<version>0.9.3</version>
19+
<version>0.9.4</version>
2020
</dependency>
2121
```
2222

pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.augustcellars.cose</groupId>
88
<artifactId>cose-java</artifactId>
9-
<version>0.9.4-snapshot</version>
9+
<version>0.9.4</version>
1010

1111
<name>com.augustcellars.cose:cose-java</name>
1212
<description>A Java implementation that supports the COSE secure message specification.</description>
@@ -99,6 +99,11 @@
9999
<artifactId>bcprov-jdk15on</artifactId>
100100
<version>1.54</version>
101101
</dependency>
102+
<dependency>
103+
<groupId>org.bouncycastle</groupId>
104+
<artifactId>bcpkix-jdk15on</artifactId>
105+
<version>1.54</version>
106+
</dependency>
102107
<dependency>
103108
<groupId>com.upokecenter</groupId>
104109
<artifactId>cbor</artifactId>

src/main/java/COSE/ECPrivateKey.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@
66
package COSE;
77

88
import com.upokecenter.cbor.CBORType;
9+
import java.io.IOException;
10+
import java.io.StringWriter;
911
import java.math.BigInteger;
1012
import java.security.spec.ECField;
1113
import java.security.spec.ECFieldFp;
1214
import java.security.spec.ECParameterSpec;
1315
import java.security.spec.ECPoint;
1416
import java.security.spec.EllipticCurve;
17+
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
18+
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
19+
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
1520
import org.bouncycastle.asn1.x9.X9ECParameters;
21+
import org.bouncycastle.crypto.params.ECDomainParameters;
22+
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
23+
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
24+
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
1625

1726
/**
1827
*
@@ -23,25 +32,31 @@ public class ECPrivateKey implements java.security.interfaces.ECPrivateKey {
2332
String algorithm;
2433
ECParameterSpec ecParameterSpec;
2534
BigInteger privateKey;
35+
byte[] encodedKey;
2636

27-
public ECPrivateKey(OneKey oneKey) throws CoseException
37+
public ECPrivateKey(OneKey oneKey) throws CoseException, IOException
2838
{
2939
X9ECParameters p = oneKey.GetCurve();
40+
org.bouncycastle.math.ec.ECPoint pubPoint;
41+
ECDomainParameters parameters = new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH());
3042

31-
/*
3243
if (oneKey.get(KeyKeys.EC2_Y).getType()== CBORType.Boolean) {
3344
byte[] X = oneKey.get(KeyKeys.EC2_X.AsCBOR()).GetByteString();
3445
byte[] rgb = new byte[X.length + 1];
3546
System.arraycopy(X, 0, rgb, 1, X.length);
3647
rgb[0] = (byte) (2 + (oneKey.get(KeyKeys.EC2_Y).AsBoolean() ? 1 : 0));
37-
org.bouncycastle.math.ec.ECPoint pubPoint;
3848
pubPoint = p.getCurve().decodePoint(rgb);
3949
point = new ECPoint(point.getAffineX(), point.getAffineY());
4050
}
4151
else {
4252
point = new ECPoint(new BigInteger(1, oneKey.get(KeyKeys.EC2_X).GetByteString()), new BigInteger(1, oneKey.get(KeyKeys.EC2_Y).GetByteString()));
43-
}
44-
*/
53+
pubPoint = p.getCurve().createPoint(new BigInteger(1, oneKey.get(KeyKeys.EC2_X).GetByteString()), new BigInteger(1, oneKey.get(KeyKeys.EC2_Y).GetByteString()));
54+
}
55+
56+
ECPublicKeyParameters pub = new ECPublicKeyParameters(pubPoint, parameters);
57+
ECPrivateKeyParameters priv = new ECPrivateKeyParameters(new BigInteger(1, oneKey.get(KeyKeys.EC2_D.AsCBOR()).GetByteString()), parameters);
58+
59+
/*
4560
switch (AlgorithmID.FromCBOR(oneKey.get(KeyKeys.Algorithm))) {
4661
case ECDH_ES_HKDF_256:
4762
case ECDH_ES_HKDF_512:
@@ -71,13 +86,24 @@ public ECPrivateKey(OneKey oneKey) throws CoseException
7186
default:
7287
throw new CoseException("No algorithm specified");
7388
}
89+
*/
90+
algorithm = "EC";
7491

7592
privateKey = new BigInteger(1, oneKey.get(KeyKeys.EC2_D).GetByteString());
7693

7794
ECField field = new ECFieldFp(p.getCurve().getField().getCharacteristic());
7895
EllipticCurve crv = new EllipticCurve(field, p.getCurve().getA().toBigInteger(), p.getCurve().getB().toBigInteger());
7996
ECPoint pt = new ECPoint(p.getG().getRawXCoord().toBigInteger(), p.getG().getRawYCoord().toBigInteger());
8097
ecParameterSpec = new ECParameterSpec(crv, pt, p.getN(), p.getH().intValue());
98+
99+
100+
AlgorithmIdentifier alg = new AlgorithmIdentifier(org.bouncycastle.asn1.x9.X9Curve.id_ecPublicKey, org.bouncycastle.asn1.nist.NISTNamedCurves.getOID("P-256"));
101+
102+
org.bouncycastle.asn1.sec.ECPrivateKey asnPrivate = new org.bouncycastle.asn1.sec.ECPrivateKey(256, privateKey);
103+
byte[] x = asnPrivate.getEncoded();
104+
105+
PrivateKeyInfo asnPrivateX = new PrivateKeyInfo(alg, asnPrivate);
106+
encodedKey = asnPrivateX.getEncoded();
81107
}
82108

83109

@@ -93,12 +119,12 @@ public String getAlgorithm() {
93119

94120
@Override
95121
public String getFormat() {
96-
return null;
122+
return "PKCS#8";
97123
}
98124

99125
@Override
100126
public byte[] getEncoded() {
101-
return null;
127+
return encodedKey;
102128
}
103129

104130
@Override

src/main/java/COSE/ECPublicKey.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
package COSE;
77

88
import com.upokecenter.cbor.*;
9+
import java.io.IOException;
910
import java.math.BigInteger;
1011
import java.security.PublicKey;
1112
import java.security.spec.ECParameterSpec;
1213
import java.security.spec.ECPoint;
1314
import java.security.spec.EllipticCurve;
1415
import java.security.spec.ECField;
1516
import java.security.spec.ECFieldFp;
17+
import org.bouncycastle.asn1.ASN1OctetString;
18+
import org.bouncycastle.asn1.DEROctetString;
19+
import org.bouncycastle.asn1.eac.ECDSAPublicKey;
20+
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
21+
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
1622
import org.bouncycastle.asn1.x9.X9ECParameters;
1723

1824
/**
@@ -23,22 +29,29 @@ public class ECPublicKey implements java.security.interfaces.ECPublicKey {
2329
ECPoint point;
2430
String algorithm;
2531
ECParameterSpec ecParameterSpec;
32+
byte[] spkiEncoded;
2633

27-
public ECPublicKey(OneKey oneKey) throws CoseException
34+
public ECPublicKey(OneKey oneKey) throws CoseException, IOException
2835
{
2936
X9ECParameters p = oneKey.GetCurve();
37+
byte [] rgbKey;
38+
byte[] X = oneKey.get(KeyKeys.EC2_X).GetByteString();
3039

3140
if (oneKey.get(KeyKeys.EC2_Y).getType()== CBORType.Boolean) {
32-
byte[] X = oneKey.get(KeyKeys.EC2_X.AsCBOR()).GetByteString();
33-
byte[] rgb = new byte[X.length + 1];
34-
System.arraycopy(X, 0, rgb, 1, X.length);
35-
rgb[0] = (byte) (2 + (oneKey.get(KeyKeys.EC2_Y).AsBoolean() ? 1 : 0));
41+
rgbKey = new byte[X.length + 1];
42+
System.arraycopy(X, 0, rgbKey, 1, X.length);
43+
rgbKey[0] = (byte) (2 + (oneKey.get(KeyKeys.EC2_Y).AsBoolean() ? 1 : 0));
3644
org.bouncycastle.math.ec.ECPoint pubPoint;
37-
pubPoint = p.getCurve().decodePoint(rgb);
45+
pubPoint = p.getCurve().decodePoint(rgbKey);
3846
point = new ECPoint(point.getAffineX(), point.getAffineY());
3947
}
4048
else {
41-
point = new ECPoint(new BigInteger(1, oneKey.get(KeyKeys.EC2_X).GetByteString()), new BigInteger(1, oneKey.get(KeyKeys.EC2_Y).GetByteString()));
49+
rgbKey = new byte[X.length*2+1];
50+
System.arraycopy(X, 0,rgbKey, 1, X.length);
51+
byte[] Y = oneKey.get(KeyKeys.EC2_Y).GetByteString();
52+
System.arraycopy(Y, 0, rgbKey, 1+X.length, X.length);
53+
rgbKey[0] = 4;
54+
point = new ECPoint(new BigInteger(1, X), new BigInteger(1, oneKey.get(KeyKeys.EC2_Y).GetByteString()));
4255
}
4356

4457
/*
@@ -80,6 +93,12 @@ public ECPublicKey(OneKey oneKey) throws CoseException
8093
EllipticCurve crv = new EllipticCurve(field, p.getCurve().getA().toBigInteger(), p.getCurve().getB().toBigInteger());
8194
ECPoint pt = new ECPoint(p.getG().getRawXCoord().toBigInteger(), p.getG().getRawYCoord().toBigInteger());
8295
ecParameterSpec = new ECParameterSpec(crv, pt, p.getN(), p.getH().intValue());
96+
97+
98+
AlgorithmIdentifier alg = new AlgorithmIdentifier(org.bouncycastle.asn1.x9.X9Curve.id_ecPublicKey, org.bouncycastle.asn1.nist.NISTNamedCurves.getOID("P-256"));
99+
SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(alg, rgbKey);
100+
spkiEncoded = spki.getEncoded();
101+
83102
}
84103

85104
@Override
@@ -94,12 +113,12 @@ public String getAlgorithm() {
94113

95114
@Override
96115
public String getFormat() {
97-
return null;
116+
return "X.509";
98117
}
99118

100119
@Override
101120
public byte[] getEncoded() {
102-
return null;
121+
return spkiEncoded;
103122
}
104123

105124
@Override

src/main/java/COSE/OneKey.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package COSE;
77

88
import com.upokecenter.cbor.*;
9+
import java.io.IOException;
910
import java.security.PrivateKey;
1011
import java.security.PublicKey;
1112
import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -223,7 +224,12 @@ public PublicKey AsPublicKey() throws CoseException
223224
{
224225
if (get(KeyKeys.KeyType).equals(KeyKeys.KeyType_EC2))
225226
{
226-
return new ECPublicKey(this);
227+
try {
228+
return new ECPublicKey(this);
229+
}
230+
catch (IOException e) {
231+
throw new CoseException("Internal Error encoding the key");
232+
}
227233
}
228234
throw new CoseException("Cannot convert key as key type is not converted");
229235
}
@@ -238,7 +244,11 @@ public PrivateKey AsPrivateKey() throws CoseException
238244
{
239245
if (get(KeyKeys.KeyType).equals(KeyKeys.KeyType_EC2))
240246
{
241-
return new ECPrivateKey(this);
247+
try {
248+
return new ECPrivateKey(this);
249+
} catch (IOException ex) {
250+
throw new CoseException("Internal error encoding the key");
251+
}
242252
}
243253
throw new CoseException("Cannot convert key as key type is not converted");
244254
}

0 commit comments

Comments
 (0)