[java-metadata-aggregator] 02/02: MDA-300 - Add RFC9500 test keys

Ian Young ian at iay.org.uk
Fri Feb 2 20:18:09 UTC 2024


This is an automated email from the git hooks/post-receive script.

iay pushed a commit to branch main
in repository java-metadata-aggregator.

View the commit online:
http://git.shibboleth.net/view/?p=java-metadata-aggregator.git;a=commit;h=a5b5119772d629b84277b81ff1551ffe582512c3

commit a5b5119772d629b84277b81ff1551ffe582512c3
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Fri Feb 2 20:17:56 2024 +0000

    MDA-300 - Add RFC9500 test keys
    
    https://shibboleth.atlassian.net/browse/MDA-300
---
 .../metadata/validate/x509/MDA300Test.java         | 214 +++++++++++++++++++++
 .../x509/testing/BaseX509ValidatorTest.java        |   3 +
 .../keylists/rsa/legacy/compromised-1024.txt       |   3 +
 .../metadata/keylists/rsa/compromised-2048.txt     |   3 +
 .../{compromised-2048.txt => compromised-4096.txt} |   9 +-
 5 files changed, 226 insertions(+), 6 deletions(-)

diff --git a/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/MDA300Test.java b/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/MDA300Test.java
new file mode 100644
index 0000000..0d99462
--- /dev/null
+++ b/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/MDA300Test.java
@@ -0,0 +1,214 @@
+
+package net.shibboleth.metadata.validate.x509;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Date;
+
+import javax.annotation.Nonnull;
+
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.testing.MockItem;
+import net.shibboleth.metadata.validate.Validator.Action;
+import net.shibboleth.metadata.validate.x509.testing.BaseX509ValidatorTest;
+
+public class MDA300Test extends BaseX509ValidatorTest {
+
+    protected MDA300Test() throws Exception{
+        super(MDA300Test.class);
+    }
+
+    static final String key1024 = """
+        -----BEGIN RSA PRIVATE KEY-----
+        MIICXQIBAAKBgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg
+        +xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566d
+        fTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPwIDAQAB
+        AoGASC6fj6TkLfMNdYHLQqG9kOlPfys4fstarpZD7X+fUBJ/H/7y5DzeZLGCYAIU
+        +QeAHWv6TfZIQjReW7Qy00RFJdgwFlTFRCsKXhG5x+IB+jL0Grr08KbgPPDgy4Jm
+        xirRHZVtU8lGbkiZX+omDIU28EHLNWL6rFEcTWao/tERspECQQDp2G5Nw0qYWn7H
+        Wm9Up1zkUTnkUkCzhqtxHbeRvNmHGKE7ryGMJEk2RmgHVstQpsvuFY4lIUSZEjAc
+        DUFJERhFAkEAwZH6O1ULORp8sHKDdidyleYcZU8L7y9Y3OXJYqELfddfBgFUZeVQ
+        duRmJj7ryu0g0uurOTE+i8VnMg/ostxiswJBAOc64Dd8uLJWKa6uug+XPr91oi0n
+        OFtM+xHrNK2jc+WmcSg3UJDnAI3uqMc5B+pERLq0Dc6hStehqHjUko3RnZECQEGZ
+        eRYWciE+Cre5dzfZkomeXE0xBrhecV0bOq6EKWLSVE+yr6mAl05ThRK9DCfPSOpy
+        F6rgN3QiyCA9J/1FluUCQQC5nX+PTU1FXx+6Ri2ZCi6EjEKMHr7gHcABhMinZYOt
+        N59pra9UdVQw9jxCU9G7eMyb0jJkNACAuEwakX3gi27b
+        -----END RSA PRIVATE KEY-----
+        """;
+
+    static final String key2048 = """
+        -----BEGIN RSA PRIVATE KEY-----
+        MIIEowIBAAKCAQEAsPnoGUOnrpiSqt4XynxA+HRP7S+BSObI6qJ7fQAVSPtRkqso
+        tWxQYLEYzNEx5ZSHTGypibVsJylvCfuToDTfMul8b/CZjP2Ob0LdpYrNH6l5hvFE
+        89FU1nZQF15oVLOpUgA7wGiHuEVawrGfey92UE68mOyUVXGweJIVDdxqdMoPvNNU
+        l86BU02vlBiESxOuox+dWmuVV7vfYZ79Toh/LUK43YvJh+rhv4nKuF7iHjVjBd9s
+        B6iDjj70HFldzOQ9r8SRI+9NirupPTkF5AKNe6kUhKJ1luB7S27ZkvB3tSTT3P59
+        3VVJvnzOjaA1z6Cz+4+eRvcysqhrRgFlwI9TEwIDAQABAoIBAEEYiyDP29vCzx/+
+        dS3LqnI5BjUuJhXUnc6AWX/PCgVAO+8A+gZRgvct7PtZb0sM6P9ZcLrweomlGezI
+        FrL0/6xQaa8bBr/ve/a8155OgcjFo6fZEw3Dz7ra5fbSiPmu4/b/kvrg+Br1l77J
+        aun6uUAs1f5B9wW+vbR7tzbT/mxaUeDiBzKpe15GwcvbJtdIVMa2YErtRjc1/5B2
+        BGVXyvlJv0SIlcIEMsHgnAFOp1ZgQ08aDzvilLq8XVMOahAhP1O2A3X8hKdXPyrx
+        IVWE9bS9ptTo+eF6eNl+d7htpKGEZHUxinoQpWEBTv+iOoHsVunkEJ3vjLP3lyI/
+        fY0NQ1ECgYEA3RBXAjgvIys2gfU3keImF8e/TprLge1I2vbWmV2j6rZCg5r/AS0u
+        pii5CvJ5/T5vfJPNgPBy8B/yRDs+6PJO1GmnlhOkG9JAIPkv0RBZvR0PMBtbp6nT
+        Y3yo1lwamBVBfY6rc0sLTzosZh2aGoLzrHNMQFMGaauORzBFpY5lU50CgYEAzPHl
+        u5DI6Xgep1vr8QvCUuEesCOgJg8Yh1UqVoY/SmQh6MYAv1I9bLGwrb3WW/7kqIoD
+        fj0aQV5buVZI2loMomtU9KY5SFIsPV+JuUpy7/+VE01ZQM5FdY8wiYCQiVZYju9X
+        Wz5LxMNoz+gT7pwlLCsC4N+R8aoBk404aF1gum8CgYAJ7VTq7Zj4TFV7Soa/T1eE
+        k9y8a+kdoYk3BASpCHJ29M5R2KEA7YV9wrBklHTz8VzSTFTbKHEQ5W5csAhoL5Fo
+        qoHzFFi3Qx7MHESQb9qHyolHEMNx6QdsHUn7rlEnaTTyrXh3ifQtD6C0yTmFXUIS
+        CW9wKApOrnyKJ9nI0HcuZQKBgQCMtoV6e9VGX4AEfpuHvAAnMYQFgeBiYTkBKltQ
+        XwozhH63uMMomUmtSG87Sz1TmrXadjAhy8gsG6I0pWaN7QgBuFnzQ/HOkwTm+qKw
+        AsrZt4zeXNwsH7QXHEJCFnCmqw9QzEoZTrNtHJHpNboBuVnYcoueZEJrP8OnUG3r
+        UjmopwKBgAqB2KYYMUqAOvYcBnEfLDmyZv9BTVNHbR2lKkMYqv5LlvDaBxVfilE0
+        2riO4p6BaAdvzXjKeRrGNEKoHNBpOSfYCOM16NjL8hIZB1CaV3WbT5oY+jp7Mzd5
+        7d56RZOE+ERK2uz/7JX9VSsM/LbH9pJibd4e8mikDS9ntciqOH/3
+        -----END RSA PRIVATE KEY-----
+        """;
+    
+    static final String key4096 = """
+        -----BEGIN RSA PRIVATE KEY-----
+        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
+        -----END RSA PRIVATE KEY-----
+        """;
+
+    private PEMKeyPair readKeypair(final @Nonnull String pem)
+            throws NoSuchAlgorithmException, IOException {
+        try (var keyReader = new StringReader(pem)) {
+            var pemParser = new PEMParser(keyReader);
+            return (PEMKeyPair)pemParser.readObject();
+        }
+    }
+
+    private @Nonnull X509Certificate buildX509Certificate(final @Nonnull String pem)
+            throws NoSuchAlgorithmException, IOException, OperatorCreationException, CertificateException {
+        var keyPair = readKeypair(pem);
+        var privateKeyInfo = keyPair.getPrivateKeyInfo();
+        var publicKeyInfo = keyPair.getPublicKeyInfo();
+
+        var converter = new JcaPEMKeyConverter();
+
+        // Build a self-signed certificate based on the private key
+        var privateKey = converter.getPrivateKey(privateKeyInfo);
+        var contentSigner 
+            = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey);
+        Date startDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
+        Date endDate = new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000);
+        final var builder = new X509v3CertificateBuilder(new X500Name("CN=Test"),
+                BigInteger.ONE, startDate, endDate,
+                new X500Name("CN=Test"), publicKeyInfo);
+        var certHolder = builder.build(contentSigner);
+        var bytes = certHolder.getEncoded();
+        
+        // Convert to the Java type. There's probably an easier way.
+        var certFactory = CertificateFactory.getInstance("X.509");
+        try (var in = new ByteArrayInputStream(bytes)) {
+            var cert = (X509Certificate)certFactory.generateCertificate(in);
+            assert cert != null;
+            return cert;
+        }
+    }
+ 
+    private void testCompromisedKey(final @Nonnull String pem, final int keySize) throws Exception {
+        final var cert = buildX509Certificate(pem);
+        final var val = getCompromisedKeyValidator(keySize);
+        final var item = new MockItem("data");
+        final var res = val.validate(cert, item, "context");
+
+        Assert.assertEquals(res, Action.CONTINUE); // always true even if an error is attached
+
+        /*
+         * Check that the error is there. If it's not, include the digest we need
+         * to put in the resource to get it right next time.
+         */
+        var errors = item.getItemMetadata().get(ErrorStatus.class);
+        if (errors.size() != 1) {
+            var publicKey = (RSAPublicKey)cert.getPublicKey();
+            assert publicKey != null;
+            var modulus = publicKey.getModulus();
+            assert modulus != null;
+            Assert.fail("did not match " + keySize + "-bit "+ openSSLDigest(modulus));
+        }
+    }
+
+    @Test
+    public void test1024() throws Exception {
+        testCompromisedKey(key1024, 1024);
+    }
+
+    @Test
+    public void test2048() throws Exception {
+        testCompromisedKey(key2048, 2048);
+    }
+
+    @Test
+    public void test4096() throws Exception {
+        testCompromisedKey(key4096, 4096);
+    }
+
+}
diff --git a/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/testing/BaseX509ValidatorTest.java b/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/testing/BaseX509ValidatorTest.java
index ee0f50c..45ba73c 100644
--- a/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/testing/BaseX509ValidatorTest.java
+++ b/mda-framework/src/test/java/net/shibboleth/metadata/validate/x509/testing/BaseX509ValidatorTest.java
@@ -101,6 +101,9 @@ public abstract class BaseX509ValidatorTest extends BaseTest {
         case 2048:
             keylistResource = new ClassPathResource("net/shibboleth/metadata/keylists/rsa/compromised-2048.txt");
             break;
+        case 4096:
+            keylistResource = new ClassPathResource("net/shibboleth/metadata/keylists/rsa/compromised-4096.txt");
+            break;
         default:
             throw new IllegalArgumentException();
         }
