Skip to content
This repository was archived by the owner on May 16, 2023. It is now read-only.

Commit 177336a

Browse files
authored
Merge pull request #29 from corona-warn-app/fix/signing-race-condition
Fix: Possible Race Condition when Signing DCC
2 parents e0ec430 + 5e0c46c commit 177336a

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

src/main/java/app/coronawarn/dcc/controller/InternalDccController.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,10 @@ public ResponseEntity<?> uploadDcc(
116116
throw new DccServerException(HttpStatus.BAD_REQUEST, "Invalid Base64 in DEK or encrypted DCC.");
117117
}
118118

119-
dccRegistrationService.updateDccRegistration(
120-
dccRegistration,
121-
uploadRequest.getDccHash(),
122-
uploadRequest.getEncryptedDcc(),
123-
uploadRequest.getDataEncryptionKey(),
124-
partnerId);
119+
dccRegistration.setDccHash(uploadRequest.getDccHash());
120+
dccRegistration.setDccEncryptedPayload(uploadRequest.getEncryptedDcc());
121+
dccRegistration.setEncryptedDataEncryptionKey(uploadRequest.getDataEncryptionKey());
122+
dccRegistration.setPartnerId(partnerId);
125123

126124
try {
127125
dccRegistration = dccService.sign(dccRegistration);
@@ -140,6 +138,13 @@ public ResponseEntity<?> uploadDcc(
140138
.body(new DccUnexpectedError(dccRegistration.getError()));
141139
}
142140

141+
dccRegistrationService.updateDccRegistration(
142+
dccRegistration,
143+
uploadRequest.getDccHash(),
144+
uploadRequest.getEncryptedDcc(),
145+
uploadRequest.getDataEncryptionKey(),
146+
partnerId);
147+
143148
return ResponseEntity.ok(new DccUploadResponse(dccRegistration.getDcc()));
144149
}
145150
}

src/main/java/app/coronawarn/dcc/service/DccRegistrationService.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.Base64;
3737
import java.util.List;
3838
import java.util.Optional;
39+
import javax.validation.constraints.NotNull;
3940
import lombok.Getter;
4041
import lombok.RequiredArgsConstructor;
4142
import lombok.extern.slf4j.Slf4j;
@@ -133,24 +134,30 @@ public DccRegistration updateDccRegistration(
133134

134135
/**
135136
* Sets the Error Property on a DCC Registration and saves it into DB.
137+
* This method also deletes previously saved DCC details from entity.
136138
*
137139
* @param registration The target DCC Registration
138140
* @param reason the new Error Reason
139141
* @return the updated Registration Entity
140142
*/
141143
public DccRegistration setError(DccRegistration registration, DccErrorReason reason) {
144+
registration.setDcc(null);
145+
registration.setDccHash(null);
146+
registration.setPartnerId(null);
147+
registration.setEncryptedDataEncryptionKey(null);
142148
registration.setError(reason);
143149
return dccRegistrationRepository.save(registration);
144150
}
145151

146152
/**
147-
* Sets the DCC Property on a DCC Registration and saves it into DB.
153+
* Sets the DCC Property and resets error on a DCC Registration and saves it into DB.
148154
*
149155
* @param registration The target DCC Registration
150156
* @param dcc the base64 encoded DCC
151157
* @return the updated Registration Entity
152158
*/
153-
public DccRegistration setDcc(DccRegistration registration, String dcc) {
159+
public DccRegistration setDcc(DccRegistration registration, @NotNull String dcc) {
160+
registration.setError(null);
154161
registration.setDcc(dcc);
155162
return dccRegistrationRepository.save(registration);
156163
}

src/main/java/app/coronawarn/dcc/service/DccService.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,7 @@ public DccRegistration sign(DccRegistration registration) throws DccGenerateExce
7676
}
7777
}
7878

79-
registration = dccRegistrationService.setDcc(registration, Base64.getEncoder().encodeToString(coseBytes));
80-
81-
// Reset Error if everything is ok and it previously exists
82-
if (registration.getError() != null) {
83-
dccRegistrationService.setError(registration, null);
84-
}
85-
86-
return registration;
79+
return dccRegistrationService.setDcc(registration, Base64.getEncoder().encodeToString(coseBytes));
8780
}
8881

8982
private byte[] callSigningApiWithRetry(String hashBase64, String hashedLabId, String hashedDcci) {

src/test/java/app/coronawarn/dcc/service/DccServiceTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ void testSigningFailedOnFirstRequestButSuccessOnSecond() throws NoSuchAlgorithmE
224224
Assertions.assertEquals(DccErrorReason.SIGNING_SERVER_ERROR, registrationWithFailedSigning.getError());
225225
Assertions.assertNull(registrationWithFailedSigning.getDcc());
226226

227+
registrationWithFailedSigning.setDccHash(dccHash);
228+
registrationWithFailedSigning.setDccEncryptedPayload(Base64.getEncoder().encodeToString(encryptedDcc));
229+
registrationWithFailedSigning.setEncryptedDataEncryptionKey(Base64.getEncoder().encodeToString(encryptedDek));
230+
registrationWithFailedSigning.setPartnerId(partnerId);
231+
227232
Assertions.assertDoesNotThrow(() -> dccService.sign(registrationWithFailedSigning));
228233

229234
registration = dccRegistrationService.findByRegistrationToken(registrationTokenValue).orElseThrow();

0 commit comments

Comments
 (0)