use of net.ripe.rpki.commons.crypto.x509cert.X509ResourceCertificate in project rpki-validator-3 by RIPE-NCC.
the class TrustAnchorsFactory method createCertificateAuthority.
public X509ResourceCertificate createCertificateAuthority(CertificateAuthority ca, CertificateAuthority issuer, ValidityPeriod mftValidityPeriod) {
ManifestCmsBuilder manifestBuilder = new ManifestCmsBuilder();
X509ResourceCertificate caCertificate = createCaCertificate(ca, ca.keyPair.getPublic(), issuer.dn, issuer.crlDistributionPoint, issuer.keyPair);
X509Crl crl = new X509CrlBuilder().withIssuerDN(caCertificate.getSubject()).withThisUpdateTime(DateTime.now()).withNextUpdateTime(DateTime.now().plusHours(8)).withAuthorityKeyIdentifier(ca.keyPair.getPublic()).withNumber(nextSerial()).build(ca.keyPair.getPrivate());
rpkiObjects.add(new RpkiObject(ca.crlDistributionPoint, crl));
manifestBuilder.addFile(ca.crlDistributionPoint.substring(ca.crlDistributionPoint.lastIndexOf('/') + 1), crl.getEncoded());
if (ca.children != null) {
for (CertificateAuthority child : ca.children) {
X509ResourceCertificate childCertificate = createCertificateAuthority(child, ca);
rpkiObjects.add(new RpkiObject(ca.repositoryURI + "/" + child.dn + ".cer", childCertificate));
manifestBuilder.addFile(child.dn + ".cer", childCertificate.getEncoded());
}
}
if (ca.roaPrefixes != null) {
ca.roaPrefixes.stream().collect(groupingBy(RoaPrefix::getAsn)).forEach((asn, roaPrefix) -> {
KeyPair roaKeyPair = KEY_PAIR_FACTORY.generate();
IpResourceSet resources = new IpResourceSet();
roaPrefix.stream().forEach(p -> resources.add(IpRange.parse(p.getPrefix())));
X509ResourceCertificate roaCertificate = new X509ResourceCertificateBuilder().withResources(resources).withIssuerDN(new X500Principal(ca.dn)).withSubjectDN(new X500Principal("CN=AS" + asn + ", CN=roa, " + ca.dn)).withValidityPeriod(typicalValidityPeriod()).withPublicKey(roaKeyPair.getPublic()).withSigningKeyPair(ca.keyPair).withCa(false).withKeyUsage(KeyUsage.digitalSignature).withSerial(nextSerial()).withCrlDistributionPoints(URI.create(ca.crlDistributionPoint)).build();
RoaCms roaCms = new RoaCmsBuilder().withAsn(new Asn(asn)).withPrefixes(roaPrefix.stream().map(p -> new net.ripe.rpki.commons.crypto.cms.roa.RoaPrefix(IpRange.parse(p.getPrefix()), p.getMaximumLength())).collect(toList())).withCertificate(roaCertificate).withSignatureProvider(BouncyCastleProvider.PROVIDER_NAME).build(roaKeyPair.getPrivate());
rpkiObjects.add(new RpkiObject(ca.repositoryURI + "/" + "AS" + asn + ".roa", roaCms));
manifestBuilder.addFile("AS" + asn + ".roa", roaCms.getEncoded());
});
}
KeyPair manifestKeyPair = KEY_PAIR_FACTORY.generate();
X509ResourceCertificate manifestCertificate = new X509ResourceCertificateBuilder().withInheritedResourceTypes(EnumSet.allOf(IpResourceType.class)).withIssuerDN(caCertificate.getSubject()).withSubjectDN(new X500Principal("CN=manifest, " + caCertificate.getSubject())).withValidityPeriod(mftValidityPeriod).withPublicKey(manifestKeyPair.getPublic()).withSigningKeyPair(ca.keyPair).withCa(false).withKeyUsage(KeyUsage.digitalSignature).withSerial(nextSerial()).withCrlDistributionPoints(URI.create(ca.crlDistributionPoint)).build();
manifestBuilder.withCertificate(manifestCertificate).withManifestNumber(nextSerial()).withThisUpdateTime(DateTime.now()).withNextUpdateTime(DateTime.now().plusHours(8));
ManifestCms manifest = manifestBuilder.build(manifestKeyPair.getPrivate());
rpkiObjects.add(new RpkiObject(ca.manifestURI, manifest));
return caCertificate;
}
use of net.ripe.rpki.commons.crypto.x509cert.X509ResourceCertificate in project rpki-validator-3 by RIPE-NCC.
the class CertificateTreeValidationService method validate.
@Transactional(Transactional.TxType.REQUIRED)
public void validate(long trustAnchorId) {
Map<URI, RpkiRepository> registeredRepositories = new HashMap<>();
entityManager.setFlushMode(FlushModeType.COMMIT);
TrustAnchor trustAnchor = trustAnchors.get(trustAnchorId);
log.info("starting tree validation for {}", trustAnchor);
CertificateTreeValidationRun validationRun = new CertificateTreeValidationRun(trustAnchor);
validationRuns.add(validationRun);
String trustAnchorLocation = trustAnchor.getLocations().get(0);
ValidationResult validationResult = ValidationResult.withLocation(trustAnchorLocation);
try {
X509ResourceCertificate certificate = trustAnchor.getCertificate();
validationResult.rejectIfNull(certificate, VALIDATOR_TRUST_ANCHOR_CERTIFICATE_AVAILABLE);
if (certificate == null) {
return;
}
CertificateRepositoryObjectValidationContext context = new CertificateRepositoryObjectValidationContext(URI.create(trustAnchorLocation), certificate);
certificate.validate(trustAnchorLocation, context, null, null, VALIDATION_OPTIONS, validationResult);
if (validationResult.hasFailureForCurrentLocation()) {
return;
}
URI locationUri = Objects.firstNonNull(certificate.getRrdpNotifyUri(), certificate.getRepositoryUri());
validationResult.warnIfNull(locationUri, VALIDATOR_TRUST_ANCHOR_CERTIFICATE_RRDP_NOTIFY_URI_OR_REPOSITORY_URI_PRESENT);
if (locationUri == null) {
return;
}
validationRun.getValidatedObjects().addAll(validateCertificateAuthority(trustAnchor, registeredRepositories, context, validationResult));
entityManager.setFlushMode(FlushModeType.AUTO);
if (isValidationRunCompleted(validationResult)) {
trustAnchor.markInitialCertificateTreeValidationRunCompleted();
if (!settings.isInitialValidationRunCompleted() && trustAnchors.allInitialCertificateTreeValidationRunsCompleted()) {
settings.markInitialValidationRunCompleted();
log.info("All trust anchors have completed their initial certificate tree validation run, validator is now ready");
}
}
validatedRpkiObjects.update(trustAnchor, validationRun.getValidatedObjects());
} finally {
validationRun.completeWith(validationResult);
log.info("tree validation {} for {}", validationRun.getStatus(), trustAnchor);
}
}
use of net.ripe.rpki.commons.crypto.x509cert.X509ResourceCertificate in project rpki-validator-3 by RIPE-NCC.
the class RpkiObjectCleanupService method cleanupRpkiObjects.
/**
* Marks all RPKI objects that are reachable from a trust anchor by following the entries in the manifests.
* Objects that are no longer reachable will be deleted after a configurable grace duration.
*/
@Scheduled(initialDelay = 60_000, fixedDelayString = "${rpki.validator.rpki.object.cleanup.interval.ms}")
public long cleanupRpkiObjects() {
Instant now = Instant.now();
for (TrustAnchor trustAnchor : trustAnchors.findAll()) {
transactionTemplate.execute((status) -> {
entityManager.setFlushMode(FlushModeType.COMMIT);
log.debug("tracing objects for trust anchor {}", trustAnchor);
X509ResourceCertificate resourceCertificate = trustAnchor.getCertificate();
if (resourceCertificate != null) {
traceCertificateAuthority(now, resourceCertificate);
}
return null;
});
}
return deleteUnreachableObjects(now);
}
use of net.ripe.rpki.commons.crypto.x509cert.X509ResourceCertificate 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.commons.crypto.x509cert.X509ResourceCertificate in project rpki-validator-3 by RIPE-NCC.
the class TrustAnchorValidationService method parseCertificate.
private X509ResourceCertificate parseCertificate(TrustAnchor trustAnchor, File certificateFile, ValidationResult validationResult) throws IOException {
CertificateRepositoryObject trustAnchorCertificate = CertificateRepositoryObjectFactory.createCertificateRepositoryObject(Files.toByteArray(certificateFile), validationResult);
validationResult.rejectIfFalse(trustAnchorCertificate instanceof X509ResourceCertificate, ErrorCodes.REPOSITORY_OBJECT_IS_TRUST_ANCHOR_CERTIFICATE, trustAnchor.getRsyncPrefetchUri());
if (validationResult.hasFailureForCurrentLocation()) {
return null;
}
X509ResourceCertificate certificate = (X509ResourceCertificate) trustAnchorCertificate;
String encodedSubjectPublicKeyInfo = X509CertificateUtil.getEncodedSubjectPublicKeyInfo(certificate.getCertificate());
validationResult.rejectIfFalse(encodedSubjectPublicKeyInfo.equals(trustAnchor.getSubjectPublicKeyInfo()), "trust.anchor.subject.key.matches.locator");
boolean signatureValid;
try {
certificate.getCertificate().verify(certificate.getPublicKey());
signatureValid = true;
} catch (GeneralSecurityException e) {
signatureValid = false;
}
validationResult.rejectIfFalse(signatureValid, ErrorCodes.TRUST_ANCHOR_SIGNATURE, trustAnchor.getRsyncPrefetchUri(), trustAnchor.getSubjectPublicKeyInfo());
return certificate;
}
Aggregations