From d5cc9c8c26ebe835229bfcbf5667f5693ba0661a Mon Sep 17 00:00:00 2001 From: Joze RIHTARSIC <joze.rihtarsic@ext.ec.europa.eu> Date: Wed, 4 Mar 2020 11:31:21 +0100 Subject: [PATCH] - add support for multivalue RDN certifcates --- smp-parent-pom/pom.xml | 2 +- .../ec/edelivery/smp/config/FileProperty.java | 2 +- .../smp/data/dao/ConfigurationDao.java | 2 +- .../ec/edelivery/smp/data/dao/DomainDao.java | 8 +-- .../smp/data/ui/enums/SMPPropertyEnum.java | 2 +- .../smp/services/ui/UITruststoreService.java | 48 +++++++++++++++--- ...rtificateToCertificateROConverterTest.java | 7 ++- .../services/ui/UITruststoreServiceTest.java | 45 +++++++++++++++- .../resources/certificates/test-mvRdn.crt | Bin 0 -> 622 bytes 9 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 smp-server-library/src/test/resources/certificates/test-mvRdn.crt diff --git a/smp-parent-pom/pom.xml b/smp-parent-pom/pom.xml index 6378e9546..84dbbc316 100644 --- a/smp-parent-pom/pom.xml +++ b/smp-parent-pom/pom.xml @@ -46,7 +46,7 @@ <properties> <!-- Only selected modules are deployed --> <maven.deploy.skip>true</maven.deploy.skip> - <edelivery.ssl-auth.version>1.6</edelivery.ssl-auth.version> + <edelivery.ssl-auth.version>1.8</edelivery.ssl-auth.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <slf4j.version>1.7.26</slf4j.version> diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java index e1108be9f..50c0db98b 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/FileProperty.java @@ -3,7 +3,7 @@ package eu.europa.ec.edelivery.smp.config; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.log4j.LogManager; import org.apache.log4j.PropertyConfigurator; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java index d3742e4c9..ae5c0d2b3 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/ConfigurationDao.java @@ -23,8 +23,8 @@ import eu.europa.ec.edelivery.smp.logging.SMPLogger; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import eu.europa.ec.edelivery.smp.utils.PropertyUtils; import eu.europa.ec.edelivery.smp.utils.SecurityUtils; -import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java index 56b120bff..985baa2dc 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DomainDao.java @@ -15,10 +15,9 @@ package eu.europa.ec.edelivery.smp.data.dao; import eu.europa.ec.edelivery.smp.data.model.DBDomain; import eu.europa.ec.edelivery.smp.data.model.DBDomainDeleteValidation; -import eu.europa.ec.edelivery.smp.data.model.DBUserDeleteValidation; import eu.europa.ec.edelivery.smp.exceptions.ErrorCode; import eu.europa.ec.edelivery.smp.exceptions.SMPRuntimeException; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Repository; import javax.persistence.NoResultException; @@ -124,10 +123,11 @@ public class DomainDao extends BaseDao<DBDomain> { /** * Validation report for domain which are used by service groups from list of domain ids.. - * @param domainIds + * + * @param domainIds * @return */ - public List<DBDomainDeleteValidation> validateDomainsForDelete(List<Long> domainIds){ + public List<DBDomainDeleteValidation> validateDomainsForDelete(List<Long> domainIds) { TypedQuery<DBDomainDeleteValidation> query = memEManager.createNamedQuery("DBDomainDeleteValidation.validateDomainUsage", DBDomainDeleteValidation.class); query.setParameter("domainIds", domainIds); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java index 5aa8253c1..e827e0dd8 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/enums/SMPPropertyEnum.java @@ -1,6 +1,6 @@ package eu.europa.ec.edelivery.smp.data.ui.enums; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import java.util.Arrays; import java.util.Optional; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java index 2dbecae9d..880034465 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java @@ -18,7 +18,9 @@ import org.springframework.security.authentication.AuthenticationServiceExceptio import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; -import javax.naming.InvalidNameException; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.BasicAttribute; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import javax.net.ssl.TrustManager; @@ -359,20 +361,54 @@ public class UITruststoreService { String dn = x509cert.getSubjectX500Principal().getName(); + String alias = null; try { - String alias = null; + LdapName ldapDN = new LdapName(dn); + Rdn cn = null; for (Rdn rdn : ldapDN.getRdns()) { - if (Objects.equals("CN", rdn.getType())) { + + if (rdn.size()>1) { + NamingEnumeration enr = rdn.toAttributes().getAll(); + while(enr.hasMore()) { + Object mvRDn = enr.next(); + if (mvRDn instanceof BasicAttribute){ + BasicAttribute ba = (BasicAttribute)mvRDn; + if (Objects.equals("CN", ba.getID())) { + cn = new Rdn(ba.getID(), ba.get()); + break; + } + } + } + + }else if (Objects.equals("CN", rdn.getType())) { alias = rdn.getValue().toString().trim(); break; } + if (cn !=null) { + alias = cn.getValue().toString().trim(); + break; + } } - return alias; - } catch (InvalidNameException e) { + + } catch (NamingException e) { LOG.error("Can not parse certificate subject: " + dn); } - return UUID.randomUUID().toString(); + alias = StringUtils.isEmpty(alias)?UUID.randomUUID().toString():alias; + + try { + if (truststore != null && truststore.containsAlias(alias)) { + int iVal = 1; + while(truststore.containsAlias(alias+"_"+iVal)){ + iVal++; + } + alias =alias+"_"+iVal; + } + } catch (KeyStoreException e) { + LOG.error("Error occured while reading truststore for validating alias: " + alias, e); + } + + return alias; } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverterTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverterTest.java index 4ad6a09a6..736db31bc 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverterTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/X509CertificateToCertificateROConverterTest.java @@ -25,13 +25,12 @@ import static org.junit.Assert.*; @RunWith(JUnitParamsRunner.class) public class X509CertificateToCertificateROConverterTest { - - @Before - public void setup(){ + static { Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1); } + private static final Object[] testCases() { return new Object[][]{ // filename, subject, issuer, serial number, blueCoatHeader, certificateId @@ -39,7 +38,7 @@ public class X509CertificateToCertificateROConverterTest { {"cert-nonAscii.pem", "CN=NonAscii chars: à øýßĉæãäħ,OU=CEF,O=DIGIT,C=BE", "CN=NonAscii chars: à øýßĉæãäħ,OU=CEF,O=DIGIT,C=BE","5c1bb38d","sno=5c1bb38d&subject=CN%3DNonAscii+chars%3A++%C3%A0%C3%B8%C3%BD%C3%9F%C4%89%C3%A6%C3%A3%C3%A4%C4%A7%2COU%3DCEF%2CO%3DDIGIT%2CC%3DBE&validfrom=Dec+20+16%3A21%3A49+2018+GMT&validto=Dec+17+16%3A21%3A49+2028+GMT&issuer=CN%3DNonAscii+chars%3A++%C3%A0%C3%B8%C3%BD%C3%9F%C4%89%C3%A6%C3%A3%C3%A4%C4%A7%2COU%3DCEF%2CO%3DDIGIT%2CC%3DBE","CN=NonAscii chars: aøyßcæaaħ,O=DIGIT,C=BE:000000005c1bb38d"}, {"cert-with-email.pem", "CN=Cert with email,OU=CEF,O=DIGIT,C=BE", "CN=Cert with email,OU=CEF,O=DIGIT,C=BE","5c1bb358","sno=5c1bb358&subject=CN%3DCert+with+email%2COU%3DCEF%2CO%3DDIGIT%2CC%3DBE&validfrom=Dec+20+16%3A20%3A56+2018+GMT&validto=Dec+17+16%3A20%3A56+2028+GMT&issuer=CN%3DCert+with+email%2COU%3DCEF%2CO%3DDIGIT%2CC%3DBE","CN=Cert with email,O=DIGIT,C=BE:000000005c1bb358"}, {"cert-smime.pem", "C=BE,O=European Commission,OU=PEPPOL TEST SMP,CN=edelivery_sml", "CN=PEPPOL SERVICE METADATA PUBLISHER TEST CA - G2,OU=FOR TEST ONLY,O=OpenPEPPOL AISBL,C=BE","3cfe6b37e4702512c01e71f9b9175464","sno=3cfe6b37e4702512c01e71f9b9175464&subject=C%3DBE%2CO%3DEuropean+Commission%2COU%3DPEPPOL+TEST+SMP%2CCN%3Dedelivery_sml&validfrom=Sep+21+02%3A00%3A00+2018+GMT&validto=Sep+11+01%3A59%3A59+2020+GMT&issuer=CN%3DPEPPOL+SERVICE+METADATA+PUBLISHER+TEST+CA+-+G2%2COU%3DFOR+TEST+ONLY%2CO%3DOpenPEPPOL+AISBL%2CC%3DBE","CN=edelivery_sml,O=European Commission,C=BE:3cfe6b37e4702512c01e71f9b9175464"}, - + {"test-mvRdn.crt", "C=BE,O=DIGIT,2.5.4.5=#130131+2.5.4.42=#0c046a6f686e+CN=SMP_receiverCN", "C=BE,O=DIGIT,2.5.4.5=#130131+2.5.4.42=#0c046a6f686e+CN=SMP_receiverCN","123456789101112","sno=123456789101112&subject=C%3DBE%2CO%3DDIGIT%2C2.5.4.5%3D%23130131%2B2.5.4.42%3D%230c046a6f686e%2BCN%3DSMP_receiverCN&validfrom=Dec+09+14%3A14%3A11+2019+GMT&validto=Feb+01+14%3A14%3A11+2021+GMT&issuer=C%3DBE%2CO%3DDIGIT%2C2.5.4.5%3D%23130131%2B2.5.4.42%3D%230c046a6f686e%2BCN%3DSMP_receiverCN","CN=SMP_receiverCN,O=DIGIT,C=BE:0123456789101112"}, }; } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceTest.java index 3f89ce579..2a30e0fbc 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreServiceTest.java @@ -21,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; +import javax.security.auth.x500.X500Principal; import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -128,6 +129,23 @@ public class UITruststoreServiceTest extends AbstractServiceIntegrationTest { assertTrue(testInstance.isSubjectOnTrustedList(certSubject)); } + @Test + public void testAddCertificateRDN() throws Exception { + // given + String certSubject = "GIVENNAME=John+SERIALNUMBER=1+CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; + String alias = UUID.randomUUID().toString(); + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest(certSubject); + String val = certificate.getSubjectX500Principal().getName(X500Principal.RFC2253); + int iSize = testInstance.getNormalizedTrustedList().size(); + assertFalse(testInstance.isSubjectOnTrustedList(certSubject)); + // when + testInstance.addCertificate(alias, certificate); + + // then + assertEquals(iSize + 1, testInstance.getNormalizedTrustedList().size()); + assertTrue(testInstance.isSubjectOnTrustedList(certSubject)); + } + @Test public void testDeleteCertificate() throws Exception { // given @@ -365,7 +383,32 @@ public class UITruststoreServiceTest extends AbstractServiceIntegrationTest { testInstance.checkFullCertificateValidity(certificate); // then - //no erroros should be thrown + //no errors should be thrown + } + + @Test + public void testCreateAliasForCert() throws Exception { + // given + String certSubject = "CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest(certSubject); + // when + String alias = testInstance.createAliasFromCert(certificate, null); + + // then + assertEquals("SMP Test", alias); + } + + + @Test + public void testCreateAliasFoMultiValuerCert() throws Exception { + // given + String certSubject = "GIVENNAME=John+SERIALNUMBER=1+CN=SMP Test,OU=eDelivery,O=DIGITAL,C=BE"; + X509Certificate certificate = X509CertificateTestUtils.createX509CertificateForTest(certSubject); + // when + String alias = testInstance.createAliasFromCert(certificate, null); + + // then + assertEquals("SMP Test", alias); } } \ No newline at end of file diff --git a/smp-server-library/src/test/resources/certificates/test-mvRdn.crt b/smp-server-library/src/test/resources/certificates/test-mvRdn.crt new file mode 100644 index 0000000000000000000000000000000000000000..97416e0da299b217ff90a11fcf7d406b5ef0d01f GIT binary patch literal 622 zcmXqLV#+dTV!XV7nTe5!iGxwuHN8_nP{@FnjZ>@5qwPB{BO@y-gMqK1o&g6Nb0`a| zFr%RXH;ARh!;+Psk!K(Z;xO~@1^WiX7o{erW|pNEIr|y%8SsE4xOiAyJl#D*47m+B zL3}o0CMQ<|IdNV?OG6_AOG9Hr6GOu&ab6=s10w@ND3{vSHO@!&4<joBb7L=qL1QOV zV<W?{N|ys$HnM4}O{<i4`|))*U*3DkIn$RdyY%i=%5&cOZATT~K2?&ED`L{pZj<^{ zGrd*L*=C=Sm8<hID^ub5%WeHmIVn5+$nuvFxc^#qm*ko3-%(6Hrmz05-rBJ3^z1ah zpS$lhyqvzVasCWZgYuo`$CupR%jeQky{qrFpFwxPBTFV`Mh3>k!3Kc_{=o2&m1prV za5HdO;IzP@%`Po7C)G+nIW<i`IX@*;KPe@*I0r)NmZv5q78K~0Bo?KomgtwH7MJKI z=Oh*vrxt@bddWpO$bJUKAv4gkT62yXukU54y!$@JpfT1eU7_OQq<v=&W*>4jzp<x$ z-7m57u;navT5Cn!Z&bBhKfhw<v;Ai`#JzVE;fs3nWADtH%g(#k`N+O4o7k_oVMD;W zteG$0-p)$N;IlZgvztG7_lK6f*Y)hp?@us2-kLeZv`z7^O8n*pJiD4T=idr1)4lEs E03vwQH2?qr literal 0 HcmV?d00001 -- GitLab