Skip to content

Commit 33ae9a1

Browse files
committed
Created EC and Sym keys for Leo
1 parent aad09ec commit 33ae9a1

5 files changed

Lines changed: 208 additions & 12 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package com.auth0.jwt.oicmsg;
2+
3+
import com.auth0.jwt.exceptions.oicmsg_exceptions.HeaderError;
4+
import com.auth0.jwt.exceptions.oicmsg_exceptions.SerializationNotPossible;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
import java.security.spec.EllipticCurve;
9+
import java.text.ParseException;
10+
import java.util.*;
11+
12+
public class ECKey extends Key{
13+
14+
private String crv;
15+
private Object x;
16+
private Object y;
17+
private Object d;
18+
private Object curve;
19+
final private static Logger logger = LoggerFactory.getLogger(ECKey.class);
20+
private static Set<String> longs = new HashSet<String>(Arrays.asList("x", "y", "d"));
21+
protected static Set<String> members = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "crv", "x", "y", "d"));
22+
public static Set<String> publicMembers = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "crv", "x", "y"));
23+
protected static Set<String> required = new HashSet<>(Arrays.asList("crv", "key", "x", "y"));
24+
25+
public ECKey(String kty, String alg, String use, String kid, Key key, String crv, Object x, Object y, Object d,
26+
Object curve, Map<String,String> args) {
27+
super(kty, alg, use, kid, "", "", "", key, args);
28+
this.crv = crv;
29+
this.x = x;
30+
this.y = y;
31+
this.d = d;
32+
this.curve = curve;
33+
34+
if(this.crv != null && this.curve == null) {
35+
try {
36+
this.verify();
37+
} catch (HeaderError headerError) {
38+
headerError.printStackTrace();
39+
}
40+
this.deserialize();
41+
} else if(this.getKey() != null && (this.crv == null && this.curve == null)) {
42+
this.loadKey(key);
43+
}
44+
}
45+
46+
public ECKey() {
47+
this("EC", "", "", "", null, "", null, null, null, null, null);
48+
}
49+
50+
public void deserialize() {
51+
try {
52+
if(!(this.x instanceof Number)) {
53+
this.x = deser(this.x);
54+
}
55+
if(!(this.y instanceof Number)) {
56+
this.y = deser(this.y);
57+
}
58+
} catch (ParseException e) {
59+
logger.error("Couldn't parse value");
60+
}
61+
62+
this.curve = byName(this.crv);
63+
if(this.d != null) {
64+
if(this.d instanceof String) {
65+
this.d = deser(this.d);
66+
}
67+
}
68+
}
69+
70+
private EllipticCurve byName(String name) {
71+
if(name.equals("P-256")) {
72+
return EllipticCurve();
73+
} else if(name.equals("P-384")) {
74+
return EllipticCurve();
75+
} else if(name.equals("P-521")) {
76+
return EllipticCurve();
77+
}
78+
}
79+
80+
public List<Object> getKey(boolean isPrivate) {
81+
if(isPrivate) {
82+
return new ArrayList<>(Arrays.asList(this.d));
83+
} else {
84+
return new ArrayList<>(Arrays.asList(this.x, this.y));
85+
}
86+
}
87+
88+
public Object serialize(boolean isPrivate) throws SerializationNotPossible {
89+
if(this.crv == null && this.curve == null) {
90+
throw new SerializationNotPossible();
91+
}
92+
93+
Map<String, String> args = common();
94+
args.put("crv", this.curve.getClass().getName());
95+
args.put("x", longToBase64(this.x));
96+
args.put("y", longToBase64(this.y));
97+
98+
if(isPrivate && this.d != null) {
99+
args.put("d", longToBase64(this.d));
100+
}
101+
102+
return args;
103+
}
104+
105+
public ECKey loadKey(Key key) {
106+
this.curve = key;
107+
//how to return multiple objects in Java?
108+
return this;
109+
}
110+
111+
public List<Object> getDecryptionKey() {
112+
return this.getKey(true);
113+
}
114+
115+
public List<Object> getEncryptionKey(boolean isPrivate) {
116+
return this.getKey(isPrivate);
117+
}
118+
}

lib/src/main/java/com/auth0/jwt/oicmsg/Key.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ public class Key {
2020
protected String x5c;
2121
protected String x5t;
2222
protected String x5u;
23-
private Key key;
24-
private long inactiveSince;
25-
private Map<String, String> args;
23+
protected Key key;
24+
protected long inactiveSince;
25+
protected Map<String, String> args;
2626
private static Map<String, Object> longs = new HashMap<String, Object>();
2727
protected static Set<String> members = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "x5c", "x5t", "x5u"));
2828
public static Set<String> publicMembers = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "x5c", "x5t", "x5u"));

