KEYCLOAK-9868 x5t and x5t#S256 JWK parameters
This commit is contained in:
parent
c6bd293d25
commit
d5cc18b960
4 changed files with 80 additions and 4 deletions
|
@ -23,9 +23,7 @@ import org.bouncycastle.openssl.PEMWriter;
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
|
@ -157,4 +155,12 @@ public final class PemUtils {
|
|||
return pem.trim();
|
||||
}
|
||||
|
||||
public static String generateThumbprint(String[] certChain, String encoding) throws NoSuchAlgorithmException, IOException {
|
||||
return Base64Url.encode(generateThumbprintBytes(certChain, encoding));
|
||||
}
|
||||
|
||||
static byte[] generateThumbprintBytes(String[] certChain, String encoding) throws NoSuchAlgorithmException, IOException {
|
||||
return MessageDigest.getInstance(encoding).digest(pemToDer(certChain[0]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package org.keycloak.common.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class PemUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGenerateThumbprintBytesSha1() throws IOException, NoSuchAlgorithmException {
|
||||
String[] test = new String[] {"abcdefg"};
|
||||
byte[] digest = PemUtils.generateThumbprintBytes(test, "SHA-1");
|
||||
assertEquals(20, digest.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateThumbprintBytesSha256() throws IOException, NoSuchAlgorithmException {
|
||||
String[] test = new String[] {"abcdefg"};
|
||||
byte[] digest = PemUtils.generateThumbprintBytes(test, "SHA-256");
|
||||
assertEquals(32, digest.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateThumbprintSha1() throws IOException, NoSuchAlgorithmException {
|
||||
String[] test = new String[] {"abcdefg"};
|
||||
String encoded = PemUtils.generateThumbprint(test, "SHA-1");
|
||||
assertEquals(27, encoded.length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerateThumbprintSha256() throws IOException, NoSuchAlgorithmException {
|
||||
String[] test = new String[] {"abcdefg"};
|
||||
String encoded = PemUtils.generateThumbprint(test, "SHA-256");
|
||||
assertEquals(43, encoded.length());
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,10 @@
|
|||
package org.keycloak.jose.jwk;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
|
@ -38,7 +42,11 @@ public class RSAPublicJWK extends JWK {
|
|||
|
||||
@JsonProperty("x5c")
|
||||
private String[] x509CertificateChain;
|
||||
|
||||
|
||||
private String sha1x509Thumbprint;
|
||||
|
||||
private String sha256x509Thumbprint;
|
||||
|
||||
public String getModulus() {
|
||||
return modulus;
|
||||
}
|
||||
|
@ -61,6 +69,24 @@ public class RSAPublicJWK extends JWK {
|
|||
|
||||
public void setX509CertificateChain(String[] x509CertificateChain) {
|
||||
this.x509CertificateChain = x509CertificateChain;
|
||||
if (x509CertificateChain != null && x509CertificateChain.length > 0) {
|
||||
try {
|
||||
sha1x509Thumbprint = PemUtils.generateThumbprint(x509CertificateChain, "SHA-1");
|
||||
sha256x509Thumbprint = PemUtils.generateThumbprint(x509CertificateChain, "SHA-256");
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonProperty("x5t")
|
||||
public String getSha1x509Thumbprint() {
|
||||
return sha1x509Thumbprint;
|
||||
}
|
||||
|
||||
@JsonProperty("x5t#S256")
|
||||
public String getSha256x509Thumbprint() {
|
||||
return sha256x509Thumbprint;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@ public class JWKTest {
|
|||
assertNotNull(((RSAPublicJWK) jwk).getPublicExponent());
|
||||
assertNotNull(((RSAPublicJWK) jwk).getX509CertificateChain());
|
||||
assertEquals(PemUtils.encodeCertificate(certificate), ((RSAPublicJWK) jwk).getX509CertificateChain()[0]);
|
||||
assertNotNull(((RSAPublicJWK) jwk).getSha1x509Thumbprint());
|
||||
assertEquals(PemUtils.generateThumbprint(((RSAPublicJWK) jwk).getX509CertificateChain(), "SHA-1"), ((RSAPublicJWK) jwk).getSha1x509Thumbprint());
|
||||
assertNotNull(((RSAPublicJWK) jwk).getSha256x509Thumbprint());
|
||||
assertEquals(PemUtils.generateThumbprint(((RSAPublicJWK) jwk).getX509CertificateChain(), "SHA-256"), ((RSAPublicJWK) jwk).getSha256x509Thumbprint());
|
||||
|
||||
String jwkJson = JsonSerialization.writeValueAsString(jwk);
|
||||
|
||||
|
|
Loading…
Reference in a new issue