Skip to content

Commit

Permalink
RIPE NCC has merged 4b1d29cc5
Browse files Browse the repository at this point in the history
* Update dependency org.eclipse.jgit:org.eclipse.jgit to v7.1.0.202411261347-r [12d41a2b2]
* Update dependency net.jqwik:jqwik to v1.9.2 [351be004b]
* Remove review-apps from Gitlab pipeline [35a54fa07]
* Update dependency org.sonarqube:org.sonarqube.gradle.plugin to v6 [1f5aa6978]
* Update dependency io.sentry:sentry-bom to v7.18.1 [3d507a92a]
* Update dependency io.freefair.lombok:io.freefair.lombok.gradle.plugin to v8.11 [7043705fb]
* Update dependency gradle [8fe1cd99e]
* Update dependency commons-io:commons-io to v2.18.0 [7f82ba930]
* Add test specific to request ID checks [648f7f8d4]
* Add check for request IDs when processing TA response [737170352]
  • Loading branch information
RPKI Team at RIPE NCC committed Dec 6, 2024
1 parent d03dc7e commit 5d162ab
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 43 deletions.
14 changes: 1 addition & 13 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
default:
image: gradle:8.10-jdk17
image: gradle:8.11-jdk17

# Explicit version of the Mergerequests-Pipelines workflow, with the main branch
# added.
Expand All @@ -15,7 +15,6 @@ stages:
- test
- qa
- package
- review
- deploy
- publish

Expand All @@ -27,10 +26,6 @@ include:
file: '/templates/mend-scanning.yml'
- project: 'swe/gitlab-ci'
file: '/templates/mend-generate-badge.yml'
# Review Apps
- project: 'rpki/helm-charts'
file: '/gitlab/review.yml'


variables:
BUILD_NUMBER: ${CI_COMMIT_REF_SLUG}-${CI_PIPELINE_ID}
Expand Down Expand Up @@ -207,10 +202,3 @@ publish-to-github:
- if: $CI_COMMIT_BRANCH == "main"
when: on_success
- when: never

review:
variables:
GIT_STRATEGY: none
RPKI_CORE_IMAGE: $CI_REGISTRY_IMAGE/ci:ci-step-$BUILD_NUMBER
needs:
- build-image
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
implementation "org.thymeleaf:thymeleaf:3.1.2.RELEASE"
implementation "org.thymeleaf:thymeleaf-spring6:3.1.2.RELEASE"

implementation platform('io.sentry:sentry-bom:7.16.0')
implementation platform('io.sentry:sentry-bom:7.18.1')
implementation 'io.sentry:sentry-spring-boot-starter'
implementation 'io.sentry:sentry-logback'

Expand All @@ -59,7 +59,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.jamesmurty.utils:java-xmlbuilder:1.3'
implementation 'commons-codec:commons-codec:1.17.1'
implementation 'commons-io:commons-io:2.17.0'
implementation 'commons-io:commons-io:2.18.0'
implementation 'ch.qos.logback.contrib:logback-json-classic:0.1.5'
implementation 'ch.qos.logback.contrib:logback-jackson:0.1.5'
implementation 'net.logstash.logback:logstash-logback-encoder:8.0'
Expand All @@ -73,7 +73,7 @@ dependencies {
}

testImplementation "org.wiremock:wiremock-jetty12:3.9.2"
testImplementation 'net.jqwik:jqwik:1.9.1'
testImplementation 'net.jqwik:jqwik:1.9.2'
testImplementation "net.ripe.rpki:rpki-commons:$rpki_commons_version:tests"
testImplementation 'org.assertj:assertj-core'

Expand Down
6 changes: 3 additions & 3 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ repositories {
}

