Skip to content

Commit

Permalink
Fix: Add Embedded Signature for DSC Migration (#171)
Browse files Browse the repository at this point in the history
* Add Embedded Signature for DSC Migration

* Checkstyle
  • Loading branch information
f11h authored Mar 25, 2022
1 parent bca4327 commit fbdff82
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 29 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<spring.cloud.version>2021.0.1</spring.cloud.version>
<h2.version>2.1.210</h2.version>
<hibernate.version>5.6.5.Final</hibernate.version>
<dgc.lib.version>1.2.0</dgc.lib.version>
<dgc.lib.version>1.3.0</dgc.lib.version>
<!-- plugins -->
<plugin.maven-assembly.version>3.3.0</plugin.maven-assembly.version>
<plugin.checkstyle.version>3.1.2</plugin.checkstyle.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ protected SignedCertificateDto readInternal(
.payloadCertificate(certificateParser.getPayload())
.signerCertificate(certificateParser.getSigningCertificate())
.rawMessage(new String(inputBytes, StandardCharsets.UTF_8))
.signature(certificateParser.getSignature())
.signature(certificateParser.getDetachedSignature())
.verified(certificateParser.isSignatureVerified())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Schema(name = "CmsPackage")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CmsPackageDto {

@Schema(description = "CMS containing the signed String or certificate")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import eu.europa.ec.dgc.gateway.repository.SignerInformationRepository;
import eu.europa.ec.dgc.gateway.restapi.dto.CmsPackageDto;
import eu.europa.ec.dgc.gateway.utils.DgcMdc;
import eu.europa.ec.dgc.signing.SignedCertificateMessageParser;
import eu.europa.ec.dgc.signing.SignedMessageParser;
import eu.europa.ec.dgc.utils.CertificateUtils;
import java.io.IOException;
import java.security.cert.X509Certificate;
Expand Down Expand Up @@ -308,10 +310,25 @@ public List<CmsPackageDto> getCmsPackage(String country) {
return signerInformationRepository
.getByCertificateTypeAndCountry(SignerInformationEntity.CertificateType.DSC, country)
.stream()
.map(this::addCertificateToSignaturePayload)
.map(it -> new CmsPackageDto(it.getSignature(), it.getId(), CmsPackageDto.CmsPackageTypeDto.DSC))
.collect(Collectors.toList());
}

private SignerInformationEntity addCertificateToSignaturePayload(SignerInformationEntity entity) {
SignedCertificateMessageParser parser = new SignedCertificateMessageParser(
entity.getSignature(), entity.getRawData());

if (parser.getParserState() == SignedMessageParser.ParserState.SUCCESS) {
entity.setSignature(parser.getEmbeddedSignature());
} else {
log.error("Failed to repack CMS for DSC {}, Parser State: {}",
entity.getThumbprint(), parser.getParserState());
}

return entity;
}

private void contentCheckUploaderCertificate(
X509CertificateHolder signerCertificate,
String authenticatedCountryCode) throws SignerCertCheckException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@

package eu.europa.ec.dgc.gateway.restapi.controller;

import static eu.europa.ec.dgc.gateway.testdata.CertificateTestUtils.getDummyValidationRule;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
Expand All @@ -40,17 +49,9 @@
import eu.europa.ec.dgc.gateway.testdata.TrustedPartyTestHelper;
import eu.europa.ec.dgc.signing.SignedCertificateMessageBuilder;
import eu.europa.ec.dgc.signing.SignedCertificateMessageParser;
import eu.europa.ec.dgc.signing.SignedMessageParser;
import eu.europa.ec.dgc.signing.SignedStringMessageBuilder;
import eu.europa.ec.dgc.utils.CertificateUtils;
import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
Expand All @@ -60,13 +61,15 @@
import java.util.Base64;
import java.util.List;
import java.util.Optional;

import static eu.europa.ec.dgc.gateway.testdata.CertificateTestUtils.getDummyValidationRule;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;

@SpringBootTest
@AutoConfigureMockMvc
Expand Down Expand Up @@ -122,22 +125,37 @@ void testAllCertTypes() throws Exception {
X509Certificate certDscEu = CertificateTestUtils.generateCertificate(keyPairGenerator.generateKeyPair(), countryCode, "Test");
String cmsBase64 = Base64.getEncoder().encodeToString(certDscEu.getEncoded());

createSignerInfo(cmsBase64, certDscEu, "signature1");
SignedCertificateMessageBuilder messageBuilder = new SignedCertificateMessageBuilder()
.withPayload(certificateUtils.convertCertificate(certDscEu))
.withSigningCertificate(
certificateUtils.convertCertificate(trustedPartyTestHelper.getCert(TrustedPartyEntity.CertificateType.UPLOAD, countryCode)),
trustedPartyTestHelper.getPrivateKey(TrustedPartyEntity.CertificateType.UPLOAD, countryCode));

String detachedSignature = messageBuilder.buildAsString(true);

createSignerInfo(cmsBase64, certDscEu, detachedSignature);
createRevocation("id1", cmsBase64, false);
createValidationEntry(cmsBase64);

String authCertHash = trustedPartyTestHelper.getHash(TrustedPartyEntity.CertificateType.AUTHENTICATION, countryCode);

mockMvc.perform(get("/cms-migration")
.header(dgcConfigProperties.getCertAuth().getHeaderFields().getThumbprint(), authCertHash)
.header(dgcConfigProperties.getCertAuth().getHeaderFields().getDistinguishedName(), authCertSubject))
.andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].type", is(CmsPackageDto.CmsPackageTypeDto.DSC.name())))
.andExpect(jsonPath("$[0].cms", is("signature1")))
.andExpect(jsonPath("$[1].type", is(CmsPackageDto.CmsPackageTypeDto.REVOCATION_LIST.name())))
.andExpect(jsonPath("$[1].cms", is(cmsBase64)))
.andExpect(jsonPath("$[2].type", is(CmsPackageDto.CmsPackageTypeDto.VALIDATION_RULE.name())))
.andExpect(jsonPath("$[2].cms", is(cmsBase64)));
MvcResult mvcResult = mockMvc.perform(get("/cms-migration")
.header(dgcConfigProperties.getCertAuth().getHeaderFields().getThumbprint(), authCertHash)
.header(dgcConfigProperties.getCertAuth().getHeaderFields().getDistinguishedName(), authCertSubject))
.andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].type", is(CmsPackageDto.CmsPackageTypeDto.DSC.name())))
.andExpect(jsonPath("$[1].type", is(CmsPackageDto.CmsPackageTypeDto.REVOCATION_LIST.name())))
.andExpect(jsonPath("$[1].cms", is(cmsBase64)))
.andExpect(jsonPath("$[2].type", is(CmsPackageDto.CmsPackageTypeDto.VALIDATION_RULE.name())))
.andExpect(jsonPath("$[2].cms", is(cmsBase64)))
.andReturn();

List<CmsPackageDto> response = objectMapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() {
});
SignedCertificateMessageParser parser = new SignedCertificateMessageParser(response.get(0).getCms());
Assertions.assertEquals(SignedMessageParser.ParserState.SUCCESS, parser.getParserState());
Assertions.assertTrue(parser.isSignatureVerified());
Assertions.assertArrayEquals(certDscEu.getEncoded(), parser.getPayload().getEncoded());
}

@Test
Expand Down

0 comments on commit fbdff82

Please sign in to comment.