mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Add ECDSA as a valid key type that should return EC public key
Closes #42588 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
9f9f5ae97a
commit
5732946388
@ -33,6 +33,7 @@ public class JavaAlgorithm {
|
|||||||
public static final String Ed25519 = "Ed25519";
|
public static final String Ed25519 = "Ed25519";
|
||||||
public static final String Ed448 = "Ed448";
|
public static final String Ed448 = "Ed448";
|
||||||
public static final String AES = "AES";
|
public static final String AES = "AES";
|
||||||
|
public static final String ECDSA = "ECDSA";
|
||||||
|
|
||||||
public static final String SHA256 = "SHA-256";
|
public static final String SHA256 = "SHA-256";
|
||||||
public static final String SHA384 = "SHA-384";
|
public static final String SHA384 = "SHA-384";
|
||||||
@ -135,6 +136,7 @@ public class JavaAlgorithm {
|
|||||||
case KeyType.RSA:
|
case KeyType.RSA:
|
||||||
return KeyType.RSA;
|
return KeyType.RSA;
|
||||||
case KeyType.EC:
|
case KeyType.EC:
|
||||||
|
case ECDSA:
|
||||||
return KeyType.EC;
|
return KeyType.EC;
|
||||||
case Algorithm.EdDSA:
|
case Algorithm.EdDSA:
|
||||||
case Algorithm.Ed448:
|
case Algorithm.Ed448:
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -29,6 +30,7 @@ import java.io.InputStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.security.KeyFactory;
|
import java.security.KeyFactory;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
@ -221,6 +223,7 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
|||||||
.id(KeycloakModelUtils.generateId())
|
.id(KeycloakModelUtils.generateId())
|
||||||
.clientId("client3")
|
.clientId("client3")
|
||||||
.directAccessGrants()
|
.directAccessGrants()
|
||||||
|
.redirectUris(OAuthClient.APP_ROOT + "/auth")
|
||||||
.authenticatorType(JWTClientAuthenticator.PROVIDER_ID)
|
.authenticatorType(JWTClientAuthenticator.PROVIDER_ID)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -230,22 +233,7 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testCodeToTokenRequestSuccess(String algorithm) throws Exception {
|
public void testCodeToTokenRequestSuccess(String algorithm) throws Exception {
|
||||||
oauth.clientId("client2");
|
testCodeToTokenRequestSuccess("client2", getClient2KeyPair(), algorithm, null);
|
||||||
oauth.doLogin("test-user@localhost", "password");
|
|
||||||
EventRepresentation loginEvent = events.expectLogin()
|
|
||||||
.client("client2")
|
|
||||||
.assertEvent();
|
|
||||||
|
|
||||||
String code = oauth.parseLoginResponse().getCode();
|
|
||||||
AccessTokenResponse response = doAccessTokenRequest(code, getClient2SignedJWT(algorithm));
|
|
||||||
|
|
||||||
assertEquals(200, response.getStatusCode());
|
|
||||||
oauth.verifyToken(response.getAccessToken());
|
|
||||||
oauth.parseRefreshToken(response.getRefreshToken());
|
|
||||||
events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID), loginEvent.getSessionId())
|
|
||||||
.client("client2")
|
|
||||||
.detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID)
|
|
||||||
.assertEvent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCodeToTokenRequestSuccessForceAlgInClient(String algorithm) throws Exception {
|
public void testCodeToTokenRequestSuccessForceAlgInClient(String algorithm) throws Exception {
|
||||||
@ -294,43 +282,62 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testUploadCertificatePEM(KeyPair keyPair, String algorithm, String curve) throws Exception {
|
||||||
|
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.BCFKS);
|
||||||
|
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.BCFKS, "clientkey", "pwd2", "keypass", keyPair);
|
||||||
|
try {
|
||||||
|
Path tempFile = Files.createTempFile("cert_", ".pem");
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(tempFile)) {
|
||||||
|
writer.write(ksInfo.getCertificateInfo().getCertificate());
|
||||||
|
}
|
||||||
|
testUploadKeystore(org.keycloak.services.resources.admin.ClientAttributeCertificateResource.CERTIFICATE_PEM,
|
||||||
|
tempFile.toFile().getAbsolutePath(), "undefined", "undefined");
|
||||||
|
Files.delete(tempFile);
|
||||||
|
|
||||||
|
testCodeToTokenRequestSuccess("client3", keyPair, algorithm, curve);
|
||||||
|
} finally {
|
||||||
|
ksInfo.getKeystoreFile().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void testUploadPublicKeyPem(KeyPair keyPair, String algorithm, String curve) throws Exception {
|
||||||
|
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.BCFKS);
|
||||||
|
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.BCFKS, "clientkey", "pwd2", "keypass", keyPair);
|
||||||
|
try {
|
||||||
|
Path tempFile = Files.createTempFile("pubkey_", ".pem");
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(tempFile)) {
|
||||||
|
writer.write(ksInfo.getCertificateInfo().getPublicKey());
|
||||||
|
}
|
||||||
|
testUploadKeystore(org.keycloak.services.resources.admin.ClientAttributeCertificateResource.PUBLIC_KEY_PEM,
|
||||||
|
tempFile.toFile().getAbsolutePath(), "undefined", "undefined");
|
||||||
|
Files.delete(tempFile);
|
||||||
|
|
||||||
|
testCodeToTokenRequestSuccess("client3", keyPair, algorithm, curve);
|
||||||
|
} finally {
|
||||||
|
ksInfo.getKeystoreFile().delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void testCodeToTokenRequestSuccess(String algorithm, boolean useJwksUri) throws Exception {
|
protected void testCodeToTokenRequestSuccess(String algorithm, boolean useJwksUri) throws Exception {
|
||||||
testCodeToTokenRequestSuccess(algorithm, null, useJwksUri);
|
testCodeToTokenRequestSuccess(algorithm, null, useJwksUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyPair setupKeyPair(ClientRepresentation clientRepresentation, ClientResource clientResource,
|
||||||
|
String algorithm, String curve, boolean useJwksUri) throws Exception {
|
||||||
|
if (useJwksUri) {
|
||||||
|
return setupJwksUrl(algorithm, curve, true, false, null, clientRepresentation, clientResource);
|
||||||
|
} else {
|
||||||
|
return setupJwks(algorithm, curve, clientRepresentation, clientResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void testCodeToTokenRequestSuccess(String algorithm, String curve, boolean useJwksUri) throws Exception {
|
protected void testCodeToTokenRequestSuccess(String algorithm, String curve, boolean useJwksUri) throws Exception {
|
||||||
ClientRepresentation clientRepresentation = app2;
|
ClientRepresentation clientRepresentation = app2;
|
||||||
ClientResource clientResource = getClient(testRealm.getRealm(), clientRepresentation.getId());
|
ClientResource clientResource = getClient(testRealm.getRealm(), clientRepresentation.getId());
|
||||||
clientRepresentation = clientResource.toRepresentation();
|
clientRepresentation = clientResource.toRepresentation();
|
||||||
try {
|
try {
|
||||||
// setup Jwks
|
KeyPair keyPair = setupKeyPair(clientRepresentation, clientResource, algorithm, curve, useJwksUri);
|
||||||
KeyPair keyPair;
|
testCodeToTokenRequestSuccess("client2", keyPair, algorithm, curve);
|
||||||
if (useJwksUri) {
|
|
||||||
keyPair = setupJwksUrl(algorithm, curve, true, false, null, clientRepresentation, clientResource);
|
|
||||||
} else {
|
|
||||||
keyPair = setupJwks(algorithm, curve, clientRepresentation, clientResource);
|
|
||||||
}
|
|
||||||
PublicKey publicKey = keyPair.getPublic();
|
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
|
||||||
|
|
||||||
// test
|
|
||||||
oauth.clientId("client2");
|
|
||||||
oauth.doLogin("test-user@localhost", "password");
|
|
||||||
EventRepresentation loginEvent = events.expectLogin()
|
|
||||||
.client("client2")
|
|
||||||
.assertEvent();
|
|
||||||
|
|
||||||
String code = oauth.parseLoginResponse().getCode();
|
|
||||||
AccessTokenResponse response = doAccessTokenRequest(code,
|
|
||||||
createSignedRequestToken("client2", getRealmInfoUrl(), privateKey, publicKey, algorithm, curve));
|
|
||||||
|
|
||||||
assertEquals(200, response.getStatusCode());
|
|
||||||
oauth.verifyToken(response.getAccessToken());
|
|
||||||
oauth.parseRefreshToken(response.getRefreshToken());
|
|
||||||
events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID), loginEvent.getSessionId())
|
|
||||||
.client("client2")
|
|
||||||
.detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID)
|
|
||||||
.assertEvent();
|
|
||||||
} finally {
|
} finally {
|
||||||
// Revert jwks settings
|
// Revert jwks settings
|
||||||
if (useJwksUri) {
|
if (useJwksUri) {
|
||||||
@ -341,6 +348,30 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void testCodeToTokenRequestSuccess(String clientId, KeyPair keyPair, String algorithm, String curve) throws Exception {
|
||||||
|
PublicKey publicKey = keyPair.getPublic();
|
||||||
|
PrivateKey privateKey = keyPair.getPrivate();
|
||||||
|
|
||||||
|
// test
|
||||||
|
oauth.realm("test").clientId(clientId);
|
||||||
|
oauth.doLogin("test-user@localhost", "password");
|
||||||
|
EventRepresentation loginEvent = events.expectLogin()
|
||||||
|
.client(clientId)
|
||||||
|
.assertEvent();
|
||||||
|
|
||||||
|
String code = oauth.parseLoginResponse().getCode();
|
||||||
|
AccessTokenResponse response = doAccessTokenRequest(code,
|
||||||
|
createSignedRequestToken(clientId, getRealmInfoUrl(), privateKey, publicKey, algorithm, curve));
|
||||||
|
|
||||||
|
assertEquals(200, response.getStatusCode());
|
||||||
|
oauth.verifyToken(response.getAccessToken());
|
||||||
|
oauth.parseRefreshToken(response.getRefreshToken());
|
||||||
|
events.expectCodeToToken(loginEvent.getDetails().get(Details.CODE_ID), loginEvent.getSessionId())
|
||||||
|
.client(clientId)
|
||||||
|
.detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID)
|
||||||
|
.assertEvent();
|
||||||
|
}
|
||||||
|
|
||||||
protected void testDirectGrantRequestSuccess(String algorithm) throws Exception {
|
protected void testDirectGrantRequestSuccess(String algorithm) throws Exception {
|
||||||
ClientRepresentation clientRepresentation = app2;
|
ClientRepresentation clientRepresentation = app2;
|
||||||
ClientResource clientResource = getClient(testRealm.getRealm(), clientRepresentation.getId());
|
ClientResource clientResource = getClient(testRealm.getRealm(), clientRepresentation.getId());
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package org.keycloak.testsuite.oauth;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.crypto.Algorithm;
|
import org.keycloak.crypto.Algorithm;
|
||||||
|
import org.keycloak.testsuite.util.KeyUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:takashi.norimatsu.ws@hitachi.com">Takashi Norimatsu</a>
|
* @author <a href="mailto:takashi.norimatsu.ws@hitachi.com">Takashi Norimatsu</a>
|
||||||
@ -35,6 +36,26 @@ public class ClientAuthEdDSASignedJWTTest extends AbstractClientAuthSignedJWTTes
|
|||||||
testCodeToTokenRequestSuccess(Algorithm.EdDSA, Algorithm.Ed25519, false);
|
testCodeToTokenRequestSuccess(Algorithm.EdDSA, Algorithm.Ed25519, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadCertificatePemEd25519() throws Exception {
|
||||||
|
testUploadCertificatePEM(KeyUtils.generateEdDSAKey(Algorithm.Ed25519), Algorithm.EdDSA, Algorithm.Ed25519);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadCertificatePemEd448() throws Exception {
|
||||||
|
testUploadCertificatePEM(KeyUtils.generateEdDSAKey(Algorithm.Ed448), Algorithm.EdDSA, Algorithm.Ed448);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadPublicKeyPemEd25519() throws Exception {
|
||||||
|
testUploadPublicKeyPem(KeyUtils.generateEdDSAKey(Algorithm.Ed25519), Algorithm.EdDSA, Algorithm.Ed25519);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadPublicKeyPemEd448() throws Exception {
|
||||||
|
testUploadPublicKeyPem(KeyUtils.generateEdDSAKey(Algorithm.Ed448), Algorithm.EdDSA, Algorithm.Ed448);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getKeyAlgorithmFromJwaAlgorithm(String jwaAlgorithm, String curve) {
|
protected String getKeyAlgorithmFromJwaAlgorithm(String jwaAlgorithm, String curve) {
|
||||||
if (!Algorithm.EdDSA.equals(jwaAlgorithm)) {
|
if (!Algorithm.EdDSA.equals(jwaAlgorithm)) {
|
||||||
|
|||||||
@ -46,6 +46,7 @@ import org.keycloak.testsuite.Assert;
|
|||||||
import org.keycloak.testsuite.admin.ApiUtil;
|
import org.keycloak.testsuite.admin.ApiUtil;
|
||||||
import org.keycloak.testsuite.util.ClientManager;
|
import org.keycloak.testsuite.util.ClientManager;
|
||||||
import org.keycloak.testsuite.util.KeystoreUtils;
|
import org.keycloak.testsuite.util.KeystoreUtils;
|
||||||
|
import org.keycloak.testsuite.util.KeyUtils;
|
||||||
import org.keycloak.testsuite.util.SignatureSignerUtil;
|
import org.keycloak.testsuite.util.SignatureSignerUtil;
|
||||||
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
||||||
|
|
||||||
@ -361,30 +362,53 @@ public class ClientAuthSignedJWTTest extends AbstractClientAuthSignedJWTTest {
|
|||||||
public void testUploadKeystoreJKS() throws Exception {
|
public void testUploadKeystoreJKS() throws Exception {
|
||||||
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.JKS);
|
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.JKS);
|
||||||
testUploadKeystore("JKS", generatedKeystoreClient1.getKeystoreFile().getAbsolutePath(), "clientkey", "storepass");
|
testUploadKeystore("JKS", generatedKeystoreClient1.getKeystoreFile().getAbsolutePath(), "clientkey", "storepass");
|
||||||
|
testCodeToTokenRequestSuccess("client3", keyPairClient1, Algorithm.RS256, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUploadKeystorePKCS12() throws Exception {
|
public void testUploadKeystorePKCS12() throws Exception {
|
||||||
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.PKCS12);
|
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.PKCS12);
|
||||||
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.PKCS12, "clientkey", "pwd2", "keypass");
|
KeyPair keyPair = org.keycloak.common.util.KeyUtils.generateRsaKeyPair(2048);
|
||||||
testUploadKeystore(KeystoreFormat.PKCS12.toString(), ksInfo.getKeystoreFile().getAbsolutePath(), "clientkey", "pwd2");
|
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.PKCS12, "clientkey", "pwd2", "keypass", keyPair);
|
||||||
|
try {
|
||||||
|
testUploadKeystore(KeystoreFormat.PKCS12.toString(), ksInfo.getKeystoreFile().getAbsolutePath(), "clientkey", "pwd2");
|
||||||
|
testCodeToTokenRequestSuccess("client3", keyPair, Algorithm.RS256, null);
|
||||||
|
} finally {
|
||||||
|
ksInfo.getKeystoreFile().delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUploadKeystoreBCFKS() throws Exception {
|
public void testUploadKeystoreBCFKS() throws Exception {
|
||||||
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.BCFKS);
|
KeystoreUtils.assumeKeystoreTypeSupported(KeystoreFormat.BCFKS);
|
||||||
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.BCFKS, "clientkey", "pwd2", "keypass");
|
KeyPair keyPair = org.keycloak.common.util.KeyUtils.generateRsaKeyPair(2048);
|
||||||
testUploadKeystore(KeystoreFormat.BCFKS.toString(), ksInfo.getKeystoreFile().getAbsolutePath(), "clientkey", "pwd2");
|
KeystoreUtils.KeystoreInfo ksInfo = KeystoreUtils.generateKeystore(folder, KeystoreFormat.BCFKS, "clientkey", "pwd2", "keypass", keyPair);
|
||||||
|
try {
|
||||||
|
testUploadKeystore(KeystoreFormat.BCFKS.toString(), ksInfo.getKeystoreFile().getAbsolutePath(), "clientkey", "pwd2");
|
||||||
|
testCodeToTokenRequestSuccess("client3", keyPair, Algorithm.RS256, null);
|
||||||
|
} finally {
|
||||||
|
ksInfo.getKeystoreFile().delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUploadCertificatePEM() throws Exception {
|
public void testUploadCertificatePemRsa() throws Exception {
|
||||||
testUploadKeystore(org.keycloak.services.resources.admin.ClientAttributeCertificateResource.CERTIFICATE_PEM, "client-auth-test/certificate.pem", "undefined", "undefined");
|
testUploadCertificatePEM(org.keycloak.common.util.KeyUtils.generateRsaKeyPair(2048), Algorithm.RS256, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUploadPublicKeyPEM() throws Exception {
|
public void testUploadCertificatePemEcdsa() throws Exception {
|
||||||
testUploadKeystore(org.keycloak.services.resources.admin.ClientAttributeCertificateResource.PUBLIC_KEY_PEM, "client-auth-test/publickey.pem", "undefined", "undefined");
|
testUploadCertificatePEM(KeyUtils.generateECKey(Algorithm.ES256), Algorithm.ES256, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadPublicKeyPemRsa() throws Exception {
|
||||||
|
testUploadPublicKeyPem(org.keycloak.common.util.KeyUtils.generateRsaKeyPair(2048), Algorithm.RS256, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUploadPublicKeyPemEcdsa() throws Exception {
|
||||||
|
testUploadPublicKeyPem(KeyUtils.generateECKey(Algorithm.ES256), Algorithm.ES256, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -1,21 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDXTCCAkWgAwIBAgIJAIzE3vQp7EQWMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
|
||||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
|
||||||
aWRnaXRzIFB0eSBMdGQwHhcNMTYwMjI5MDgzMDU0WhcNNDMwNzE2MDgzMDU0WjBF
|
|
||||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
|
||||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
||||||
CgKCAQEAp1+GzdEkt2FZbISXYO12503FL6Oh8s4+tJ2fE66N8IezhugP8xiySDfW
|
|
||||||
TEMaO5Z2TaTnQQoF9SSZ9Edq1GPxpBX0cdkCOBopEGdlb3hUYDeMaDMs18KGemUc
|
|
||||||
Fj+CWB5VVcbmWMJ36WCz7FC+Oe38tmujR1AJpJL3pwqazyWIZzPqX8rW+rrNPGKP
|
|
||||||
C96oBPZMb4RJWivLBJi/o5MGSpo1sJNtxyF4zUUI00LX0wZAV1HH1XErd1Vz41on
|
|
||||||
nmB+tj9nevVRR4rDV280IELp9Ud0PIb3w843uJtwfSAwVG0pT6hv1VBDrBxTS08N
|
|
||||||
dPU8CtkQAXzCCr8nqfAbUFOhcWRQgQIDAQABo1AwTjAdBgNVHQ4EFgQUFE+uUZAI
|
|
||||||
n57ArEylqhCmHkAenTEwHwYDVR0jBBgwFoAUFE+uUZAIn57ArEylqhCmHkAenTEw
|
|
||||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEApkgD3OCtw3+sk7GR1YaJ
|
|
||||||
xNd8HT+fxXmnLqGnCQWX8lRIg5vj1PDMRev6vlIK3JfQV3zajcpKFfpy96klWsJy
|
|
||||||
ZLYBVW2QOtMzDdQ9I8dS4Pn/SJ/Vo/M/ucfY4ttcuUL3oQCrI/c/u9tcamGMfbwd
|
|
||||||
658MlXrUvt4B6qXY5AbgUvYR25P86uw7hSFMq5tQftNQsLbOh2FEeIiKhpgI7w8S
|
|
||||||
SPajaWjUXsfHc5H7f9MciE2NS1Vd3AViGrVWP1rgQ1Iv0UyQVQrnjmIs12ENJmTd
|
|
||||||
5lDqra5FJhaO7+RUG6er8n8HwXzhHkPmezGqtxWKikjitqvDY9prB3omJSa4Led+
|
|
||||||
AQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
-----BEGIN PUBLIC KEY-----
|
|
||||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApnZ/E2BUULHjsRiSnEgZ
|
|
||||||
4vGe15BRqZPdkHR+NcvVYpThc7JqY6nZrdrwO9sOjlMC5e2Q18Fypi4KbJpGSe9r
|
|
||||||
0DPgcbPsHSoe2xFO3M8XBE0DyoRblaQFhe6p/sj3ak32k2zn+fMZUmlx/MTNQh1I
|
|
||||||
Cki7So0NDCBXt8XGZNnEyvKeXOUZP5qicP9KxVAQiWJvlkaTjc8rrRTmf+HWw/Qf
|
|
||||||
gQC0tzBRpa7T+RpW9O+rnWfOaNfTkTb9itIc+ZOa2Z4iidZ7+ifMOp9cNT641Wb6
|
|
||||||
iYqJ2ufqY+msxI54tYM1tPgGS7r4SnCwmnqTaO383wXUl8TQ7qStmAWIepV3nNyu
|
|
||||||
AQIDAQAB
|
|
||||||
-----END PUBLIC KEY-----
|
|
||||||
Loading…
x
Reference in New Issue
Block a user