moved jwk/x509 publishing over to nimbus-jose (mostly)

pull/306/merge
Justin Richer 2013-02-19 15:59:34 -05:00
parent fca30cd13f
commit 10ab55a7e2
5 changed files with 49 additions and 41 deletions

View File

@ -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.

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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();
}
*/
}

View File

@ -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);
}
/**