diff --git a/peppol-commons/src/main/java/com/helger/peppol/utils/PeppolKeyStoreHelper.java b/peppol-commons/src/main/java/com/helger/peppol/utils/PeppolKeyStoreHelper.java index 4ed9d806..09d3ee37 100644 --- a/peppol-commons/src/main/java/com/helger/peppol/utils/PeppolKeyStoreHelper.java +++ b/peppol-commons/src/main/java/com/helger/peppol/utils/PeppolKeyStoreHelper.java @@ -128,7 +128,7 @@ private Config2018 () static { if (TRUSTSTORE_AP_PRODUCTION == null) - throw new IllegalStateException ("Failed to load pre-configured production trust store"); + throw new IllegalStateException ("Failed to load pre-configured production AP trust store"); } // SMP Production @@ -215,7 +215,7 @@ private Config2018 () static { if (TRUSTSTORE_AP_PILOT == null) - throw new IllegalStateException ("Failed to load pre-configured pilot trust store"); + throw new IllegalStateException ("Failed to load pre-configured AP pilot trust store"); } // SMP Test @@ -244,6 +244,34 @@ private Config2018 () throw new IllegalStateException ("Failed to load pre-configured SMP pilot trust store"); } + // AP eB2B Test + + /** + * The classpath entry referencing the global truststore with all OpenPeppol + * pilot entries for an eB2B AP. + * + * @since 9.6.0 + */ + public static final String TRUSTSTORE_EB2B_AP_PILOT_CLASSPATH = "truststore/2018/eb2b-ap-pilot-truststore.jks"; + + public static final ITrustStoreDescriptor TRUSTSTORE_DESCRIPTOR_EB2B_AP_PILOT = TrustStoreDescriptor.builder () + .type (TRUSTSTORE_TYPE) + .path (TRUSTSTORE_EB2B_AP_PILOT_CLASSPATH) + .password (TRUSTSTORE_PASSWORD) + .build (); + + /** + * The full eB2B AP pilot truststore. Never modify. + */ + public static final KeyStore TRUSTSTORE_EB2B_AP_PILOT = TRUSTSTORE_DESCRIPTOR_EB2B_AP_PILOT.loadTrustStore () + .getKeyStore (); + + static + { + if (TRUSTSTORE_EB2B_AP_PILOT == null) + throw new IllegalStateException ("Failed to load pre-configured pilot eB2B AP trust store"); + } + // Test CA certificates /** The truststore alias for the OpenPeppol pilot root certificate */ @@ -266,6 +294,13 @@ private Config2018 () /** The OpenPeppol pilot SMP certificate */ public static final X509Certificate CERTIFICATE_PILOT_SMP = _resolveCert (TRUSTSTORE_AP_PILOT, TRUSTSTORE_PILOT_ALIAS_SMP); + + /** The truststore alias for the OpenPeppol pilot eB2B AP certificate */ + public static final String TRUSTSTORE_PILOT_ALIAS_EB2B_AP = "peppol eb2b access point test ca - g2 (peppol root test ca - g2)"; + + /** The OpenPeppol pilot AP certificate */ + public static final X509Certificate CERTIFICATE_PILOT_EB2B_AP = _resolveCert (TRUSTSTORE_EB2B_AP_PILOT, + TRUSTSTORE_PILOT_ALIAS_EB2B_AP); } @PresentForCodeCoverage diff --git a/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.md5 b/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.md5 new file mode 100644 index 00000000..c3923183 --- /dev/null +++ b/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.md5 @@ -0,0 +1 @@ +a37ada4afb0293878479c6e06b2fa19b \ No newline at end of file diff --git a/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.sha256 b/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.sha256 new file mode 100644 index 00000000..2d972eab --- /dev/null +++ b/peppol-commons/src/main/resources/truststore/2018/eb2b-ap-pilot-truststore.jks.sha256 @@ -0,0 +1 @@ +2535d2515ee0ec61f5b540bae195584849ae3f6f62debde47c102d4ba6562913 \ No newline at end of file diff --git a/peppol-commons/src/main/resources/truststore/complete-truststore.jks b/peppol-commons/src/main/resources/truststore/complete-truststore.jks index b5f70d47..dc4de179 100644 Binary files a/peppol-commons/src/main/resources/truststore/complete-truststore.jks and b/peppol-commons/src/main/resources/truststore/complete-truststore.jks differ diff --git a/peppol-commons/src/main/resources/truststore/complete-truststore.jks.md5 b/peppol-commons/src/main/resources/truststore/complete-truststore.jks.md5 index 66e892a8..cb1efe53 100644 --- a/peppol-commons/src/main/resources/truststore/complete-truststore.jks.md5 +++ b/peppol-commons/src/main/resources/truststore/complete-truststore.jks.md5 @@ -1 +1 @@ -55ac713dcc1223092aa37d0dbdc20260 \ No newline at end of file +7c75f6a4fb7ab9cc1c37a7d2489f1f37 \ No newline at end of file diff --git a/peppol-commons/src/main/resources/truststore/complete-truststore.jks.sha256 b/peppol-commons/src/main/resources/truststore/complete-truststore.jks.sha256 index 9e86f755..80da3f7c 100644 --- a/peppol-commons/src/main/resources/truststore/complete-truststore.jks.sha256 +++ b/peppol-commons/src/main/resources/truststore/complete-truststore.jks.sha256 @@ -1 +1 @@ -ac33ed9f010c5f36aee47460787a741785f8fcbaab96bdca60626cbbd91b2b12 \ No newline at end of file +045639bf9dfb29b2c4c43049d7044c2584ea6e143a4a7089da4fd9763a3566c6 \ No newline at end of file diff --git a/peppol-commons/src/main/resources/truststore/readme.md b/peppol-commons/src/main/resources/truststore/readme.md index d1cbafe0..e8a62a4d 100644 --- a/peppol-commons/src/main/resources/truststore/readme.md +++ b/peppol-commons/src/main/resources/truststore/readme.md @@ -17,7 +17,7 @@ * `r3 (isrg root x1)` `2018/pilot-truststore.jks` -* Is the global trust store for OpenPeppol pilot and works for APs +* Is the global trust store for OpenPeppol pilot APs * It is valid from 2018-2028 * The contained aliases are: * `peppol root test ca - g2` @@ -25,7 +25,7 @@ * `peppol service metadata publisher test ca - g2 (peppol root test ca - g2)` `2018/prod-truststore.jks` -* Is the global trust store for OpenPeppol production and works for APs +* Is the global trust store for OpenPeppol production APs * It is valid from 2018-2028 * The contained aliases are: * `peppol root ca - g2` @@ -33,7 +33,7 @@ * `peppol service metadata publisher ca - g2 (peppol root ca - g2)` `2018/smp-pilot-truststore.jks` (since 8.6.4) -* Is the global trust store for OpenPeppol pilot and works as well for SML and SMPs +* Is the global trust store for OpenPeppol pilot SMPs * It is valid from 2018-2028 * Updated 2024-01-02 removed the old GlobalSign certificates * The contained aliases are: @@ -46,7 +46,7 @@ * `r3 (isrg root x1)` `2018/smp-prod-truststore.jks` (since 8.6.4) -* Is the global trust store for OpenPeppol production and works as well for APs +* Is the global trust store for OpenPeppol production SMPs * It is valid from 2018-2028 * Updated 2024-01-02 removed the old GlobalSign certificates * The contained aliases are: @@ -58,8 +58,17 @@ * `isrg root x1` * `r3 (isrg root x1)` +`2018/eb2b-ap-pilot-truststore.jks` (since 9.6.0) +* Is the global trust store for OpenPeppol pilot eB2B APs +* It is valid from 2018-2028 +* The contained aliases are: + * `peppol root ca - g2` + * `peppol eb2b access point test ca - g2 (peppol root test ca - g2)` + * `peppol service metadata publisher ca - g2 (peppol root ca - g2)` + `complete-truststore.jks` * This is the combination of all available truststores with the same aliases! +* Updated in v9.6.0 to include eB2B AP Test CA * Updated in v8.4.1 (add new) and v8.5.2 (remove old) to reflect the new Let's Encrypt issuing certificate * Updated 2024-01-02 removed the old GlobalSign certificates * `peppol root ca - g2` @@ -67,6 +76,7 @@ * `peppol service metadata publisher ca - g2 (peppol root ca - g2)` * `peppol root test ca - g2` * `peppol access point test ca - g2 (peppol root test ca - g2)` + * `peppol eb2b access point test ca - g2 (peppol root test ca - g2)` * `peppol service metadata publisher test ca - g2 (peppol root test ca - g2)` * `globalsign` * `globalsign rsa ov ssl ca 2018 (globalsign)` diff --git a/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreComplete.java b/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreComplete.java index 2e0bf244..187ed575 100644 --- a/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreComplete.java +++ b/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreComplete.java @@ -20,11 +20,14 @@ import java.io.FileOutputStream; import java.io.OutputStream; import java.security.KeyStore; -import java.util.Enumeration; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableEntryException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.helger.commons.collection.impl.CommonsHashSet; +import com.helger.commons.collection.impl.ICommonsSet; import com.helger.peppol.utils.PeppolKeyStoreHelper; import com.helger.security.keystore.EKeyStoreType; import com.helger.security.keystore.KeyStoreHelper; @@ -40,18 +43,33 @@ public static void main (final String [] args) throws Exception // null stream means: create new key store aSMPTrustStore.load (null, null); - for (final String sTS : new String [] { "directory", "sml", "2018/pilot", "2018/prod" }) + final ICommonsSet aAdded = new CommonsHashSet <> (); + for (final String sTS : new String [] { "directory", + "sml", + "2018/eb2b-ap-pilot", + "2018/pilot", + "2018/prod", + "2018/smp-pilot", + "2018/smp-prod" }) { final LoadedKeyStore aLKS = KeyStoreHelper.loadKeyStore (EKeyStoreType.JKS, "truststore/" + sTS + "-truststore.jks", PeppolKeyStoreHelper.TRUSTSTORE_PASSWORD.toCharArray ()); - final Enumeration aAliases = aLKS.getKeyStore ().aliases (); - while (aAliases.hasMoreElements ()) - { - final String sAlias = aAliases.nextElement (); - // No key password - aSMPTrustStore.setEntry (sAlias, aLKS.getKeyStore ().getEntry (sAlias, null), null); - } + KeyStoreHelper.iterateKeyStore (aLKS.getKeyStore (), sAlias -> { + if (aAdded.add (sAlias)) + { + // No key password + try + { + LOGGER.info ("Adding '" + sAlias + "'"); + aSMPTrustStore.setEntry (sAlias, aLKS.getKeyStore ().getEntry (sAlias, null), null); + } + catch (final NoSuchAlgorithmException | UnrecoverableEntryException ex) + { + throw new IllegalStateException (ex); + } + } + }); } final File fDest = new File ("src/main/resources/truststore/complete-truststore.jks"); diff --git a/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreHashFiles.java b/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreHashFiles.java index 48d8956d..02bf54ac 100644 --- a/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreHashFiles.java +++ b/peppol-commons/src/test/java/com/helger/peppol/supplementary/tools/MainCreateTrustStoreHashFiles.java @@ -46,12 +46,17 @@ private static void _create (@Nonnull final String sTruststorePath) throws IOExc { final IReadableResource aTrustStore = new ClassPathResource (sTruststorePath); - final String sMD5 = MessageDigestValue.create (aTrustStore.getInputStream (), EMessageDigestAlgorithm.MD5).getHexEncodedDigestString (); - SimpleFileIO.writeFile (new File ("src/main/resources/" + sTruststorePath + ".md5"), sMD5, StandardCharsets.ISO_8859_1); + final String sMD5 = MessageDigestValue.create (aTrustStore.getInputStream (), EMessageDigestAlgorithm.MD5) + .getHexEncodedDigestString (); + SimpleFileIO.writeFile (new File ("src/main/resources/" + sTruststorePath + ".md5"), + sMD5, + StandardCharsets.ISO_8859_1); final String sSHA1 = MessageDigestValue.create (aTrustStore.getInputStream (), EMessageDigestAlgorithm.SHA_256) .getHexEncodedDigestString (); - SimpleFileIO.writeFile (new File ("src/main/resources/" + sTruststorePath + ".sha256"), sSHA1, StandardCharsets.ISO_8859_1); + SimpleFileIO.writeFile (new File ("src/main/resources/" + sTruststorePath + ".sha256"), + sSHA1, + StandardCharsets.ISO_8859_1); LOGGER.info ("Done creating hash values for " + sTruststorePath); } @@ -65,7 +70,8 @@ public static void main (final String [] args) throws IOException _create ("truststore/2010/pilot-truststore.jks"); _create (PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PRODUCTION_CLASSPATH); _create (PeppolKeyStoreHelper.Config2018.TRUSTSTORE_AP_PILOT_CLASSPATH); - _create ("truststore/2018/smp-prod-truststore.jks"); - _create ("truststore/2018/smp-pilot-truststore.jks"); + _create (PeppolKeyStoreHelper.Config2018.TRUSTSTORE_SMP_PRODUCTION_CLASSPATH); + _create (PeppolKeyStoreHelper.Config2018.TRUSTSTORE_SMP_PILOT_CLASSPATH); + _create (PeppolKeyStoreHelper.Config2018.TRUSTSTORE_EB2B_AP_PILOT_CLASSPATH); } }