use of org.apache.hadoop.hdds.security.x509.certificate.CertInfo in project ozone by apache.
the class SCMCertStore method listCertificate.
@Override
public List<X509Certificate> listCertificate(NodeType role, BigInteger startSerialID, int count, CertType certType) throws IOException {
List<X509Certificate> results = new ArrayList<>();
String errorMessage = "Fail to list certificate from SCM metadata store";
Preconditions.checkNotNull(startSerialID);
if (startSerialID.longValue() == 0) {
startSerialID = null;
}
if (certType == VALID_CERTS) {
List<? extends Table.KeyValue<BigInteger, X509Certificate>> certs = getValidCertTableList(role, startSerialID, count);
for (Table.KeyValue<BigInteger, X509Certificate> kv : certs) {
try {
X509Certificate cert = kv.getValue();
results.add(cert);
} catch (IOException e) {
LOG.error(errorMessage, e);
throw new SCMSecurityException(errorMessage);
}
}
} else {
List<? extends Table.KeyValue<BigInteger, CertInfo>> certs = scmMetadataStore.getRevokedCertsV2Table().getRangeKVs(startSerialID, count);
for (Table.KeyValue<BigInteger, CertInfo> kv : certs) {
try {
CertInfo certInfo = kv.getValue();
X509Certificate cert = certInfo != null ? certInfo.getX509Certificate() : null;
results.add(cert);
} catch (IOException e) {
LOG.error(errorMessage, e);
throw new SCMSecurityException(errorMessage);
}
}
}
return results;
}
use of org.apache.hadoop.hdds.security.x509.certificate.CertInfo in project ozone by apache.
the class TestSCMCertStore method testRevokeCertificates.
@Test
public void testRevokeCertificates() throws Exception {
BigInteger serialID = x509Certificate.getSerialNumber();
scmCertStore.storeValidCertificate(serialID, x509Certificate, SCM);
Date now = new Date();
assertNotNull(scmCertStore.getCertificateByID(serialID, VALID_CERTS));
X509CertificateHolder caCertificateHolder = new X509CertificateHolder(generateX509Cert().getEncoded());
List<BigInteger> certs = new ArrayList<>();
certs.add(x509Certificate.getSerialNumber());
Optional<Long> sequenceId = scmCertStore.revokeCertificates(certs, caCertificateHolder, CRLReason.lookup(CRLReason.keyCompromise), now, crlApprover);
assertTrue(sequenceId.isPresent());
assertEquals(INITIAL_SEQUENCE_ID + 1L, (long) sequenceId.get());
assertNull(scmCertStore.getCertificateByID(serialID, VALID_CERTS));
CertInfo certInfo = scmCertStore.getRevokedCertificateInfoByID(serialID);
assertNotNull(certInfo);
assertNotNull(certInfo.getX509Certificate());
assertTrue("Timestamp should be greater than 0", certInfo.getTimestamp() > 0L);
long crlId = scmCertStore.getLatestCrlId();
assertEquals(sequenceId.get().longValue(), crlId);
List<CRLInfo> crls = scmCertStore.getCrls(Arrays.asList(crlId));
assertEquals(1, crls.size());
// CRL Info table should have a CRL with sequence id
assertNotNull(scmMetadataStore.getCRLInfoTable().get(sequenceId.get()));
// Check the sequence ID table for latest sequence id
assertEquals(INITIAL_SEQUENCE_ID + 1L, (long) scmMetadataStore.getCRLSequenceIdTable().get(CRL_SEQUENCE_ID_KEY));
CRLInfo crlInfo = crls.get(0);
assertEquals(crlInfo.getCrlSequenceID(), sequenceId.get().longValue());
Set<? extends X509CRLEntry> revokedCertificates = crlInfo.getX509CRL().getRevokedCertificates();
assertEquals(1L, revokedCertificates.size());
assertEquals(x509Certificate.getSerialNumber(), revokedCertificates.iterator().next().getSerialNumber());
// Now trying to revoke the already revoked certificate should result in
// a warning message and no-op. It should not create a new CRL.
sequenceId = scmCertStore.revokeCertificates(certs, caCertificateHolder, CRLReason.lookup(CRLReason.unspecified), now, crlApprover);
assertFalse(sequenceId.isPresent());
assertEquals(1L, getTableSize(scmMetadataStore.getCRLInfoTable().iterator()));
// Generate 3 more certificates and revoke 2 of them
List<BigInteger> newSerialIDs = new ArrayList<>();
for (int i = 0; i < 3; i++) {
X509Certificate cert = generateX509Cert();
scmCertStore.storeValidCertificate(cert.getSerialNumber(), cert, SCM);
newSerialIDs.add(cert.getSerialNumber());
}
// Add the first 2 certificates to the revocation list
sequenceId = scmCertStore.revokeCertificates(newSerialIDs.subList(0, 2), caCertificateHolder, CRLReason.lookup(CRLReason.aACompromise), now, crlApprover);
// This should create a CRL with sequence id INITIAL_SEQUENCE_ID + 2
// And contain 2 certificates in it
assertTrue(sequenceId.isPresent());
assertEquals(sequenceId.get().longValue(), scmCertStore.getLatestCrlId());
assertEquals(INITIAL_SEQUENCE_ID + 2L, (long) sequenceId.get());
// Check the sequence ID table for latest sequence id
assertEquals(INITIAL_SEQUENCE_ID + 2L, (long) scmMetadataStore.getCRLSequenceIdTable().get(CRL_SEQUENCE_ID_KEY));
CRLInfo newCrlInfo = scmCertStore.getCrls(Arrays.asList(INITIAL_SEQUENCE_ID + 2)).get(0);
revokedCertificates = newCrlInfo.getX509CRL().getRevokedCertificates();
assertEquals(2L, revokedCertificates.size());
assertNotNull(revokedCertificates.stream().filter(c -> c.getSerialNumber().equals(newSerialIDs.get(0))).findAny());
assertNotNull(revokedCertificates.stream().filter(c -> c.getSerialNumber().equals(newSerialIDs.get(1))).findAny());
assertEquals(newCrlInfo.getCrlSequenceID(), sequenceId.get().longValue());
// Valid certs table should have 1 cert
assertEquals(1L, getTableSize(scmMetadataStore.getValidCertsTable().iterator()));
// Make sure that the last certificate that was not revoked is the one
// in the valid certs table.
assertEquals(newSerialIDs.get(2), scmMetadataStore.getValidCertsTable().iterator().next().getKey());
// Revoked certs table should have 3 certs
assertEquals(3L, getTableSize(scmMetadataStore.getRevokedCertsV2Table().iterator()));
}
use of org.apache.hadoop.hdds.security.x509.certificate.CertInfo in project ozone by apache.
the class SCMCertStore method revokeCertificates.
@Override
public Optional<Long> revokeCertificates(List<BigInteger> serialIDs, X509CertificateHolder caCertificateHolder, CRLReason reason, Date revocationTime, CRLApprover crlApprover) throws IOException {
Date now = new Date();
X509v2CRLBuilder builder = new X509v2CRLBuilder(caCertificateHolder.getIssuer(), now);
List<X509Certificate> certsToRevoke = new ArrayList<>();
X509CRL crl;
Optional<Long> sequenceId = Optional.empty();
lock.lock();
try {
for (BigInteger serialID : serialIDs) {
X509Certificate cert = getCertificateByID(serialID, CertType.VALID_CERTS);
if (cert == null && LOG.isWarnEnabled()) {
LOG.warn("Trying to revoke a certificate that is not valid. " + "Serial ID: {}", serialID.toString());
} else if (getCertificateByID(serialID, CertType.REVOKED_CERTS) != null) {
LOG.warn("Trying to revoke a certificate that is already revoked.");
} else {
builder.addCRLEntry(serialID, revocationTime, reason.getValue().intValue());
certsToRevoke.add(cert);
}
}
if (!certsToRevoke.isEmpty()) {
try {
crl = crlApprover.sign(builder);
} catch (OperatorCreationException | CRLException e) {
throw new SCMSecurityException("Unable to create Certificate " + "Revocation List.", e);
}
// let us do this in a transaction.
try (BatchOperation batch = scmMetadataStore.getStore().initBatchOperation()) {
// only if the revocation time has passed.
if (now.after(revocationTime) || now.equals(revocationTime)) {
for (X509Certificate cert : certsToRevoke) {
CertInfo certInfo = new CertInfo.Builder().setX509Certificate(cert).setTimestamp(now.getTime()).build();
scmMetadataStore.getRevokedCertsV2Table().putWithBatch(batch, cert.getSerialNumber(), certInfo);
scmMetadataStore.getValidCertsTable().deleteWithBatch(batch, cert.getSerialNumber());
}
}
long id = crlSequenceId.incrementAndGet();
CRLInfo crlInfo = new CRLInfo.Builder().setX509CRL(crl).setCreationTimestamp(now.getTime()).setCrlSequenceID(id).build();
scmMetadataStore.getCRLInfoTable().putWithBatch(batch, id, crlInfo);
// Update the CRL Sequence Id Table with the last sequence id.
scmMetadataStore.getCRLSequenceIdTable().putWithBatch(batch, CRL_SEQUENCE_ID_KEY, id);
scmMetadataStore.getStore().commitBatchOperation(batch);
sequenceId = Optional.of(id);
}
}
} finally {
lock.unlock();
}
return sequenceId;
}
Aggregations