Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/insert manager #213

Merged
merged 13 commits into from
Sep 9, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import org.dpppt.backend.sdk.ws.controller.GaenController;
import org.dpppt.backend.sdk.ws.filter.ResponseWrapperFilter;
import org.dpppt.backend.sdk.ws.insertmanager.InsertManager;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.AssertBase64;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.AssertKeyFormat;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.EnforceMatchingJWTClaimsForExposed;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.EnforceMatchingJWTClaimsForExposedNextDay;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.EnforceRetentionPeriod;
Expand Down Expand Up @@ -217,7 +217,7 @@ public ProtoSignature gaenSigner() {
@Bean
public InsertManager insertManagerExposed() {
var manager = new InsertManager(gaenDataService(), gaenValidationUtils());
manager.addFilter(new AssertBase64(gaenValidationUtils()));
manager.addFilter(new AssertKeyFormat(gaenValidationUtils()));
manager.addFilter(new EnforceMatchingJWTClaimsForExposed(gaenRequestValidator));
manager.addFilter(new RemoveKeysFromFuture());
manager.addFilter(new EnforceRetentionPeriod(gaenValidationUtils()));
Expand All @@ -229,7 +229,7 @@ public InsertManager insertManagerExposed() {
@Bean
public InsertManager insertManagerExposedNextDay() {
var manager = new InsertManager(gaenDataService(), gaenValidationUtils());
manager.addFilter(new AssertBase64(gaenValidationUtils()));
manager.addFilter(new AssertKeyFormat(gaenValidationUtils()));
manager.addFilter(new EnforceMatchingJWTClaimsForExposedNextDay(gaenValidationUtils()));
manager.addFilter(new RemoveKeysFromFuture());
manager.addFilter(new EnforceRetentionPeriod(gaenValidationUtils()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public DPPPTController(
if (!this.validateRequest.isValid(principal)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
if (!validationUtils.isValidBase64Key(exposeeRequest.getKey())) {
if (!validationUtils.isValidKeyFormat(exposeeRequest.getKey())) {
return new ResponseEntity<>("No valid base64 key", HttpStatus.BAD_REQUEST);
}
// TODO: should we give that information?
Expand Down Expand Up @@ -186,7 +186,7 @@ public DPPPTController(

List<Exposee> exposees = new ArrayList<>();
for (var exposedKey : exposeeRequests.getExposedKeys()) {
if (!validationUtils.isValidBase64Key(exposedKey.getKey())) {
if (!validationUtils.isValidKeyFormat(exposedKey.getKey())) {
return new ResponseEntity<>("No valid base64 key", HttpStatus.BAD_REQUEST);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public DebugController(

List<GaenKey> nonFakeKeys = new ArrayList<>();
for (var key : gaenRequest.getGaenKeys()) {
if (!validationUtils.isValidBase64Key(key.getKeyData())) {
if (!validationUtils.isValidKeyFormat(key.getKeyData())) {
return new ResponseEntity<>("No valid base64 key", HttpStatus.BAD_REQUEST);
}
this.validateRequest.validateKeyDate(now, principal, key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import org.dpppt.backend.sdk.utils.UTCInstant;
import org.dpppt.backend.sdk.ws.insertmanager.InsertException;
import org.dpppt.backend.sdk.ws.insertmanager.InsertManager;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.AssertBase64.KeyIsNotBase64Exception;
import org.dpppt.backend.sdk.ws.insertmanager.insertionfilters.AssertKeyFormat.KeyFormatException;
import org.dpppt.backend.sdk.ws.security.ValidateRequest;
import org.dpppt.backend.sdk.ws.security.ValidateRequest.ClaimIsBeforeOnsetException;
import org.dpppt.backend.sdk.ws.security.ValidateRequest.InvalidDateException;
Expand Down Expand Up @@ -355,7 +355,7 @@ public ResponseEntity<String> delayedKeyDateIsInvalid() {
BadBatchReleaseTimeException.class,
DateTimeParseException.class,
ClaimIsBeforeOnsetException.class,
KeyIsNotBase64Exception.class
KeyFormatException.class
})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Object> invalidArguments() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Encapsulating the logic into smaller pieces of code, should allow for easier and

## Valid Keys
A valid key is defined as follows:
- Base64 Encoded key
- Base64 Encoded key with correct length of 32 bytes
- Non Fake
- Rolling Period in [1..144]
- Rolling start number inside the configured retention period
Expand Down Expand Up @@ -78,7 +78,7 @@ public abstract class WSBaseConfig implements SchedulingConfigurer, WebMvcConfig
@Bean
public InsertManager insertManagerExposed() {
var manager = new InsertManager(gaenDataService(), gaenValidationUtils());
manager.addFilter(new AssertBase64(gaenValidationUtils()));
manager.addFilter(new AssertKeyFormst(gaenValidationUtils()));
ineiti marked this conversation as resolved.
Show resolved Hide resolved
manager.addFilter(new EnforceMatchingJWTClaimsForExposed(gaenRequestValidator));
manager.addFilter(new RemoveKeysFromFuture());
manager.addFilter(new EnforceRetentionPeriod(gaenValidationUtils()));
Expand All @@ -90,7 +90,7 @@ public abstract class WSBaseConfig implements SchedulingConfigurer, WebMvcConfig
@Bean
public InsertManager insertManagerExposedNextDay() {
var manager = new InsertManager(gaenDataService(), gaenValidationUtils());
manager.addFilter(new AssertBase64(gaenValidationUtils()));
manager.addFilter(new AssertKeyFormat(gaenValidationUtils()));
manager.addFilter(new EnforceMatchingJWTClaimsForExposedNextDay(gaenValidationUtils()));
manager.addFilter(new RemoveKeysFromFuture());
manager.addFilter(new EnforceRetentionPeriod(gaenValidationUtils()));
Expand All @@ -102,8 +102,12 @@ public abstract class WSBaseConfig implements SchedulingConfigurer, WebMvcConfig
}
```

- `AssertBase64`
> This filter validates that the key actually is a correctly encoded base64 string. Since we are using 16 bytes of key data, those can be represented with exactly 24 characters. The validation of the length is already done during model validation and is assumed to be correct when reaching the filter. This filter _throws_ a `KeyIsNotBase64Exception` if any of the keys is wrongly encoded. Every key submitted _MUST_ have correct base64 encoding
- `AssertKeyFormat`
> This filter validates that the key actually is a correctly encoded base64 string and has the correct length. Since
we are using 16 bytes of key data, those can be represented with exactly 24 characters. The validation of the
length is already done during model validation and is assumed to be correct when reaching the filter. This
filter _throws_ a `KeyFormatException` if any of the keys is wrongly encoded. Every key submitted _MUST_ have
correct base64 encoding and have the correct length.
- `EnforceMatchingJWTClaimsForExposed`:
> This filter compares the supplied keys with information found in the JWT token for the `exposed` request. It makes sure, that the onset date, which will be set by the health authority and inserted as a claim into the JWT is the lower bound for allowed key dates.
- `EnforceMatchingJWTClaimsForExposedNextDay`:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
import org.dpppt.backend.sdk.ws.util.ValidationUtils;

/**
* Rejects a batch of keys if any of them have an invalid base64 encoding. Invalid base64 encodings
* point to a client error.
* Rejects a batch of keys if any of them have an invalid base64 encoding or doesn't have the
* correct length. Invalid base64 encodings or wrong key lengths point to a client error.
*/
public class AssertBase64 implements KeyInsertionFilter {
public class AssertKeyFormat implements KeyInsertionFilter {

private final ValidationUtils validationUtils;

public AssertBase64(ValidationUtils validationUtils) {
public AssertKeyFormat(ValidationUtils validationUtils) {
this.validationUtils = validationUtils;
}

Expand All @@ -31,15 +31,15 @@ public List<GaenKey> filter(
throws InsertException {

var hasInvalidKeys =
content.stream().anyMatch(key -> !validationUtils.isValidBase64Key(key.getKeyData()));
content.stream().anyMatch(key -> !validationUtils.isValidKeyFormat(key.getKeyData()));

if (hasInvalidKeys) {
throw new KeyIsNotBase64Exception();
throw new KeyFormatException();
}
return content;
}

public class KeyIsNotBase64Exception extends InsertException {
public class KeyFormatException extends InsertException {

/** */
private static final long serialVersionUID = -918099046973553472L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,15 @@ public ValidationUtils(int keyLengthBytes, Duration retentionPeriod, Long releas
}

/**
* Check the validty of a base64 value
* Check the validity of a base64 encoded key by decoding it and checking the key length
*
* @param value representation of a base64 value
* @return if _value_ is a valid representation
*/
public boolean isValidBase64Key(String value) {
public boolean isValidKeyFormat(String value) {
try {
byte[] key = Base64.getDecoder().decode(value);
if (key.length != KEY_LENGTH_BYTES) {
return false;
}
return true;
return key.length == KEY_LENGTH_BYTES;
} catch (Exception e) {
return false;
}
Expand Down