dependencies {
implementation 'io.freefair.lombok:io.freefair.lombok.gradle.plugin:8.10.2'
implementation 'io.freefair.lombok:io.freefair.lombok.gradle.plugin:8.11'
implementation('com.gorylenko.gradle-git-properties:com.gorylenko.gradle-git-properties.gradle.plugin:2.4.2') {
exclude group: 'org.eclipse.jgit', module: 'org.eclipse.jgit'
}
implementation 'org.eclipse.jgit:org.eclipse.jgit:7.0.0.202409031743-r'
implementation 'org.sonarqube:org.sonarqube.gradle.plugin:5.1.0.4882'
implementation 'org.eclipse.jgit:org.eclipse.jgit:7.1.0.202411261347-r'
implementation 'org.sonarqube:org.sonarqube.gradle.plugin:6.0.1.5171'
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.ripe.rpki.commons.crypto.CertificateRepositoryObject;
import net.ripe.rpki.commons.crypto.util.EncodedPublicKey;
import net.ripe.rpki.commons.crypto.util.SignedObjectUtil;
import net.ripe.rpki.commons.ta.domain.request.TrustAnchorRequest;
import net.ripe.rpki.domain.*;
import net.ripe.rpki.domain.archive.KeyPairDeletionService;
import net.ripe.rpki.domain.interca.CertificateIssuanceResponse;
Expand All @@ -29,11 +30,7 @@
import jakarta.persistence.PersistenceContext;
import javax.security.auth.x500.X500Principal;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -196,7 +193,7 @@ private void validateResponse(AllResourcesCertificateAuthority allResourcesCa, T

validatePendingRequestExists(upStreamCaRequestEntity);
validateResponseContainsTrustAnchorResponse(response);
validateRequestAndResponseHaveSameTimeStamp(response, upStreamCaRequestEntity);
validateResponseIsForTheCorrectRequest(response, upStreamCaRequestEntity);
}

private void validateResponseContainsTrustAnchorResponse(TrustAnchorResponse response) {
Expand All @@ -211,15 +208,31 @@ private void validatePendingRequestExists(UpStreamCARequestEntity upStreamCARequ
}
}

private void validateRequestAndResponseHaveSameTimeStamp(TrustAnchorResponse response, UpStreamCARequestEntity upStreamCARequestEntity) {
long creationTimeMillis = upStreamCARequestEntity.getUpStreamCARequest().getCreationTimestamp();
private void validateResponseIsForTheCorrectRequest(TrustAnchorResponse response, UpStreamCARequestEntity upStreamCARequestEntity) {
TrustAnchorRequest upStreamCARequest = upStreamCARequestEntity.getUpStreamCARequest();
long creationTimeMillis = upStreamCARequest.getCreationTimestamp();
long correspondingRequestCreationTimeStamp = response.getRequestCreationTimestamp();

if (creationTimeMillis != correspondingRequestCreationTimeStamp) {
throw new OfflineResponseProcessorException("Response seems related to request dated: "
+ new DateTime(correspondingRequestCreationTimeStamp) + ", but current pending request is dated: "
+ new DateTime(creationTimeMillis));
}

Set<UUID> requestIdsInRequests = upStreamCARequest.getTaRequests().stream()
.map(TaRequest::getRequestId)
.collect(Collectors.toSet());

Set<UUID> requestIdsInResponse = response.getTaResponses().stream()
.map(TaResponse::getRequestId)
.collect(Collectors.toSet());

if (!requestIdsInRequests.equals(requestIdsInResponse)) {
throw new OfflineResponseProcessorException(
"Response is generated for the request with the set of IDs: "
+ requestIdsInResponse + ", but current pending request has IDs: "
+ requestIdsInRequests);
}
}

private AllResourcesCertificateAuthority getAllResourcesCa() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public class TrustAnchorResponseProcessorTest {
@Rule
public FixedDateRule fixedDateRule = new FixedDateRule(1);


private static final X500Principal CA_NAME = new X500Principal("CN=test");
private static final X509ResourceCertificate NEW_CERTIFICATE = createSelfSignedCaResourceCertificate(new IpResourceSet(ALL_PRIVATE_USE_RESOURCES));
private static final String NEW_CERTIFICATE_FILE_NAME = "cert.cer";
Expand Down Expand Up @@ -92,7 +91,9 @@ public void should_process_a_sign_response_and_remove_pending_request() {
given(allResourcesCertificateAuthority.getUpStreamCARequestEntity()).willReturn(pendingRequest);
given(certificateAuthorityRepository.findAllResourcesCAByName(CA_NAME)).willReturn(allResourcesCertificateAuthority);

subject.process(getResponseWithSignedCertificates(1L, TA_OBJECTS, TEST_SIGN_RESPONSE));
UUID requestId = pendingRequest.getUpStreamCARequest().getTaRequests().get(0).getRequestId();
var signingResponse = new SigningResponse(requestId, "RIPE", NEW_CERTIFICATE_PUBLICATION_URI, NEW_CERTIFICATE);
subject.process(getResponseWithSignedCertificates(1L, TA_OBJECTS, signingResponse));

// expect that the pending request is revoked
verify(allResourcesCertificateAuthority).setUpStreamCARequestEntity(null);
Expand Down Expand Up @@ -168,17 +169,27 @@ public void shouldRejectWhenResponseSeemsToReferToOtherRequest() {

@Test(expected = OfflineResponseProcessorException.class )
public void shouldRejectWhenNoPendingRequestFound() {

TrustAnchorResponse taResponse = getResponseWithSignedCertificates(1L, TA_OBJECTS, TEST_SIGN_RESPONSE);
when(certificateAuthorityRepository.findAllResourcesCAByName(CA_NAME)).thenReturn(allResourcesCA);

subject.process(taResponse);
}

@Test(expected = OfflineResponseProcessorException.class )
public void shouldRejectWhenResponseContainsDifferentRequestIds() {
setUpPendingCertificateSigningRequest();
Long creationTimestamp = allResourcesCA.getUpStreamCARequestEntity().getUpStreamCARequest().getCreationTimestamp();

SigningResponse signingResponse = new SigningResponse(UUID.randomUUID(), "RIPE", NEW_CERTIFICATE_PUBLICATION_URI, NEW_CERTIFICATE);
TrustAnchorResponse taResponse = getResponseWithSignedCertificates(creationTimestamp, TA_OBJECTS, signingResponse);
when(certificateAuthorityRepository.findAllResourcesCAByName(CA_NAME)).thenReturn(allResourcesCA);

subject.process(taResponse);
}

@Test
public void shouldNotifyACAAboutRevokedKeys() {
String pubKeyIdentifier = "CN=testkey";
TrustAnchorResponse combinedResponse = getResponseWithRevocationResponse(1L, TA_OBJECTS, pubKeyIdentifier);

// make sure there is a pending request
setUpPendingRevocationRequest();
Expand All @@ -190,6 +201,8 @@ public void shouldNotifyACAAboutRevokedKeys() {
entityManager.remove(isA(UpStreamCARequestEntity.class));
entityManager.flush();

UUID requestId = allResourcesCA.getUpStreamCARequestEntity().getUpStreamCARequest().getTaRequests().get(0).getRequestId();
TrustAnchorResponse combinedResponse = getResponseWithRevocationResponse(1L, TA_OBJECTS, pubKeyIdentifier, requestId);
assertThatThrownBy(() -> subject.process(combinedResponse))
.isInstanceOf(CertificateAuthorityException.class)
.hasMessage("Unknown encoded key: " + pubKeyIdentifier);
Expand All @@ -198,8 +211,6 @@ public void shouldNotifyACAAboutRevokedKeys() {

@Test
public void shouldRemoveRequestOnErrorResponse() {
TrustAnchorResponse taResponse = getResponseWithErrorResponse(1L, TA_OBJECTS);

// make sure there is a pending request
setUpPendingRevocationRequest();

Expand All @@ -209,6 +220,8 @@ public void shouldRemoveRequestOnErrorResponse() {
entityManager.remove(isA(UpStreamCARequestEntity.class));
entityManager.flush();

UUID requestId = allResourcesCA.getUpStreamCARequestEntity().getUpStreamCARequest().getTaRequests().get(0).getRequestId();
TrustAnchorResponse taResponse = getResponseWithErrorResponse(1L, TA_OBJECTS, requestId);
subject.process(taResponse);

assertThat(allResourcesCA.getUpStreamCARequestEntity()).isNull();
Expand Down Expand Up @@ -249,33 +262,35 @@ private TrustAnchorRequest createTrustAnchorRequest(AllResourcesCertificateAutho
TestObjects.SUBJECT_INFORMATION_ACCESS, requests);
}

public static TrustAnchorResponse getResponseWithSignedCertificates(Long serial, Map<URI, CertificateRepositoryObject> publishedObjects, SigningResponse response) {
public static TrustAnchorResponse getResponseWithSignedCertificates(
Long serial, Map<URI, CertificateRepositoryObject> publishedObjects, SigningResponse response) {

TrustAnchorResponse.Builder builder = TrustAnchorResponse.newBuilder(serial);

builder.addPublishedObjects(publishedObjects);
builder.addTaResponse(response);

return builder.build();
}

public static TrustAnchorResponse getResponseWithErrorResponse(Long serial, Map<URI, CertificateRepositoryObject> publishedObjects) {
public static TrustAnchorResponse getResponseWithErrorResponse(
Long serial,
Map<URI, CertificateRepositoryObject> publishedObjects,
UUID uuid) {
TrustAnchorResponse.Builder builder = TrustAnchorResponse.newBuilder(serial);

builder.addPublishedObjects(publishedObjects);
builder.addTaResponse(new ErrorResponse(UUID.randomUUID(), "User cancelled to proceed. Request will not be processed."));

builder.addTaResponse(new ErrorResponse(uuid, "User cancelled to proceed. Request will not be processed."));
return builder.build();
}

public static TrustAnchorResponse getResponseWithRevocationResponse(Long serial, Map<URI, CertificateRepositoryObject> publishedObjects, String encodedKey) {
public static TrustAnchorResponse getResponseWithRevocationResponse(
Long serial, Map<URI, CertificateRepositoryObject> publishedObjects, String encodedKey, UUID uuid) {
TrustAnchorResponse.Builder builder = TrustAnchorResponse.newBuilder(serial);

RevocationResponse revocationResponse = new RevocationResponse(UUID.randomUUID(), "test resource class", encodedKey);
RevocationResponse revocationResponse = new RevocationResponse(
uuid, "test resource class", encodedKey);

builder.addPublishedObjects(publishedObjects);
builder.addTaResponse(revocationResponse);

return builder.build();
}

Expand Down

0 comments on commit 5d162ab

Please sign in to comment.