package io.vertx.ext.auth.impl.cose;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.impl.jose.JWK;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class CWK {
private static class NV {
private final String name;
private final Map<String, String> values;
private NV(String name, String... pairs) {
this.name = name;
if (pairs == null || pairs.length == 0) {
this.values = Collections.emptyMap();
} else {
Map<String, String> tmp = new HashMap<>();
for (int i = 0; i < pairs.length; i += 2) {
tmp.put(pairs[i], pairs[i + 1]);
}
this.values = Collections.unmodifiableMap(tmp);
}
}
}
private static final Map<String, NV> COSE_LABELS = Collections.unmodifiableMap(new HashMap<String, NV>() {{
put("1",
new NV("kty", "1", "OKP", "2", "EC", "3", "RSA"));
put("2",
new NV("kid"));
put("3",
new NV("alg", "-7", "ES256", "-8", "EdDSA", "-35", "ES384", "-36", "ES512", "-37", "PS256", "-38", "PS384", "-39", "PS512", "-47", "ES256K", "-257", "RS256", "-258", "RS384", "-259", "RS512", "-65535", "RS1"));
put("4",
new NV("key_ops"));
put("5",
new NV("base_iv"));
}});
private static final Map<String, NV> EC_KEY_PARAMS = Collections.unmodifiableMap(new HashMap<String, NV>() {{
put("-1",
new NV("crv", "1", "P-256", "2", "P-384", "3", "P-521", "8", "secp256k1")
);
put("-2",
new NV("x"));
put("-3",
new NV("y"));
put("-4",
new NV("d"));
}});
private static final Map<String, NV> OKP_KEY_PARAMS = Collections.unmodifiableMap(new HashMap<String, NV>() {{
put("-1",
new NV("crv", "4", "X25519", "5", "X448", "6", "Ed25519", "7", "Ed448")
);
put("-2",
new NV("x"));
put("-3",
new NV("y"));
put("-4",
new NV("d"));
}});
private static final Map<String, NV> RSA_KEY_PARAMS = Collections.unmodifiableMap(new HashMap<String, NV>() {{
put("-1",
new NV("n"));
put("-2",
new NV("e"));
put("-3",
new NV("d"));
put("-4",
new NV("p"));
put("-5",
new NV("q"));
put("-6",
new NV("dp"));
put("-7",
new NV("dq"));
put("-8",
new NV("qi"));
put("-9",
new NV("other"));
put("-10",
new NV("r_i"));
put("-11",
new NV("d_i"));
put("-12",
new NV("t_i"));
}});
private static final Map<String, Map<String, NV>> KEY_PARAMS = Collections.unmodifiableMap(new HashMap<String, Map<String, NV>>() {{
put("OKP", OKP_KEY_PARAMS);
put("EC", EC_KEY_PARAMS);
put("RSA", RSA_KEY_PARAMS);
}});
public static JWK toJWK(Iterable<Map.Entry<String, Object>> coseMap) {
JsonObject retKey = new JsonObject();
Map<String, String> extraMap = new HashMap<>();
for (Map.Entry<String, Object> kv : coseMap) {
String key = kv.getKey();
String value = kv.getValue().toString();
if (!COSE_LABELS.containsKey(key)) {
extraMap.put(key, value);
continue;
}
String name = COSE_LABELS.get(key).name;
if (COSE_LABELS.get(key).values.containsKey(value)) {
value = COSE_LABELS.get(key).values.get(value);
}
retKey.put(name, value);
}
Map<String, NV> keyParams = KEY_PARAMS.get(retKey.getString("kty"));
for (Map.Entry<String, String> kv : extraMap.entrySet()) {
String key = kv.getKey();
String value = kv.getValue();
if (!keyParams.containsKey(key)) {
throw new RuntimeException("unknown COSE key label: " + retKey.getString("kty") + " " + key);
}
String name = keyParams.get(key).name;
if (keyParams.get(key).values.containsKey(value)) {
value = keyParams.get(key).values.get(value);
}
retKey.put(name, value);
}
return new JWK(retKey);
}
}