moved jwk/x509 publishing over to nimbus-jose (mostly)
parent
fca30cd13f
commit
10ab55a7e2
|
@ -16,11 +16,18 @@
|
|||
package org.mitre.jwt.signer.service;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.util.Map;
|
||||
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
public interface JwtSigningAndValidationService {
|
||||
|
||||
/**
|
||||
* Get all public keys for this service, mapped by their ID
|
||||
*/
|
||||
public Map<String, PublicKey> getAllPublicKeys();
|
||||
|
||||
/**
|
||||
* Checks the signature of the given JWT against all configured signers,
|
||||
* returns true if at least one of the signers validates it.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.mitre.jwt.signer.service.impl;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -30,6 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import com.nimbusds.jose.JOSEException;
|
||||
import com.nimbusds.jose.JWSSigner;
|
||||
import com.nimbusds.jose.JWSVerifier;
|
||||
import com.nimbusds.jose.crypto.RSASSAVerifier;
|
||||
import com.nimbusds.jwt.SignedJWT;
|
||||
|
||||
public class DefaultJwtSigningAndValidationService implements JwtSigningAndValidationService, InitializingBean {
|
||||
|
@ -133,4 +135,20 @@ public class DefaultJwtSigningAndValidationService implements JwtSigningAndValid
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, PublicKey> getAllPublicKeys() {
|
||||
Map<String, PublicKey> keys = new HashMap<String, PublicKey>();
|
||||
|
||||
// pull all keys out of the verifiers if we know how
|
||||
for (String keyId : verifiers.keySet()) {
|
||||
JWSVerifier verifier = verifiers.get(keyId);
|
||||
if (verifier instanceof RSASSAVerifier) {
|
||||
// we know how to do RSA public keys
|
||||
keys.put(keyId, ((RSASSAVerifier) verifier).getPublicKey());
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mitre.openid.connect.view;
|
|||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.math.BigInteger;
|
||||
import java.security.PublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -28,8 +29,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.mitre.jwt.signer.JwtSigner;
|
||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -78,22 +77,19 @@ public class JwkKeyListView extends AbstractView {
|
|||
|
||||
|
||||
//BiMap<String, PublicKey> keyMap = (BiMap<String, PublicKey>) model.get("keys");
|
||||
Map<String, JwtSigner> signers = (Map<String, JwtSigner>) model.get("signers");
|
||||
Map<String, PublicKey> keys = (Map<String, PublicKey>) model.get("keys");
|
||||
|
||||
JsonObject obj = new JsonObject();
|
||||
JsonArray keys = new JsonArray();
|
||||
obj.add("keys", keys);
|
||||
JsonArray keyList = new JsonArray();
|
||||
obj.add("keys", keyList);
|
||||
|
||||
for (String keyId : signers.keySet()) {
|
||||
for (String keyId : keys.keySet()) {
|
||||
|
||||
JwtSigner src = signers.get(keyId);
|
||||
PublicKey key = keys.get(keyId);
|
||||
|
||||
if (src instanceof RsaSigner) {
|
||||
|
||||
RsaSigner rsaSigner = (RsaSigner) src;
|
||||
|
||||
RSAPublicKey rsa = (RSAPublicKey) rsaSigner.getPublicKey(); // we're sure this is an RSAPublicKey b/c this is an RsaSigner
|
||||
if (key instanceof RSAPublicKey) {
|
||||
|
||||
RSAPublicKey rsa = (RSAPublicKey) key;
|
||||
|
||||
BigInteger mod = rsa.getModulus();
|
||||
BigInteger exp = rsa.getPublicExponent();
|
||||
|
@ -109,7 +105,7 @@ public class JwkKeyListView extends AbstractView {
|
|||
o.addProperty("exp", e64);
|
||||
o.addProperty("kid", keyId);
|
||||
|
||||
keys.add(o);
|
||||
keyList.add(o);
|
||||
} // TODO: deal with non-RSA key types
|
||||
}
|
||||
|
||||
|
|
|
@ -8,32 +8,21 @@ import java.io.OutputStreamWriter;
|
|||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.bouncycastle.asn1.DERObjectIdentifier;
|
||||
import org.bouncycastle.asn1.x509.BasicConstraints;
|
||||
import org.bouncycastle.asn1.x509.X509Extensions;
|
||||
import org.bouncycastle.jce.X509Principal;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.bouncycastle.x509.X509V3CertificateGenerator;
|
||||
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
|
||||
import org.mitre.jwt.signer.JwtSigner;
|
||||
import org.mitre.jwt.signer.impl.RsaSigner;
|
||||
import org.mitre.openid.connect.config.ConfigurationPropertiesBean;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -41,10 +30,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
|
@ -65,20 +50,20 @@ public class X509CertificateView extends AbstractView {
|
|||
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
Map<String, JwtSigner> signers = (Map<String, JwtSigner>) model.get("signers");
|
||||
Map<String, PublicKey> keys = (Map<String, PublicKey>) model.get("keys");
|
||||
|
||||
response.setContentType("application/x-pem-file");
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream());
|
||||
PEMWriter pemWriter = new PEMWriter(writer);
|
||||
|
||||
for (String keyId : signers.keySet()) {
|
||||
for (String keyId : keys.keySet()) {
|
||||
|
||||
JwtSigner src = signers.get(keyId);
|
||||
PublicKey key = keys.get(keyId);
|
||||
|
||||
if (src instanceof RsaSigner) {
|
||||
if (key instanceof RSAPublicKey) {
|
||||
|
||||
RsaSigner rsaSigner = (RsaSigner) src;
|
||||
RSAPublicKey rsa = (RSAPublicKey) key;
|
||||
|
||||
X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
|
||||
|
||||
|
@ -88,9 +73,11 @@ public class X509CertificateView extends AbstractView {
|
|||
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * daysNotValidAfter )));
|
||||
v3CertGen.setSubjectDN(new X509Principal("CN=" + config.getIssuer() + ", OU=None, O=None L=None, C=None"));
|
||||
|
||||
v3CertGen.setPublicKey(rsaSigner.getPublicKey());
|
||||
v3CertGen.setPublicKey(key);
|
||||
v3CertGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
|
||||
|
||||
// FIXME: need to get the private keys over here, too, or make one up
|
||||
/*
|
||||
try {
|
||||
X509Certificate cert = v3CertGen.generate(rsaSigner.getPrivateKey());
|
||||
pemWriter.writeObject(cert);
|
||||
|
@ -108,7 +95,7 @@ public class X509CertificateView extends AbstractView {
|
|||
pemWriter.flush();
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
******************************************************************************/
|
||||
package org.mitre.openid.connect.web;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mitre.jwt.signer.JwtSigner;
|
||||
import org.mitre.jwt.signer.service.JwtSigningAndValidationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -34,21 +34,21 @@ public class JsonWebKeyEndpoint {
|
|||
public ModelAndView getJwk() {
|
||||
|
||||
// map from key id to signer
|
||||
Map<String, JwtSigner> signers = jwtService.getAllSigners();
|
||||
Map<String, PublicKey> keys = jwtService.getAllPublicKeys();
|
||||
|
||||
// TODO: check if keys are empty, return a 404 here or just an empty list?
|
||||
|
||||
return new ModelAndView("jwkKeyList", "signers", signers);
|
||||
return new ModelAndView("jwkKeyList", "keys", keys);
|
||||
}
|
||||
|
||||
@RequestMapping("/x509")
|
||||
public ModelAndView getX509() {
|
||||
// map from key id to signer
|
||||
Map<String, JwtSigner> signers = jwtService.getAllSigners();
|
||||
Map<String, PublicKey> keys = jwtService.getAllPublicKeys();
|
||||
|
||||
// TODO: check if keys are empty, return a 404 here or just an empty list?
|
||||
|
||||
return new ModelAndView("x509certs", "signers", signers);
|
||||
return new ModelAndView("x509certs", "keys", keys);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue