use of net.ripe.rpki.validator3.domain.RpkiRepository in project rpki-validator-3 by RIPE-NCC.
the class CertificateTreeValidationService method validateCertificateAuthority.
private List<RpkiObject> validateCertificateAuthority(TrustAnchor trustAnchor, Map<URI, RpkiRepository> registeredRepositories, CertificateRepositoryObjectValidationContext context, ValidationResult validationResult) {
final List<RpkiObject> validatedObjects = new ArrayList<>();
ValidationLocation certificateLocation = validationResult.getCurrentLocation();
ValidationResult temporary = ValidationResult.withLocation(certificateLocation);
try {
RpkiRepository rpkiRepository = registerRepository(trustAnchor, registeredRepositories, context);
temporary.warnIfTrue(rpkiRepository.isPending(), VALIDATOR_RPKI_REPOSITORY_PENDING, rpkiRepository.getLocationUri());
if (rpkiRepository.isPending()) {
return validatedObjects;
}
X509ResourceCertificate certificate = context.getCertificate();
URI manifestUri = certificate.getManifestUri();
temporary.setLocation(new ValidationLocation(manifestUri));
Optional<RpkiObject> manifestObject = rpkiObjects.findLatestByTypeAndAuthorityKeyIdentifier(RpkiObject.Type.MFT, context.getSubjectKeyIdentifier());
if (!manifestObject.isPresent()) {
if (rpkiRepository.getStatus() == RpkiRepository.Status.FAILED) {
temporary.error(ValidationString.VALIDATOR_NO_MANIFEST_REPOSITORY_FAILED, rpkiRepository.getLocationUri());
} else {
temporary.error(ValidationString.VALIDATOR_NO_LOCAL_MANIFEST_NO_MANIFEST_IN_REPOSITORY, rpkiRepository.getLocationUri());
}
}
Optional<ManifestCms> maybeManifest = manifestObject.flatMap(x -> rpkiObjects.findCertificateRepositoryObject(x.getId(), ManifestCms.class, temporary));
temporary.rejectIfTrue(manifestObject.isPresent() && rpkiRepository.getStatus() == RpkiRepository.Status.FAILED && maybeManifest.isPresent() && maybeManifest.get().isPastValidityTime(), ValidationString.VALIDATOR_OLD_LOCAL_MANIFEST_REPOSITORY_FAILED, rpkiRepository.getLocationUri());
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
ManifestCms manifest = maybeManifest.get();
List<Map.Entry<String, byte[]>> crlEntries = manifest.getFiles().entrySet().stream().filter((entry) -> RepositoryObjectType.parse(entry.getKey()) == RepositoryObjectType.Crl).collect(toList());
temporary.rejectIfFalse(crlEntries.size() == 1, VALIDATOR_MANIFEST_CONTAINS_ONE_CRL_ENTRY, String.valueOf(crlEntries.size()));
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
Map.Entry<String, byte[]> crlEntry = crlEntries.get(0);
URI crlUri = manifestUri.resolve(crlEntry.getKey());
Optional<RpkiObject> crlObject = rpkiObjects.findBySha256(crlEntry.getValue());
temporary.rejectIfFalse(crlObject.isPresent(), VALIDATOR_CRL_FOUND, crlUri.toASCIIString());
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
temporary.setLocation(new ValidationLocation(crlUri));
Optional<X509Crl> crl = crlObject.flatMap(x -> rpkiObjects.findCertificateRepositoryObject(x.getId(), X509Crl.class, temporary));
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
crl.get().validate(crlUri.toASCIIString(), context, null, VALIDATION_OPTIONS, temporary);
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
temporary.setLocation(new ValidationLocation(manifestUri));
manifest.validate(manifestUri.toASCIIString(), context, crl.get(), manifest.getCrlUri(), VALIDATION_OPTIONS, temporary);
if (temporary.hasFailureForCurrentLocation()) {
return validatedObjects;
}
validatedObjects.add(manifestObject.get());
Map<URI, RpkiObject> manifestEntries = retrieveManifestEntries(manifest, manifestUri, temporary);
manifestEntries.forEach((location, obj) -> {
temporary.setLocation(new ValidationLocation(location));
Optional<CertificateRepositoryObject> maybeCertificateRepositoryObject = rpkiObjects.findCertificateRepositoryObject(obj.getId(), CertificateRepositoryObject.class, temporary);
if (temporary.hasFailureForCurrentLocation()) {
return;
}
maybeCertificateRepositoryObject.ifPresent(certificateRepositoryObject -> {
certificateRepositoryObject.validate(location.toASCIIString(), context, crl.get(), crlUri, VALIDATION_OPTIONS, temporary);
if (!temporary.hasFailureForCurrentLocation()) {
validatedObjects.add(obj);
}
if (certificateRepositoryObject instanceof X509ResourceCertificate && ((X509ResourceCertificate) certificateRepositoryObject).isCa() && !temporary.hasFailureForCurrentLocation()) {
CertificateRepositoryObjectValidationContext childContext = context.createChildContext(location, (X509ResourceCertificate) certificateRepositoryObject);
validatedObjects.addAll(validateCertificateAuthority(trustAnchor, registeredRepositories, childContext, temporary));
}
});
});
} catch (Exception e) {
log.debug("e", e);
validationResult.error(ErrorCodes.UNHANDLED_EXCEPTION, e.toString(), ExceptionUtils.getStackTrace(e));
} finally {
validationResult.addAll(temporary);
}
return validatedObjects;
}
use of net.ripe.rpki.validator3.domain.RpkiRepository in project rpki-validator-3 by RIPE-NCC.
the class RpkiRepositoryValidationService method validateRpkiRepository.
public void validateRpkiRepository(long rpkiRepositoryId) {
entityManager.setFlushMode(FlushModeType.COMMIT);
final RpkiRepository rpkiRepository = rpkiRepositories.get(rpkiRepositoryId);
log.info("Starting RPKI repository validation for " + rpkiRepository);
ValidationResult validationResult = ValidationResult.withLocation(rpkiRepository.getRrdpNotifyUri());
final RpkiRepositoryValidationRun validationRun = new RrdpRepositoryValidationRun(rpkiRepository);
validationRunRepository.add(validationRun);
final String uri = rpkiRepository.getRrdpNotifyUri();
if (isRrdpUri(uri)) {
rrdpService.storeRepository(rpkiRepository, validationRun);
if (validationRun.isFailed()) {
rpkiRepository.setFailed();
} else {
rpkiRepository.setDownloaded();
}
} else if (isRsyncUri(uri)) {
validationResult.error("rsync.repository.not.supported");
} else {
log.error("Unsupported type of the URI " + uri);
}
if (validationResult.hasFailures()) {
validationRun.setFailed();
} else {
validationRun.setSucceeded();
}
if (validationRun.isSucceeded() && validationRun.getAddedObjectCount() > 0) {
rpkiRepository.getTrustAnchors().forEach(validationRunRepository::runCertificateTreeValidation);
}
}
use of net.ripe.rpki.validator3.domain.RpkiRepository in project rpki-validator-3 by RIPE-NCC.
the class RpkiRepositoryValidationService method validateRsyncRepositories.
@Scheduled(initialDelay = 10_000, fixedDelay = 10_000)
public void validateRsyncRepositories() {
entityManager.setFlushMode(FlushModeType.COMMIT);
Instant cutoffTime = Instant.now().minus(rsyncRepositoryDownloadInterval);
log.info("updating all rsync repositories that have not been downloaded since {}", cutoffTime);
Set<TrustAnchor> affectedTrustAnchors = new HashSet<>();
final RsyncRepositoryValidationRun validationRun = new RsyncRepositoryValidationRun();
validationRunRepository.add(validationRun);
Stream<RpkiRepository> repositories = rpkiRepositories.findRsyncRepositories();
Map<String, RpkiObject> objectsBySha256 = new HashMap<>();
Map<URI, RpkiRepository> fetchedLocations = new HashMap<>();
ValidationResult results = repositories.filter((repository) -> {
boolean needsUpdate = repository.isPending() || repository.getLastDownloadedAt() == null || repository.getLastDownloadedAt().isBefore(cutoffTime);
if (!needsUpdate) {
fetchedLocations.put(URI.create(repository.getRsyncRepositoryUri()), repository);
}
return needsUpdate;
}).map((repository) -> processRsyncRepository(affectedTrustAnchors, validationRun, fetchedLocations, objectsBySha256, repository)).collect(() -> ValidationResult.withLocation("placeholder"), ValidationResult::addAll, ValidationResult::addAll);
validationRun.completeWith(results);
affectedTrustAnchors.forEach(validationRunRepository::runCertificateTreeValidation);
}
use of net.ripe.rpki.validator3.domain.RpkiRepository in project rpki-validator-3 by RIPE-NCC.
the class RpkiRepositoryValidationService method processRsyncRepository.
protected ValidationResult processRsyncRepository(Set<TrustAnchor> affectedTrustAnchors, RsyncRepositoryValidationRun validationRun, Map<URI, RpkiRepository> fetchedLocations, Map<String, RpkiObject> objectsBySha256, RpkiRepository repository) {
ValidationResult validationResult = ValidationResult.withLocation(URI.create(repository.getRsyncRepositoryUri()));
validationRun.addRpkiRepository(repository);
try {
File targetDirectory = RsyncUtils.localFileFromRsyncUri(rsyncLocalStorageDirectory, URI.create(repository.getRsyncRepositoryUri()));
RpkiRepository parentRepository = findDownloadedParentRepository(fetchedLocations, repository);
if (parentRepository == null) {
fetchRsyncRepository(repository, targetDirectory, validationResult);
if (validationResult.hasFailureForCurrentLocation()) {
return validationResult;
}
}
if (repository.getType() == RpkiRepository.Type.RSYNC && (parentRepository == null || parentRepository.getType() == RpkiRepository.Type.RSYNC_PREFETCH)) {
storeObjects(targetDirectory, validationRun, validationResult, objectsBySha256, repository);
}
} catch (IOException e) {
repository.setFailed();
validationResult.error(ErrorCodes.RSYNC_REPOSITORY_IO, e.toString(), ExceptionUtils.getStackTrace(e));
}
affectedTrustAnchors.addAll(repository.getTrustAnchors());
repository.setDownloaded();
fetchedLocations.put(URI.create(repository.getRsyncRepositoryUri()), repository);
return validationResult;
}
use of net.ripe.rpki.validator3.domain.RpkiRepository in project rpki-validator-3 by RIPE-NCC.
the class RrdpServiceTest method should_parse_notification_verify_snapshot_hash.
@Test
public void should_parse_notification_verify_snapshot_hash() {
final Objects.Publish cert = new Objects.Publish("rsync://host/path/cert.cer", Objects.aParseableCertificate());
final Objects.Publish crl = new Objects.Publish("rsync://host/path/crl1.crl", Objects.aParseableCrl());
rrdpClient.add(cert.uri, cert.content);
rrdpClient.add(crl.uri, crl.content);
final int serial = 1;
final String sessionId = UUID.randomUUID().toString();
final byte[] snapshotXml = Objects.snapshotXml(serial, sessionId, cert, crl);
final String snapshotUri = "https://host/path/snapshot.xml";
final Objects.SnapshotInfo snapshot = new Objects.SnapshotInfo(snapshotUri, Hex.parse("FFFFFF"));
rrdpClient.add(snapshot.uri, snapshotXml);
final byte[] notificationXml = Objects.notificationXml(serial, sessionId, snapshot);
final String notificationUri = "https://rrdp.ripe.net/notification.xml";
rrdpClient.add(notificationUri, notificationXml);
final TrustAnchor trustAnchor = TestObjects.newTrustAnchor();
entityManager.persist(trustAnchor);
final RpkiRepository rpkiRepository = new RpkiRepository(trustAnchor, notificationUri, RpkiRepository.Type.RRDP);
entityManager.persist(rpkiRepository);
final RrdpRepositoryValidationRun validationRun = new RrdpRepositoryValidationRun(rpkiRepository);
subject.storeRepository(rpkiRepository, validationRun);
final List<RpkiObject> objects = rpkiObjects.all().collect(Collectors.toList());
assertEquals(0, objects.size());
assertEquals(1, validationRun.getValidationChecks().size());
final ValidationCheck validationCheck = validationRun.getValidationChecks().get(0);
assertEquals(ErrorCodes.RRDP_FETCH, validationCheck.getKey());
assertEquals(ValidationCheck.Status.ERROR, validationCheck.getStatus());
assertEquals("Hash of the snapshot file " + snapshotUri + " is " + Hex.format(Sha256.hash(snapshotXml)) + ", but notification file says FFFFFF", validationCheck.getParameters().get(0));
assertEquals(rpkiRepository.getRrdpNotifyUri(), validationCheck.getLocation());
}
Aggregations