package net.oauth.jsontoken.discovery;
import com.google.common.collect.Lists;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.oauth.jsontoken.crypto.RsaSHA256Verifier;
import net.oauth.jsontoken.crypto.Verifier;
import org.apache.commons.codec.binary.Base64;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
/**
* Simple certificates finder by fetching from URL. Expects simple json
* format, for example:
* {"keyid":"x509 certificate in Pem format", "keyid2":"x509 certificate in Pem format"..}
*/
public class UrlBasedVerifierProvider implements VerifierProvider {
private final String publicCertUrl;
public UrlBasedVerifierProvider(String publicCertUrl) {
this.publicCertUrl = publicCertUrl;
}
@Override
public List<Verifier> findVerifier(String issuer, String keyId) {
try {
URL url = new URL(publicCertUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStreamReader in = new InputStreamReader((InputStream) connection.getContent());
BufferedReader buff = new BufferedReader(in);
StringBuffer content = new StringBuffer();
String line = "";
do {
line = buff.readLine();
content.append(line + "\n");
} while (line != null);
JsonParser parser = new JsonParser();
JsonObject jsonObject = parser.parse(content.toString()).getAsJsonObject();
List<Verifier> verifiers = Lists.newArrayList();
for (Map.Entry<String, JsonElement> cert : jsonObject.entrySet()) {
String x509PemCertString = cert.getValue().getAsString();
// Parse pem format
String[] parts = x509PemCertString.split("\n");
if (parts.length < 3) {
return null;
}
String x509CertString = "";
for (int i = 1; i < parts.length - 1; i++) {
x509CertString += parts[i];
}
// parse x509
byte[] certBytes = Base64.decodeBase64(x509CertString);
CertificateFactory factory = CertificateFactory.getInstance("X509");
X509Certificate x509Cert =
(X509Certificate) factory.generateCertificate(new ByteArrayInputStream(certBytes));
verifiers.add(new RsaSHA256Verifier(x509Cert.getPublicKey()));
}
return verifiers;
} else {
return null;
}
} catch (MalformedURLException e) {
return null;
} catch (IOException e) {
return null;
} catch (CertificateException e) {
return null;
}
}
}