parent
fbae2251e1
commit
ceea11d044
9 changed files with 286 additions and 55 deletions
|
@ -37,6 +37,7 @@ import java.util.List;
|
|||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.crypto.CertificateUtilsProvider;
|
||||
import org.wildfly.security.asn1.ASN1;
|
||||
import org.wildfly.security.asn1.DERDecoder;
|
||||
|
@ -60,6 +61,8 @@ import org.wildfly.security.x500.cert.X509CertificateExtension;
|
|||
*/
|
||||
public class ElytronCertificateUtils implements CertificateUtilsProvider {
|
||||
|
||||
Logger log = Logger.getLogger(getClass());
|
||||
|
||||
/**
|
||||
* Generates version 3 {@link java.security.cert.X509Certificate}.
|
||||
*
|
||||
|
@ -249,16 +252,29 @@ public class ElytronCertificateUtils implements CertificateUtilsProvider {
|
|||
case ASN1.UTF8_STRING_TYPE:
|
||||
distPointUrls.add(der.decodeUtf8String());
|
||||
break;
|
||||
case 0xa0:
|
||||
der.decodeImplicit(0xa0);
|
||||
byte[] edata = der.decodeOctetString();
|
||||
while(!Character.isLetterOrDigit(edata[0])) {
|
||||
edata = Arrays.copyOfRange(edata, 1, edata.length);
|
||||
}
|
||||
distPointUrls.add(new String(edata));
|
||||
case 0xa0: // Decode CRLDistributionPoint FullName list
|
||||
der.startExplicit(0xa0);
|
||||
break;
|
||||
case 0x86: // Decode CRLDistributionPoint FullName
|
||||
der.decodeImplicit(0x86);
|
||||
distPointUrls.add(der.decodeOctetStringAsString());
|
||||
log.debug("Adding Dist point name: " + distPointUrls.get(distPointUrls.size()-1));
|
||||
break;
|
||||
default:
|
||||
der.skipElement();
|
||||
}
|
||||
// Check to see if there is another sequence to process
|
||||
try {
|
||||
if(!der.hasNextElement() && der.peekType() == ASN1.SEQUENCE_TYPE) {
|
||||
der.startSequence();
|
||||
} else if (!der.hasNextElement() && der.peekType() == 0xa0) {
|
||||
der.startExplicit(0xa0);
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
// Just log this error. Likely the Dist points have been parsed, but
|
||||
// the end of the cert is failing to parse.
|
||||
log.warn("There is an issue parsing the certificate for Distribution Points", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.crypto.elytron;
|
|||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.crypto.ECDSACryptoProvider;
|
||||
import org.wildfly.security.asn1.DERDecoder;
|
||||
import org.wildfly.security.asn1.DEREncoder;
|
||||
|
@ -28,6 +29,8 @@ import org.wildfly.security.asn1.DEREncoder;
|
|||
*/
|
||||
public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
|
||||
|
||||
Logger log = Logger.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
public byte[] concatenatedRSToASN1DER(final byte[] signature, int signLength) throws IOException {
|
||||
int len = signLength / 2;
|
||||
|
@ -45,6 +48,7 @@ public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
|
|||
seq.startSequence();
|
||||
seq.encodeInteger(rBigInteger);
|
||||
seq.encodeInteger(sBigInteger);
|
||||
seq.endSequence();
|
||||
|
||||
return seq.getEncoded();
|
||||
|
||||
|
@ -56,13 +60,35 @@ public class ElytronECDSACryptoProvider implements ECDSACryptoProvider {
|
|||
|
||||
DERDecoder der = new DERDecoder(derEncodedSignatureValue);
|
||||
der.startSequence();
|
||||
byte[] r = der.decodeInteger().toByteArray();
|
||||
byte[] s = der.decodeInteger().toByteArray();
|
||||
byte[] r = convertToBytes(der.decodeInteger(),len);
|
||||
byte[] s = convertToBytes(der.decodeInteger(),len);
|
||||
der.endSequence();
|
||||
byte[] concatenatedSignatureValue = new byte[signLength];
|
||||
|
||||
System.arraycopy(r, 0, concatenatedSignatureValue, 0, len);
|
||||
System.arraycopy(s, 0, concatenatedSignatureValue, len, len);
|
||||
|
||||
return concatenatedSignatureValue;
|
||||
}
|
||||
|
||||
// If byte array length doesn't match expected length, copy to new
|
||||
// byte array of the expected length
|
||||
private byte[] convertToBytes(BigInteger decodeInteger, int len) {
|
||||
|
||||
byte[] bytes = decodeInteger.toByteArray();
|
||||
|
||||
if(len < bytes.length) {
|
||||
log.debug("Decoded integer byte length greater than expected.");
|
||||
byte[] t = new byte[len];
|
||||
System.arraycopy(bytes, bytes.length - len, t, 0, len);
|
||||
bytes = t;
|
||||
} else if (len > bytes.length) {
|
||||
log.debug("Decoded integer byte length less than expected.");
|
||||
byte[] t = new byte[len];
|
||||
System.arraycopy(bytes, 0, t, len - bytes.length, bytes.length);
|
||||
bytes = t;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,24 +16,42 @@
|
|||
*/
|
||||
package org.keycloak.crypto.elytron;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CRLReason;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathBuilder;
|
||||
import java.security.cert.CertPathBuilderException;
|
||||
import java.security.cert.CertPathValidator;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertPathValidatorResult;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
import java.security.cert.PKIXCertPathValidatorResult;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.PKIXRevocationChecker;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.utils.OCSPProvider;
|
||||
import org.wildfly.security.asn1.ASN1;
|
||||
|
@ -61,27 +79,42 @@ public class ElytronOCSPProvider extends OCSPProvider {
|
|||
* @throws CertPathValidatorException
|
||||
*/
|
||||
@Override
|
||||
protected OCSPRevocationStatus check(KeycloakSession session, X509Certificate cert, X509Certificate issuerCertificate, List<URI> responderURIs, X509Certificate responderCert, Date date) throws CertPathValidatorException {
|
||||
protected OCSPRevocationStatus check(KeycloakSession session, X509Certificate cert,
|
||||
X509Certificate issuerCertificate, List<URI> responderURIs, X509Certificate responderCert, Date date)
|
||||
throws CertPathValidatorException {
|
||||
if (responderURIs == null || responderURIs.size() == 0)
|
||||
throw new IllegalArgumentException("Need at least one responder");
|
||||
|
||||
try {
|
||||
try {
|
||||
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
trustStore.load(null,"pass".toCharArray());
|
||||
trustStore.setCertificateEntry("trust", cert);
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustStore.load(null, "pass".toCharArray());
|
||||
trustStore.setCertificateEntry("trust", issuerCertificate);
|
||||
|
||||
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
|
||||
PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker();
|
||||
X509CertSelector certSelector = new X509CertSelector();
|
||||
|
||||
X509RevocationTrustManager trustMgr = X509RevocationTrustManager.builder()
|
||||
.setOcspResponderCert(responderCert)
|
||||
.setTrustStore(trustStore)
|
||||
.setTrustManagerFactory(trustManagerFactory)
|
||||
.build()
|
||||
;
|
||||
X509Certificate[] certs = { cert };
|
||||
certSelector.setCertificate(cert);
|
||||
certSelector.setCertificateValid(date);
|
||||
|
||||
X509Certificate[] certs = { cert };
|
||||
trustMgr.checkClientTrusted(certs, cert.getType());
|
||||
} catch (NoSuchAlgorithmException | CertificateException | IOException | KeyStoreException e) {
|
||||
CertPath cp = cf.generateCertPath(Arrays.asList(certs));
|
||||
|
||||
PKIXParameters params = new PKIXBuilderParameters(trustStore, certSelector);
|
||||
|
||||
rc.setOcspResponder(responderURIs.get(0));
|
||||
rc.setOcspResponderCert(responderCert);
|
||||
rc.setOptions(EnumSet.noneOf(PKIXRevocationChecker.Option.class));
|
||||
params.setRevocationEnabled(false);
|
||||
params.addCertPathChecker(rc);
|
||||
|
||||
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params);
|
||||
logger.debug("Certificate validated by CA: " + result.getTrustAnchor().getCAName());
|
||||
|
||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | CertificateException | IOException
|
||||
| KeyStoreException e) {
|
||||
logger.warn("OSCP Response check failed.", e);
|
||||
return unknownStatus();
|
||||
}
|
||||
|
@ -155,6 +188,7 @@ public class ElytronOCSPProvider extends OCSPProvider {
|
|||
}
|
||||
}
|
||||
|
||||
logger.warn("OCSP Responder URIs" + Arrays.toString(responderURIs.toArray()));
|
||||
return responderURIs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.wildfly.security.x500.principal.X500AttributePrincipalDecoder;
|
|||
*/
|
||||
public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractorProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ElytronUserIdentityExtractorProvider.class.getName());
|
||||
private Logger log = Logger.getLogger(this.getClass());
|
||||
|
||||
class X500NameRDNExtractorElytronProvider extends X500NameRDNExtractor {
|
||||
|
||||
|
@ -47,8 +47,13 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
Function<X509Certificate[],Principal> x500Name;
|
||||
|
||||
public X500NameRDNExtractorElytronProvider(String attrName, Function<X509Certificate[], Principal> x500Name) {
|
||||
//this.x500NameStyle = BCStyle.INSTANCE.attrNameToOID(attrName);
|
||||
// The OidsUtil fails to map 'EmailAddress', instead 'E' is mapped to the OID.
|
||||
// TODO: Open an issue with wildfly-elytron to include 'EmailAddress' in the oid mapping
|
||||
if(attrName.equals("EmailAddress")) {
|
||||
attrName = "E";
|
||||
}
|
||||
this.x500NameStyle = OidsUtil.attributeNameToOid(OidsUtil.Category.RDN, attrName);
|
||||
log.debug("Attribute Name: " + attrName + " X500NameStyle OID: " + x500NameStyle);
|
||||
this.x500Name = x500Name;
|
||||
}
|
||||
|
||||
|
@ -59,6 +64,7 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
throw new IllegalArgumentException();
|
||||
|
||||
Principal name = x500Name.apply(certs);
|
||||
log.debug("Principal Name " + name.getName());
|
||||
X500AttributePrincipalDecoder xDecoder = new X500AttributePrincipalDecoder(x500NameStyle);
|
||||
String cn = xDecoder.apply(name);
|
||||
|
||||
|
@ -95,13 +101,14 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
}
|
||||
String subjectName = null;
|
||||
|
||||
logger.info("SubjPrinc " + certs[0].getSubjectX500Principal());
|
||||
log.debug("SubjPrinc " + certs[0].getSubjectX500Principal());
|
||||
Collection<List<?>> subjectAlternativeNames;
|
||||
try {
|
||||
subjectAlternativeNames = certs[0].getSubjectAlternativeNames();
|
||||
if (subjectAlternativeNames == null) {
|
||||
return null;
|
||||
}
|
||||
log.info(Arrays.toString(subjectAlternativeNames.toArray()));
|
||||
for (List<?> sbjAltName : subjectAlternativeNames) {
|
||||
if (sbjAltName == null)
|
||||
continue;
|
||||
|
@ -109,15 +116,13 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
Integer nameType = (Integer) sbjAltName.get(0);
|
||||
|
||||
if (nameType == generalName) {
|
||||
logger.info("sbjAltName Type " + nameType);
|
||||
logger.info("sbjAltName[1]: " + sbjAltName.get(1));
|
||||
|
||||
Object sbjObj = sbjAltName.get(1);
|
||||
|
||||
switch (nameType) {
|
||||
case GeneralName.RFC_822_NAME:
|
||||
case GeneralName.DNS_NAME:
|
||||
case GeneralName.DIRECTORY_NAME:
|
||||
case GeneralName.URI_NAME:
|
||||
subjectName = (String) sbjObj;
|
||||
break;
|
||||
case GeneralName.OTHER_NAME:
|
||||
|
@ -126,12 +131,12 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
boolean upnOidFound = false;
|
||||
while (derDecoder.hasNextElement() && !upnOidFound) {
|
||||
int asn1Type = derDecoder.peekType();
|
||||
logger.info("ASN.1 Type: " + derDecoder.peekType());
|
||||
log.debug("ASN.1 Type: " + derDecoder.peekType());
|
||||
|
||||
switch (asn1Type) {
|
||||
case ASN1.OBJECT_IDENTIFIER_TYPE:
|
||||
String oid = derDecoder.decodeObjectIdentifier();
|
||||
logger.info("OID: " + oid);
|
||||
log.debug("OID: " + oid);
|
||||
if(UPN_OID.equals(oid)) {
|
||||
derDecoder.decodeImplicit(160);
|
||||
byte[] sb = derDecoder.drainElementValue();
|
||||
|
@ -154,22 +159,28 @@ public class ElytronUserIdentityExtractorProvider extends UserIdentityExtractor
|
|||
case ASN1.OCTET_STRING_TYPE:
|
||||
subjectName = derDecoder.decodeOctetStringAsString();
|
||||
break;
|
||||
case 0xa0:
|
||||
derDecoder.startExplicit(asn1Type);
|
||||
break;
|
||||
case ASN1.SEQUENCE_TYPE:
|
||||
derDecoder.startSequence();
|
||||
default:
|
||||
derDecoder.skipElement();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
logger.info("Subject Alt Name: " + subjectName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} catch (CertificateParsingException | UnsupportedEncodingException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
log.error("Failed to parse Subject Name:",e);
|
||||
}
|
||||
|
||||
log.debug("Subject Alt Name: " + subjectName);
|
||||
return subjectName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,22 @@ package org.keycloak.crypto.elytron.test;
|
|||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.util.PemUtils;
|
||||
import org.keycloak.crypto.elytron.ElytronCertificateUtils;
|
||||
import org.wildfly.security.x500.GeneralName;
|
||||
import org.wildfly.security.x500.cert.CRLDistributionPoint;
|
||||
|
@ -46,9 +50,9 @@ public class CRLDistributionPointTest {
|
|||
@Test
|
||||
public void getCrlDistPoint() throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
X509Certificate cert = createCRLcert();
|
||||
X509Certificate cert = createCRLcert(1,1);
|
||||
List<String> expect = new ArrayList<>();
|
||||
expect.add("http://crl.test.com");
|
||||
expect.add("http://crl0.test0.com");
|
||||
|
||||
|
||||
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
|
||||
|
@ -58,16 +62,67 @@ public class CRLDistributionPointTest {
|
|||
|
||||
}
|
||||
|
||||
private X509Certificate createCRLcert() throws CertificateException, NoSuchAlgorithmException {
|
||||
@Test
|
||||
public void getCrlDistPointMultiNames() throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
X509Certificate cert = createCRLcert(1,2);
|
||||
List<String> expect = new ArrayList<>();
|
||||
expect.add("http://crl0.test0.com");
|
||||
expect.add("http://crl0.test1.com");
|
||||
|
||||
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
|
||||
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
|
||||
|
||||
assertArrayEquals(expect.toArray(), crldp.toArray());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMultiCrlDistPointMultiNames() throws CertificateException, NoSuchAlgorithmException, IOException {
|
||||
|
||||
X509Certificate cert = createCRLcert(2,2);
|
||||
List<String> expect = new ArrayList<>();
|
||||
expect.add("http://crl0.test0.com");
|
||||
expect.add("http://crl0.test1.com");
|
||||
expect.add("http://crl1.test0.com");
|
||||
expect.add("http://crl1.test1.com");
|
||||
|
||||
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
|
||||
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
|
||||
|
||||
assertArrayEquals(expect.toArray(), crldp.toArray());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void revokedCertCRLDistTest() throws CertificateException, IOException {
|
||||
X509Certificate cert = revokedCert();
|
||||
List<String> expect = new ArrayList<>();
|
||||
expect.add("http://localhost:8889/empty.crl");
|
||||
expect.add("http://localhost:8889/intermediate-ca.crl");
|
||||
|
||||
ElytronCertificateUtils bcutil = new ElytronCertificateUtils();
|
||||
List<String> crldp = bcutil.getCRLDistributionPoints(cert);
|
||||
|
||||
assertArrayEquals(expect.toArray(), crldp.toArray());
|
||||
|
||||
}
|
||||
|
||||
private X509Certificate createCRLcert(int crldistcount, int namecount) throws CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
X500Principal dn = new X500Principal("CN=testuser,OU=UNIT,O=TST");
|
||||
List<CRLDistributionPoint> distributionPoints = new ArrayList<>();
|
||||
|
||||
List<GeneralName> fullName = new ArrayList<>();
|
||||
fullName.add(new GeneralName.URIName("http://crl.test.com"));
|
||||
DistributionPointName distributionPoint = new FullNameDistributionPointName(fullName);
|
||||
CRLDistributionPoint arg0 = new CRLDistributionPoint(distributionPoint, null, null);
|
||||
distributionPoints.add(arg0);
|
||||
for(int x = 0; x<crldistcount;x++) {
|
||||
List<GeneralName> fullName = new ArrayList<>();
|
||||
for(int y = 0; y<namecount; y++) {
|
||||
fullName.add(new GeneralName.URIName("http://crl"+x+".test"+y+".com"));
|
||||
}
|
||||
DistributionPointName distributionPoint = new FullNameDistributionPointName(fullName);
|
||||
CRLDistributionPoint arg0 = new CRLDistributionPoint(distributionPoint, null, null);
|
||||
distributionPoints.add(arg0);
|
||||
|
||||
}
|
||||
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").genKeyPair();
|
||||
X509CertificateBuilder cbuilder = new X509CertificateBuilder()
|
||||
.setSubjectDn(dn)
|
||||
|
@ -83,6 +138,16 @@ public class CRLDistributionPointTest {
|
|||
return cbuilder.build();
|
||||
}
|
||||
|
||||
X509Certificate revokedCert() throws CertificateException {
|
||||
String certStr = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"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"
|
||||
+ "\n-----END CERTIFICATE-----";
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
|
||||
return (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certStr.getBytes()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -42,9 +42,13 @@ public class ElytronHmacTest extends HmacTest {
|
|||
SecureRandom random = isWindows() ? SecureRandom.getInstance("Windows-PRNG") : SecureRandom.getInstance("NativePRNG");
|
||||
random.setSeed(UUID.randomUUID().toString().getBytes());
|
||||
keygen.init(random);
|
||||
SecretKey secretKey = keygen.generateKey();
|
||||
SecretKey secret = keygen.generateKey();
|
||||
|
||||
testHMACSignAndVerify(secretKey, "testHmacSignaturesUsingKeyGen");
|
||||
String encoded = new JWSBuilder().content("12345678901234567890".getBytes())
|
||||
.hmac256(secret);
|
||||
System.out.println("length: " + encoded.length());
|
||||
JWSInput input = new JWSInput(encoded);
|
||||
Assert.assertTrue(HMACProvider.verify(input, secret));
|
||||
}
|
||||
private boolean isWindows(){
|
||||
return System.getProperty("os.name").startsWith("Windows");
|
||||
|
|
|
@ -30,8 +30,6 @@ import org.keycloak.common.crypto.CryptoIntegration;
|
|||
import org.keycloak.common.util.KeystoreUtil;
|
||||
import org.keycloak.rule.CryptoInitRule;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -44,7 +42,7 @@ public class ElytronKeyStoreTypesTest {
|
|||
@Test
|
||||
public void testKeystoreFormats() {
|
||||
Set<KeystoreUtil.KeystoreFormat> supportedKeystoreFormats = CryptoIntegration.getProvider().getSupportedKeyStoreTypes().collect(Collectors.toSet());
|
||||
assertThat(supportedKeystoreFormats, Matchers.containsInAnyOrder(
|
||||
Assert.assertThat(supportedKeystoreFormats, Matchers.containsInAnyOrder(
|
||||
KeystoreUtil.KeystoreFormat.JKS,
|
||||
KeystoreUtil.KeystoreFormat.PKCS12
|
||||
));
|
||||
|
|
|
@ -18,10 +18,14 @@ package org.keycloak.crypto.elytron.test;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.common.crypto.PemUtilsProvider;
|
||||
import org.keycloak.rule.CryptoInitRule;
|
||||
|
||||
public class ElytronPemUtilsTest {
|
||||
|
@ -42,5 +46,26 @@ public class ElytronPemUtilsTest {
|
|||
String encoded = org.keycloak.common.util.PemUtils.generateThumbprint(test, "SHA-256");
|
||||
assertEquals(43, encoded.length());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testenocdedecode() throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
PemUtilsProvider pemutil = CryptoIntegration.getProvider().getPemUtils();
|
||||
|
||||
KeyPair keypair = CryptoIntegration.getProvider().getKeyPairGen("RSA").generateKeyPair();
|
||||
String pem = pemutil.encodeKey(keypair.getPrivate());
|
||||
|
||||
Object decodekey = pemutil.decodePrivateKey(pem);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testtrkey() {
|
||||
String key = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKtWsK5O0CtuBpnMvWG+HTG0vmZzujQ2o9WdheQu+BzCILcGMsbDW0YQaglpcO5JpGWWhubnckGGPHfdQ2/7nP9QwbiTK0FbGF41UqcvoaCqU1psxoV88s8IXyQCAqeyLv00yj6foqdJjxh5SZ5z+na+M7Y2OxIBVxYRAxWEnfUvAgMBAAECgYB+Y7yBWHIHF2qXGYi6CVvPxtyNBuFcktHYShLyeBNeY3VujYv3QzSZQpJ1zuoXXQuARMHOovyNiVAhu357pMfx9wSkoKNSXKrQx/+9Vt9lI1pXJxjXedPOjbuI/JZAcrk0u4nOfXG/HGtR5cjoDZYWkYQEtsePCnHlZAb0D7axwQJBAO92f00Tvkc9NU/EGqwR3bPXRMqSX0JnG7XRBvLeJBCZYsQn0s2bLdpy8qsTeAyJg1ZvrEc8qIio5HVqzsvbhpMCQQC3K9A6UK+vmQCNWqsQpdqWPRPN7CPB67FzSmyS8CtMjY6jTvSHrkamggotz2N/5QDr1xG2q7A/3dpkq1bTpTx1AkAXZjjiSz+Yrn57IOqKTeSgIjTypoLwdirbBWXsbZCQnqxsBogu1y8P3ZOg6/IbJ4TR+W+YNnExiW9pmdpDSVxJAkEAplTq6YmLf/F4RuQmox94tyUPbtcYQWg942uZ3HSrXQDOng18kBj5nwpHJAJHYEQb6g2K0E5n5hcX0oKkfdx2YQJAcSKAmFiD7KQ6+vVqJlQwVPvYdTSOeZB7YVV6S4b4slS3ZObsa0yNMWgal/QnCtW5k3f185gCWj6dOLGB5btfxg==";
|
||||
|
||||
PemUtilsProvider pemutil = CryptoIntegration.getProvider().getPemUtils();
|
||||
|
||||
pemutil.decodePrivateKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package org.keycloak.crypto.elytron.test;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.PSSParameterSpec;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.common.crypto.CryptoIntegration;
|
||||
import org.keycloak.crypto.JavaAlgorithm;
|
||||
import org.keycloak.crypto.KeyWrapper;
|
||||
|
||||
public class ElytronSignatureAlgTest {
|
||||
|
||||
private byte[] data = "Test String to Encrypt".getBytes();
|
||||
|
||||
@Test
|
||||
public void signatureDefaultAlg() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidAlgorithmParameterException, InvalidKeySpecException {
|
||||
KeyPair keyPair = KeyPairGenerator.getInstance("RSASSA-PSS").genKeyPair();
|
||||
KeyWrapper key = new KeyWrapper();
|
||||
//key.setPrivateKey(keyPair.getPrivate());
|
||||
key.setAlgorithm("PS256");
|
||||
|
||||
KeySpec kspec = new PKCS8EncodedKeySpec(keyPair.getPrivate().getEncoded());
|
||||
key.setPrivateKey(KeyFactory.getInstance("RSASSA-PSS").generatePrivate(kspec));
|
||||
|
||||
Signature signature = Signature.getInstance("RSASSA-PSS");
|
||||
MGF1ParameterSpec ps = MGF1ParameterSpec.SHA256;
|
||||
AlgorithmParameterSpec params = new PSSParameterSpec(ps.getDigestAlgorithm(), "MGF1", ps, 32, 1);
|
||||
|
||||
signature.setParameter(params);
|
||||
signature.initSign(keyPair.getPrivate());
|
||||
//signature.initSign((PrivateKey) key.getPrivateKey());
|
||||
signature.update(data);
|
||||
System.out.println(signature.getProvider() + " Alg ###########");
|
||||
if(signature.getAlgorithm().equals("RSASSA-PSS")) {
|
||||
}
|
||||
signature.sign();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue