-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #83 from eu-digital-green-certificates/feat/revoca…
…tion_list_download Feat/revocation list download
- Loading branch information
Showing
10 changed files
with
819 additions
and
0 deletions.
There are no files selected for viewing
132 changes: 132 additions & 0 deletions
132
...in/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayRevocationListDownloadConnector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package eu.europa.ec.dgc.gateway.connector; | ||
|
||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.DeserializationFeature; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import eu.europa.ec.dgc.gateway.connector.client.DgcGatewayConnectorRestClient; | ||
import eu.europa.ec.dgc.gateway.connector.dto.RevocationBatchDto; | ||
import eu.europa.ec.dgc.gateway.connector.exception.RevocationBatchDownloadException; | ||
import eu.europa.ec.dgc.gateway.connector.exception.RevocationBatchGoneException; | ||
import eu.europa.ec.dgc.gateway.connector.exception.RevocationBatchParseException; | ||
import eu.europa.ec.dgc.gateway.connector.iterator.DgcGatewayRevocationListDownloadIterator; | ||
import eu.europa.ec.dgc.signing.SignedMessageParser; | ||
import eu.europa.ec.dgc.signing.SignedStringMessageParser; | ||
import feign.FeignException; | ||
import java.time.ZonedDateTime; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.config.ConfigurableBeanFactory; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
import org.springframework.context.annotation.Scope; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Service; | ||
|
||
@ConditionalOnProperty("dgc.gateway.connector.enabled") | ||
@Service | ||
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class DgcGatewayRevocationListDownloadConnector { | ||
|
||
private final DgcGatewayConnectorRestClient dgcGatewayConnectorRestClient; | ||
private final ObjectMapper objectMapper; | ||
|
||
/** | ||
* Gets a revocation list iterator, for partly downloading the revocation list. | ||
* The if-modified-since header is set to the default value to start at the beginning of the list. | ||
* @return revocation list iterator | ||
*/ | ||
public DgcGatewayRevocationListDownloadIterator getRevocationListDownloadIterator() { | ||
return new DgcGatewayRevocationListDownloadIterator(dgcGatewayConnectorRestClient); | ||
} | ||
|
||
/** | ||
* Gets a revocation list iterator, for partly downloading the revocation list. | ||
* The if-modified-since header is set to the value of the parameter. Only newer part of the list are downloaded. | ||
* @param ifModifiedSinceDate The value for the if-modified-since header | ||
* @return revocation list iterator | ||
*/ | ||
public DgcGatewayRevocationListDownloadIterator getRevocationListDownloadIterator( | ||
ZonedDateTime ifModifiedSinceDate) { | ||
|
||
return new DgcGatewayRevocationListDownloadIterator(dgcGatewayConnectorRestClient, ifModifiedSinceDate); | ||
} | ||
|
||
/** | ||
* Gets the revocation list batch data for a given batchId. | ||
* @param batchId the id of the batch to download. | ||
* @return the batch data. | ||
*/ | ||
public RevocationBatchDto getRevocationListBatchById(String batchId) throws RevocationBatchDownloadException, | ||
RevocationBatchGoneException, RevocationBatchParseException { | ||
|
||
ResponseEntity<String> responseEntity; | ||
|
||
try { | ||
responseEntity = dgcGatewayConnectorRestClient.downloadBatch(batchId); | ||
} catch (FeignException e) { | ||
log.error("Download of revocation list batch failed. DGCG responded with status code: {}", e.status()); | ||
|
||
if (e.status() == HttpStatus.GONE.value()) { | ||
throw new RevocationBatchGoneException(String.format("Batch already gone: %s", batchId),batchId); | ||
} | ||
|
||
throw new RevocationBatchDownloadException("Batch download failed with exception.", e); | ||
} | ||
|
||
if (responseEntity.getStatusCode() != HttpStatus.OK) { | ||
int statusCode = responseEntity.getStatusCode().value(); | ||
log.error("Download of revocation list batch failed. DGCG responded with status code: {}", statusCode); | ||
|
||
throw new RevocationBatchDownloadException( | ||
String.format("Batch download failed with unexpected response. Response status code: %d", statusCode), | ||
statusCode); | ||
} | ||
|
||
String cms = responseEntity.getBody(); | ||
|
||
if (!checkCmsSignature(cms)) { | ||
log.error("CMS check failed for revocation batch: {}", batchId); | ||
throw new RevocationBatchParseException( | ||
String.format("CMS check failed for revocation batch: %s", batchId), batchId); | ||
} | ||
|
||
return map(cms, batchId); | ||
} | ||
|
||
private boolean checkCmsSignature(String cms) { | ||
SignedStringMessageParser parser = | ||
new SignedStringMessageParser(cms); | ||
|
||
if (parser.getParserState() != SignedMessageParser.ParserState.SUCCESS) { | ||
log.error("Invalid CMS for Revocation List Batch."); | ||
return false; | ||
} | ||
|
||
if (!parser.isSignatureVerified()) { | ||
log.error("Invalid CMS Signature for Revocation List Batch"); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private RevocationBatchDto map(String cms, String batchId) { | ||
SignedStringMessageParser parser = | ||
new SignedStringMessageParser(cms); | ||
|
||
try { | ||
objectMapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); | ||
return objectMapper.readValue(parser.getPayload(), RevocationBatchDto.class); | ||
} catch (JsonProcessingException e) { | ||
log.error("Failed to parse revocation batch JSON: {}", e.getMessage()); | ||
|
||
throw new RevocationBatchParseException( | ||
String.format("Failed to parse revocation batch JSON: %s", e.getMessage()), batchId); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
src/main/java/eu/europa/ec/dgc/gateway/connector/dto/RevocationBatchDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/*- | ||
* ---license-start | ||
* eu-digital-green-certificates / dgc-lib | ||
* --- | ||
* Copyright (C) 2022 T-Systems International GmbH and all other contributors | ||
* --- | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ---license-end | ||
*/ | ||
|
||
package eu.europa.ec.dgc.gateway.connector.dto; | ||
|
||
import java.time.ZonedDateTime; | ||
import java.util.List; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
|
||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class RevocationBatchDto { | ||
|
||
private String country; | ||
|
||
private ZonedDateTime expires; | ||
|
||
private String kid; | ||
|
||
private RevocationHashTypeDto hashType; | ||
|
||
private List<BatchEntryDto> entries; | ||
|
||
@Data | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public static class BatchEntryDto { | ||
|
||
private String hash; | ||
|
||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/eu/europa/ec/dgc/gateway/connector/dto/RevocationBatchListDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/*- | ||
* ---license-start | ||
* eu-digital-green-certificates / dgc-lib | ||
* --- | ||
* Copyright (C) 2022 T-Systems International GmbH and all other contributors | ||
* --- | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ---license-end | ||
*/ | ||
|
||
package eu.europa.ec.dgc.gateway.connector.dto; | ||
|
||
import java.time.ZonedDateTime; | ||
import java.util.List; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
|
||
@Data | ||
public class RevocationBatchListDto { | ||
|
||
|
||
private Boolean more; | ||
|
||
private List<RevocationBatchListItemDto> batches; | ||
|
||
@Data | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
public static class RevocationBatchListItemDto { | ||
|
||
private String batchId; | ||
|
||
private String country; | ||
|
||
private ZonedDateTime date; | ||
|
||
private Boolean deleted; | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/eu/europa/ec/dgc/gateway/connector/dto/RevocationHashTypeDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/*- | ||
* ---license-start | ||
* eu-digital-green-certificates / dgc-lib | ||
* --- | ||
* Copyright (C) 2022 T-Systems International GmbH and all other contributors | ||
* --- | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* ---license-end | ||
*/ | ||
|
||
package eu.europa.ec.dgc.gateway.connector.dto; | ||
|
||
// Type of hash for revocation lists | ||
public enum RevocationHashTypeDto { | ||
|
||
// The hash is calculated over the UCI string encoded in UTF-8 and converted to a byte array. | ||
UCI, | ||
|
||
// The hash is calculated over the bytes of the COSE_SIGN1 signature from the CWT | ||
SIGNATURE, | ||
|
||
// The CountryCode encoded as a UTF-8 string concatenated with the UCI encoded with a | ||
// UTF-8 string. This is then converted to a byte array and used as input to the hash function.") | ||
COUNTRYCODEUCI | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
...n/java/eu/europa/ec/dgc/gateway/connector/exception/RevocationBatchDownloadException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package eu.europa.ec.dgc.gateway.connector.exception; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class RevocationBatchDownloadException extends RuntimeException { | ||
|
||
|
||
private final int status; | ||
|
||
public RevocationBatchDownloadException(String message, Throwable inner) { | ||
super(message, inner); | ||
this.status = 500; | ||
} | ||
|
||
public RevocationBatchDownloadException(String message) { | ||
super(message); | ||
this.status = 500; | ||
} | ||
|
||
public RevocationBatchDownloadException(String message, Throwable inner, int status) { | ||
super(message, inner); | ||
this.status = status; | ||
} | ||
|
||
public RevocationBatchDownloadException(String message, int status) { | ||
super(message); | ||
this.status = status; | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/eu/europa/ec/dgc/gateway/connector/exception/RevocationBatchGoneException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package eu.europa.ec.dgc.gateway.connector.exception; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class RevocationBatchGoneException extends RuntimeException { | ||
|
||
private final String batchId; | ||
|
||
public RevocationBatchGoneException(String message, String batchId) { | ||
super(message); | ||
this.batchId = batchId; | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
...main/java/eu/europa/ec/dgc/gateway/connector/exception/RevocationBatchParseException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package eu.europa.ec.dgc.gateway.connector.exception; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public class RevocationBatchParseException extends RuntimeException { | ||
|
||
private final String batchId; | ||
|
||
public RevocationBatchParseException(String message, String batchId) { | ||
super(message); | ||
this.batchId = batchId; | ||
} | ||
|
||
} | ||
|
Oops, something went wrong.