Synchronize reads and writes in Spiffe SVID Manager
Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
parent
0a2fc88078
commit
fdff8485cf
|
|
@ -69,7 +69,7 @@ public final class X509SVIDFetcher implements Fetcher<List<X509SVID>> {
|
|||
StreamObserver<X509SVIDResponse> observer = new StreamObserver<X509SVIDResponse>() {
|
||||
@Override
|
||||
public void onNext(X509SVIDResponse value) {
|
||||
LOGGER.log(Level.INFO, "New SVID received ");
|
||||
LOGGER.log(Level.FINE, "New SVID received ");
|
||||
listener.accept(value.getSvidsList());
|
||||
retryHandler.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package spiffe.provider;
|
||||
|
||||
import java.util.concurrent.locks.StampedLock;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class FunctionalReadWriteLock {
|
||||
|
||||
private final StampedLock lock;
|
||||
|
||||
public FunctionalReadWriteLock() {
|
||||
this.lock = new StampedLock();
|
||||
}
|
||||
|
||||
public <T> T read(Supplier<T> supplier) {
|
||||
long stamp = lock.readLock();
|
||||
try {
|
||||
return supplier.get();
|
||||
} finally {
|
||||
lock.unlockRead(stamp);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Runnable runnable) {
|
||||
long stamp = lock.writeLock();
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
lock.unlockWrite(stamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import java.security.PrivateKey;
|
|||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static java.util.Collections.EMPTY_SET;
|
||||
|
||||
|
|
@ -26,8 +25,16 @@ class SpiffeIdManager {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Spiffe SVID handled by this manager
|
||||
*/
|
||||
private SpiffeSVID spiffeSVID;
|
||||
|
||||
/**
|
||||
* Used to synchronize spiffeSVID writes and reads
|
||||
*/
|
||||
private final FunctionalReadWriteLock guard;
|
||||
|
||||
/**
|
||||
* Private Constructor
|
||||
*
|
||||
|
|
@ -35,33 +42,30 @@ class SpiffeIdManager {
|
|||
*
|
||||
*/
|
||||
private SpiffeIdManager() {
|
||||
Consumer<List<X509SVID>> certificateUpdater = certs -> {
|
||||
X509SVID svid = certs.get(0);
|
||||
spiffeSVID = new SpiffeSVID(svid);
|
||||
};
|
||||
guard = new FunctionalReadWriteLock();
|
||||
Fetcher<List<X509SVID>> svidFetcher = new X509SVIDFetcher();
|
||||
svidFetcher.registerListener(certificateUpdater);
|
||||
svidFetcher.registerListener(this::updateSVID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used as callback that gets executed whenever an SVID update is pushed by the Workload API
|
||||
* Uses a write lock to synchronize access to spiffeSVID
|
||||
*/
|
||||
private void updateSVID(List<X509SVID> certs) {
|
||||
X509SVID svid = certs.get(0);
|
||||
guard.write(() -> spiffeSVID = new SpiffeSVID(svid));
|
||||
}
|
||||
|
||||
X509Certificate getCertificate() {
|
||||
if (spiffeSVID != null) {
|
||||
return spiffeSVID.getCertificate();
|
||||
}
|
||||
return null;
|
||||
return guard.read(() -> spiffeSVID != null ? spiffeSVID.getCertificate() : null);
|
||||
}
|
||||
|
||||
PrivateKey getPrivateKey() {
|
||||
if (spiffeSVID != null) {
|
||||
return spiffeSVID.getPrivateKey();
|
||||
}
|
||||
return null;
|
||||
return guard.read(() -> spiffeSVID != null ? spiffeSVID.getPrivateKey() : null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<X509Certificate> getTrustedCerts() {
|
||||
if (spiffeSVID != null) {
|
||||
return spiffeSVID.getBundle();
|
||||
}
|
||||
return EMPTY_SET;
|
||||
return guard.read(() -> spiffeSVID != null ? spiffeSVID.getBundle() : EMPTY_SET);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import static spiffe.provider.CertificateUtils.validate;
|
|||
*/
|
||||
public class SpiffeTrustManager extends X509ExtendedTrustManager {
|
||||
|
||||
|
||||
private final SpiffeIdManager spiffeIdManager;
|
||||
|
||||
SpiffeTrustManager() {
|
||||
|
|
@ -85,7 +84,7 @@ public class SpiffeTrustManager extends X509ExtendedTrustManager {
|
|||
*
|
||||
* @param chain an array of X509Certificate that contains the Peer's SVID to be validated
|
||||
* @throws CertificateException when either the Peer's certificate doesn't chain to any Trusted CA
|
||||
* or the SPIFFE ID is not authorized.
|
||||
*
|
||||
*/
|
||||
private void checkPeer(X509Certificate[] chain) throws CertificateException {
|
||||
validate(chain, spiffeIdManager.getTrustedCerts());
|
||||
|
|
|
|||
Loading…
Reference in New Issue