diff --git a/mda-keylists-rsa-legacy/src/main/resources/net/shibboleth/metadata/keylists/rsa/legacy/compromised-1024.txt b/mda-keylists-rsa-legacy/src/main/resources/net/shibboleth/metadata/keylists/rsa/legacy/compromised-1024.txt
index 8e9dbc4..a5339fc 100644
--- a/mda-keylists-rsa-legacy/src/main/resources/net/shibboleth/metadata/keylists/rsa/legacy/compromised-1024.txt
+++ b/mda-keylists-rsa-legacy/src/main/resources/net/shibboleth/metadata/keylists/rsa/legacy/compromised-1024.txt
@@ -21,3 +21,6 @@
 
 # "mykey" demo key, shipped in jetty-distribution-9.4.6.v20170531
 a45c935fecfe041cf87b
+
+# RFC 9500
+e6f4c70a91b9571ee5ac
diff --git a/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt b/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt
index 3ab3e09..d4bb062 100644
--- a/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt
+++ b/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt
@@ -17,3 +17,6 @@
 
 # "jetty" demo key, shipped in jetty-distribution-9.4.6.v20170531
 6475773dd6238880de70
+
+# RFC 9500
+9fd664357ec53b076260
diff --git a/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt b/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-4096.txt
similarity index 60%
copy from mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt
copy to mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-4096.txt
index 3ab3e09..c37a246 100644
--- a/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-2048.txt
+++ b/mda-keylists-rsa/src/main/resources/net/shibboleth/metadata/keylists/rsa/compromised-4096.txt
@@ -1,5 +1,5 @@
 #
-# This is a list of known-compromised 2048-bit keys in OpenSSL format.
+# This is a list of known-compromised 4096-bit keys in OpenSSL format.
 #
 # Derive new values from a private key file as follows:
 #
@@ -12,8 +12,5 @@
 #       cut -d ' ' -f 1 | cut -c 21-
 #
 
-# Shibboleth IdP dummy key, shipped in 3.0.0-alpha1 release
-959a1a153444578d010b
-
-# "jetty" demo key, shipped in jetty-distribution-9.4.6.v20170531
-6475773dd6238880de70
+# RFC 9500
+784e7ba15f4e8f1e83e8

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list