lib/src/main/java/com/auth0/jwt/oicmsg/KeyBundle.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.auth0.jwt.exceptions.oicmsg_exceptions.*;
44
import com.google.common.collect.ImmutableMap;
55
import com.google.gson.Gson;
6-
import com.nimbusds.jose.jwk.RSAKey;
76
import org.apache.http.Header;
87
import org.apache.http.HttpResponse;
98
import org.apache.http.client.HttpClient;
@@ -16,6 +15,7 @@
1615
import org.json.simple.parser.ParseException;
1716
import org.slf4j.Logger;
1817
import org.slf4j.LoggerFactory;
18+
import com.auth0.jwt.oicmsg.*;
1919
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
2020

2121
import java.io.File;
@@ -123,18 +123,29 @@ public void doKeys(List<Key> keys) {
123123
add(kty.toLowerCase());
124124
add(kty.toUpperCase());
125125
}};
126-
boolean isError = false;
126+
boolean isSuccess = true;
127127
Key key;
128128
for (String typeIndex : types) {
129129
try {
130-
key = K2C.get(typeIndex);
131-
//call key's constructor afterwards
130+
switch(typeIndex) {
131+
case "RSA":
132+
key = new RSAKey("use");
133+
break;
134+
case "EC":
135+
key = new ECKey("use");
136+
break;
137+
case "SYMKey":
138+
key = new SYMKey("use");
139+
break;
140+
default:
141+
throw new IllegalArgumentException("Encryption type: " + typeIndex + " isn't supported");
142+
}
132143
} catch (JWKException exception) {
133144
logger.warn("While loading keys: " + exception);
134-
isError = true;
145+
isSuccess = false;
135146
}
136147

137-
if (isError) {
148+
if (isSuccess) {
138149
this.keys.add(key);
139150
flag = true;
140151
break;

lib/src/main/java/com/auth0/jwt/oicmsg/RSAKey.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
public class RSAKey extends Key {
1212

13-
final private static Logger logger = LoggerFactory.getLogger(KeyBundle.class);
13+
final private static Logger logger = LoggerFactory.getLogger(RSAKey.class);
1414
private static Set<String> longs = new HashSet<String>(Arrays.asList("n", "e", "d", "p", "q", "dp", "dq", "di", "qi"));
1515
private String n;
1616
private String e;
@@ -49,8 +49,8 @@ public RSAKey(String kty, String alg, String use, String kid, String x5c, String
4949
}
5050
}
5151

52-
public RSAKey() {
53-
this("RSA", "", "", "", "", "", "", null, "", "", "", "", "", "", "", "", "", null);
52+
public RSAKey(String use) {
53+
this("RSA", "", use, "", "", "", "", null, "", "", "", "", "", "", "", "", "", null);
5454
}
5555

5656
public void deserialize() throws DeserializationNotPossible {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.auth0.jwt.oicmsg;
2+
3+
import com.auth0.jwt.exceptions.oicmsg_exceptions.JWKException;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import java.util.*;
8+
9+
public class SYMKey extends Key{
10+
11+
final private static Logger logger = LoggerFactory.getLogger(SYMKey.class);
12+
protected static Set<String> members = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "k"));
13+
public static Set<String> publicMembers = new HashSet<>(Arrays.asList("kty", "alg", "use", "kid", "k"));
14+
protected static Set<String> required = new HashSet<>(Arrays.asList("k", "kty"));
15+
private String k;
16+
private static Map<String,Integer> alg2Keylen = new HashMap<String,Integer>(){{
17+
put("A128KW", 16);
18+
put("A192KW", 24);
19+
put("A256KW", 32);
20+
put("HS256", 32);
21+
put("HS384", 48);
22+
put("HS512", 64);
23+
}};
24+
25+
public SYMKey(String kty, String alg, String use, String kid, Key key, String x5c,
26+
String x5t, String x5u, String k, Map<String,String> args) {
27+
super(kty, alg, use, kid, x5c, x5t, x5u, key, args);
28+
this.k = k;
29+
30+
if(this.key == null) {
31+
this.key = b64d(this.k.getBytes());
32+
}
33+
}
34+
35+
public void deserialize() {
36+
this.key = b64d(this.k.getBytes());
37+
}
38+
39+
public Map<String,String> serialize(boolean isPrivate) {
40+
Map<String,String> args = common();
41+
args.put("k", b64e(this.k.getBytes()).asUnicode());
42+
return args;
43+
}
44+
45+
public String encryptionKey(String alg) throws JWKException {
46+
if(this.key == null) {
47+
deserialize();
48+
}
49+
50+
int size = alg2Keylen.get(alg);
51+
52+
String encryptedKey;
53+
if(size <= 32) {
54+
encryptedKey = sha256_digest(this.key).substring(0,size);
55+
} else if (size <= 48) {
56+
encryptedKey = sha384_digest(this.key).substring(0,size);
57+
} else if (size <= 64) {
58+
encryptedKey = sha512_digest(this.key).substring(0,size);
59+
} else {
60+
throw new JWKException("No support for symmetric keys > 512 bits");
61+
}
62+
63+
logger.debug(String.format("Symmetric encryption key: %s", as_unicode(b64e(encryptedKey)));
64+
65+
return encryptedKey;
66+
}
67+
}

0 commit comments

Comments
 (0)