Minor fixes
Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
parent
44cda6e809
commit
ecabc0f288
|
|
@ -137,7 +137,7 @@ public class CertificateUtils {
|
||||||
|
|
||||||
// Create an instance of PKIXParameters used as input for the PKIX CertPathValidator
|
// Create an instance of PKIXParameters used as input for the PKIX CertPathValidator
|
||||||
private static PKIXParameters toPkixParameters(List<X509Certificate> trustedCerts) throws CertificateException, InvalidAlgorithmParameterException {
|
private static PKIXParameters toPkixParameters(List<X509Certificate> trustedCerts) throws CertificateException, InvalidAlgorithmParameterException {
|
||||||
if (trustedCerts == null || trustedCerts.size() == 0) {
|
if (trustedCerts == null || trustedCerts.isEmpty()) {
|
||||||
throw new CertificateException("No trusted Certs");
|
throw new CertificateException("No trusted Certs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,4 +166,6 @@ public class CertificateUtils {
|
||||||
val decoder = Base64.getDecoder();
|
val decoder = Base64.getDecoder();
|
||||||
return decoder.decode(privateKey);
|
return decoder.decode(privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CertificateUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class SpiffeId {
|
||||||
val path = Arrays.stream(segments)
|
val path = Arrays.stream(segments)
|
||||||
.filter(StringUtils::isNotBlank)
|
.filter(StringUtils::isNotBlank)
|
||||||
.map(SpiffeId::normalize)
|
.map(SpiffeId::normalize)
|
||||||
.map(s -> "/" + s)
|
.map(s -> '/' + s)
|
||||||
.collect(Collectors.joining());
|
.collect(Collectors.joining());
|
||||||
return new SpiffeId(trustDomain, path);
|
return new SpiffeId(trustDomain, path);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,11 @@ public class SpiffeIdUtils {
|
||||||
* @throws IllegalArgumentException if any of the SPIFFE IDs in the file cannot be parsed
|
* @throws IllegalArgumentException if any of the SPIFFE IDs in the file cannot be parsed
|
||||||
*/
|
*/
|
||||||
public static List<SpiffeId> getSpiffeIdListFromFile(final Path spiffeIdsFile) throws IOException {
|
public static List<SpiffeId> getSpiffeIdListFromFile(final Path spiffeIdsFile) throws IOException {
|
||||||
Stream<String> lines = Files.lines(spiffeIdsFile);
|
try (Stream<String> lines = Files.lines(spiffeIdsFile)) {
|
||||||
return lines
|
return lines
|
||||||
.map(SpiffeId::parse)
|
.map(SpiffeId::parse)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -95,4 +96,6 @@ public class SpiffeIdUtils {
|
||||||
.map(SpiffeId::parse)
|
.map(SpiffeId::parse)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SpiffeIdUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ import static java.lang.String.format;
|
||||||
@Value
|
@Value
|
||||||
public class TrustDomain {
|
public class TrustDomain {
|
||||||
|
|
||||||
String trustDomain;
|
String name;
|
||||||
|
|
||||||
private TrustDomain(String trustDomain) {
|
private TrustDomain(String trustDomain) {
|
||||||
this.trustDomain = trustDomain;
|
this.name = trustDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,7 +51,7 @@ public class TrustDomain {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return trustDomain;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String normalize(String s) {
|
private static String normalize(String s) {
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,5 @@ public interface JwtSvidSource {
|
||||||
*
|
*
|
||||||
* @throws //TODO: declare thrown exceptions
|
* @throws //TODO: declare thrown exceptions
|
||||||
*/
|
*/
|
||||||
JwtSvid FetchJwtSvid(SpiffeId subject, String audience, String... extraAudiences);
|
JwtSvid fetchJwtSvid(SpiffeId subject, String audience, String... extraAudiences);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,4 +62,6 @@ public class X509SvidValidator {
|
||||||
throw new CertificateException(String.format("SPIFFE ID %s in x509Certificate is not accepted", spiffeId));
|
throw new CertificateException(String.format("SPIFFE ID %s in x509Certificate is not accepted", spiffeId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private X509SvidValidator() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,76 +62,14 @@ public class Address {
|
||||||
|
|
||||||
String error = null;
|
String error = null;
|
||||||
switch (scheme) {
|
switch (scheme) {
|
||||||
case "unix": {
|
case "unix":
|
||||||
if (parsedAddress.isOpaque() && parsedAddress.isAbsolute()) {
|
error = validateUnixAddress(parsedAddress);
|
||||||
error = "Workload endpoint unix socket URI must not be opaque: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getUserInfo())) {
|
|
||||||
error = "Workload endpoint unix socket URI must not include user info: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(parsedAddress.getHost()) && StringUtils.isBlank(parsedAddress.getPath())) {
|
|
||||||
error = "Workload endpoint unix socket URI must include a path: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
|
||||||
error = "Workload endpoint unix socket URI must not include query values: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
|
||||||
error = "Workload endpoint unix socket URI must not include a fragment: %s";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
case "tcp":
|
||||||
|
error = validateTcpAddress(parsedAddress);
|
||||||
case "tcp": {
|
|
||||||
if (parsedAddress.isOpaque() && parsedAddress.isAbsolute()) {
|
|
||||||
error = "Workload endpoint tcp socket URI must not be opaque: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getUserInfo())) {
|
|
||||||
error = "Workload endpoint tcp socket URI must not include user info: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(parsedAddress.getHost())) {
|
|
||||||
error = "Workload endpoint tcp socket URI must include a host: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getPath())) {
|
|
||||||
error = "Workload endpoint tcp socket URI must not include a path: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
|
||||||
error = "Workload endpoint tcp socket URI must not include query values: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
|
||||||
error = "Workload endpoint tcp socket URI must not include a fragment: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
String ip = parseIp(parsedAddress.getHost());
|
|
||||||
if (StringUtils.isBlank(ip)) {
|
|
||||||
error = "Workload endpoint tcp socket URI host component must be an IP:port: %s";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int port = parsedAddress.getPort();
|
|
||||||
if (port == -1) {
|
|
||||||
error = "Workload endpoint tcp socket URI host component must include a port: %s";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
error = "Workload endpoint socket URI must have a tcp:// or unix:// scheme: %s";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(error)) {
|
if (StringUtils.isNotBlank(error)) {
|
||||||
|
|
@ -141,6 +79,66 @@ public class Address {
|
||||||
return parsedAddress;
|
return parsedAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String validateUnixAddress(URI parsedAddress) {
|
||||||
|
if (parsedAddress.isOpaque() && parsedAddress.isAbsolute()) {
|
||||||
|
return "Workload endpoint unix socket URI must not be opaque: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getUserInfo())) {
|
||||||
|
return "Workload endpoint unix socket URI must not include user info: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(parsedAddress.getHost()) && StringUtils.isBlank(parsedAddress.getPath())) {
|
||||||
|
return "Workload endpoint unix socket URI must include a path: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
||||||
|
return "Workload endpoint unix socket URI must not include query values: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
||||||
|
return "Workload endpoint unix socket URI must not include a fragment: %s";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String validateTcpAddress(URI parsedAddress) {
|
||||||
|
if (parsedAddress.isOpaque() && parsedAddress.isAbsolute()) {
|
||||||
|
return "Workload endpoint tcp socket URI must not be opaque: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getUserInfo())) {
|
||||||
|
return "Workload endpoint tcp socket URI must not include user info: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(parsedAddress.getHost())) {
|
||||||
|
return "Workload endpoint tcp socket URI must include a host: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getPath())) {
|
||||||
|
return "Workload endpoint tcp socket URI must not include a path: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
||||||
|
return "Workload endpoint tcp socket URI must not include query values: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
||||||
|
return "Workload endpoint tcp socket URI must not include a fragment: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
String ip = parseIp(parsedAddress.getHost());
|
||||||
|
if (StringUtils.isBlank(ip)) {
|
||||||
|
return "Workload endpoint tcp socket URI host component must be an IP:port: %s";
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = parsedAddress.getPort();
|
||||||
|
if (port == -1) {
|
||||||
|
return "Workload endpoint tcp socket URI host component must include a port: %s";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isValid(String scheme) {
|
private static boolean isValid(String scheme) {
|
||||||
return (StringUtils.isNotBlank(scheme) && VALID_SCHEMES.contains(scheme));
|
return (StringUtils.isNotBlank(scheme) && VALID_SCHEMES.contains(scheme));
|
||||||
}
|
}
|
||||||
|
|
@ -153,4 +151,6 @@ public class Address {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Address() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class JwtSource implements JwtSvidSource, JwtBundleSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JwtSvid FetchJwtSvid(SpiffeId subject, String audience, String... extraAudiences) {
|
public JwtSvid fetchJwtSvid(SpiffeId subject, String audience, String... extraAudiences) {
|
||||||
throw new NotImplementedException("Not implemented");
|
throw new NotImplementedException("Not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ package spiffe.workloadapi;
|
||||||
* @param <T> is the type of the updates.
|
* @param <T> is the type of the updates.
|
||||||
*/
|
*/
|
||||||
public interface Watcher<T> {
|
public interface Watcher<T> {
|
||||||
|
void onUpdate(final T update);
|
||||||
void OnUpdate(final T update);
|
void onError(final Throwable e);
|
||||||
|
|
||||||
void OnError(final Throwable e);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,19 +125,19 @@ public class WorkloadApiClient implements Closeable {
|
||||||
try {
|
try {
|
||||||
x509Context = GrpcConversionUtils.toX509Context(value);
|
x509Context = GrpcConversionUtils.toX509Context(value);
|
||||||
} catch (CertificateException | X509SvidException e) {
|
} catch (CertificateException | X509SvidException e) {
|
||||||
watcher.OnError(new X509ContextException("Error processing X509 Context update", e));
|
watcher.onError(new X509ContextException("Error processing X509 Context update", e));
|
||||||
}
|
}
|
||||||
watcher.OnUpdate(x509Context);
|
watcher.onUpdate(x509Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(Throwable t) {
|
public void onError(Throwable t) {
|
||||||
watcher.OnError(new X509ContextException("Error getting X509Context", t));
|
watcher.onError(new X509ContextException("Error getting X509Context", t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCompleted() {
|
public void onCompleted() {
|
||||||
watcher.OnError(new X509ContextException("Unexpected completed stream"));
|
watcher.onError(new X509ContextException("Unexpected completed stream"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Context.CancellableContext cancellableContext;
|
Context.CancellableContext cancellableContext;
|
||||||
|
|
|
||||||
|
|
@ -158,27 +158,27 @@ public class X509Source implements X509SvidSource, X509BundleSource, Closeable {
|
||||||
private void setX509ContextWatcher() {
|
private void setX509ContextWatcher() {
|
||||||
workloadApiClient.watchX509Context(new Watcher<X509Context>() {
|
workloadApiClient.watchX509Context(new Watcher<X509Context>() {
|
||||||
@Override
|
@Override
|
||||||
public void OnUpdate(X509Context update) {
|
public void onUpdate(X509Context update) {
|
||||||
log.log(Level.INFO, "Received X509Context update");
|
log.log(Level.INFO, "Received X509Context update");
|
||||||
setX509Context(update);
|
setX509Context(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void OnError(Throwable error) {
|
public void onError(Throwable error) {
|
||||||
log.log(Level.SEVERE, String.format("Error in X509Context watcher: %s %n %s", error.getMessage(), ExceptionUtils.getStackTrace(error)));
|
log.log(Level.SEVERE, String.format("Error in X509Context watcher: %s %n %s", error.getMessage(), ExceptionUtils.getStackTrace(error)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setX509Context(@NonNull final X509Context update) {
|
private void setX509Context(@NonNull final X509Context update) {
|
||||||
X509Svid svid;
|
X509Svid svidUpdate;
|
||||||
if (picker == null) {
|
if (picker == null) {
|
||||||
svid = update.getDefaultSvid();
|
svidUpdate = update.getDefaultSvid();
|
||||||
} else {
|
} else {
|
||||||
svid = picker.apply(update.getX509Svid());
|
svidUpdate = picker.apply(update.getX509Svid());
|
||||||
}
|
}
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
this.svid = svid;
|
this.svid = svidUpdate;
|
||||||
this.bundles = update.getX509BundleSet();
|
this.bundles = update.getX509BundleSet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,6 @@ public class GrpcConversionUtils {
|
||||||
}
|
}
|
||||||
return x509SvidList;
|
return x509SvidList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GrpcConversionUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,4 +65,6 @@ public class GrpcManagedChannelFactory {
|
||||||
|
|
||||||
channelBuilder.eventLoopGroup(new NioEventLoopGroup());
|
channelBuilder.eventLoopGroup(new NioEventLoopGroup());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GrpcManagedChannelFactory() {}
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ class KeyStore {
|
||||||
private final KeyStoreType keyStoreType;
|
private final KeyStoreType keyStoreType;
|
||||||
private final char[] keyStorePassword;
|
private final char[] keyStorePassword;
|
||||||
|
|
||||||
private java.security.KeyStore keyStore;
|
private java.security.KeyStore javaKeyStore;
|
||||||
private File keyStoreFile;
|
private File keyStoreFile;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
|
|
@ -41,7 +41,7 @@ class KeyStore {
|
||||||
|
|
||||||
private void setupKeyStore() throws KeyStoreException {
|
private void setupKeyStore() throws KeyStoreException {
|
||||||
this.keyStoreFile = new File(keyStoreFilePath.toUri());
|
this.keyStoreFile = new File(keyStoreFilePath.toUri());
|
||||||
this.keyStore = loadKeyStore(keyStoreFile);
|
this.javaKeyStore = loadKeyStore(keyStoreFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ class KeyStore {
|
||||||
*/
|
*/
|
||||||
void storePrivateKey(final PrivateKeyEntry privateKeyEntry) throws KeyStoreException {
|
void storePrivateKey(final PrivateKeyEntry privateKeyEntry) throws KeyStoreException {
|
||||||
// Store PrivateKey Entry in KeyStore
|
// Store PrivateKey Entry in KeyStore
|
||||||
keyStore.setKeyEntry(
|
javaKeyStore.setKeyEntry(
|
||||||
privateKeyEntry.getAlias(),
|
privateKeyEntry.getAlias(),
|
||||||
privateKeyEntry.getPrivateKey(),
|
privateKeyEntry.getPrivateKey(),
|
||||||
privateKeyEntry.getPassword(),
|
privateKeyEntry.getPassword(),
|
||||||
|
|
@ -85,7 +85,7 @@ class KeyStore {
|
||||||
*/
|
*/
|
||||||
void storeBundleEntry(BundleEntry bundleEntry) throws KeyStoreException {
|
void storeBundleEntry(BundleEntry bundleEntry) throws KeyStoreException {
|
||||||
// Store Bundle Entry in KeyStore
|
// Store Bundle Entry in KeyStore
|
||||||
this.keyStore.setCertificateEntry(
|
this.javaKeyStore.setCertificateEntry(
|
||||||
bundleEntry.getAlias(),
|
bundleEntry.getAlias(),
|
||||||
bundleEntry.getCertificate()
|
bundleEntry.getCertificate()
|
||||||
);
|
);
|
||||||
|
|
@ -95,7 +95,7 @@ class KeyStore {
|
||||||
// Flush KeyStore to disk, to the configured (@see keyStoreFilePath)
|
// Flush KeyStore to disk, to the configured (@see keyStoreFilePath)
|
||||||
private void flush() throws KeyStoreException {
|
private void flush() throws KeyStoreException {
|
||||||
try {
|
try {
|
||||||
keyStore.store(new FileOutputStream(keyStoreFile), keyStorePassword);
|
javaKeyStore.store(new FileOutputStream(keyStoreFile), keyStorePassword);
|
||||||
} catch (IOException | NoSuchAlgorithmException | CertificateException e) {
|
} catch (IOException | NoSuchAlgorithmException | CertificateException e) {
|
||||||
throw new KeyStoreException(e);
|
throw new KeyStoreException(e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,18 +96,18 @@ public class KeyStoreHelper {
|
||||||
private void setX509ContextWatcher(WorkloadApiClient workloadApiClient, CountDownLatch countDownLatch) {
|
private void setX509ContextWatcher(WorkloadApiClient workloadApiClient, CountDownLatch countDownLatch) {
|
||||||
workloadApiClient.watchX509Context(new Watcher<X509Context>() {
|
workloadApiClient.watchX509Context(new Watcher<X509Context>() {
|
||||||
@Override
|
@Override
|
||||||
public void OnUpdate(X509Context update) {
|
public void onUpdate(X509Context update) {
|
||||||
log.log(Level.INFO, "Received X509Context update");
|
log.log(Level.INFO, "Received X509Context update");
|
||||||
try {
|
try {
|
||||||
storeX509ContextUpdate(update);
|
storeX509ContextUpdate(update);
|
||||||
} catch (KeyStoreException e) {
|
} catch (KeyStoreException e) {
|
||||||
this.OnError(e);
|
this.onError(e);
|
||||||
}
|
}
|
||||||
countDownLatch.countDown();
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void OnError(Throwable t) {
|
public void onError(Throwable t) {
|
||||||
throw new RuntimeException(t);
|
throw new RuntimeException(t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ public final class SpiffeKeyManager extends X509ExtendedKeyManager {
|
||||||
@Override
|
@Override
|
||||||
public X509Certificate[] getCertificateChain(String alias) {
|
public X509Certificate[] getCertificateChain(String alias) {
|
||||||
if (!Objects.equals(alias, DEFAULT_ALIAS)) {
|
if (!Objects.equals(alias, DEFAULT_ALIAS)) {
|
||||||
return null;
|
return new X509Certificate[0];
|
||||||
}
|
}
|
||||||
X509Svid x509Svid = x509SvidSource.getX509Svid();
|
X509Svid x509Svid = x509SvidSource.getX509Svid();
|
||||||
return x509Svid.getChainArray();
|
return x509Svid.getChainArray();
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public final class SpiffeKeyStore extends KeyStoreSpi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate[] engineGetCertificateChain(String alias) {
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
return null;
|
return new Certificate[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,6 @@ class SpiffeProviderConstants {
|
||||||
|
|
||||||
// alias used by the SpiffeKeyStore
|
// alias used by the SpiffeKeyStore
|
||||||
static final String DEFAULT_ALIAS = "Spiffe";
|
static final String DEFAULT_ALIAS = "Spiffe";
|
||||||
|
|
||||||
|
private SpiffeProviderConstants() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,4 +74,6 @@ public final class SpiffeSslContextFactory {
|
||||||
this.sslProtocol = sslProtocol;
|
this.sslProtocol = sslProtocol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SpiffeSslContextFactory() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,15 @@ public final class SpiffeTrustManager extends X509ExtendedTrustManager {
|
||||||
private final Supplier<List<SpiffeId>> acceptedSpiffeIdsSupplier;
|
private final Supplier<List<SpiffeId>> acceptedSpiffeIdsSupplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a SpiffeTrustManager with a X509BundleSource used to provide the trusted
|
* Creates a SpiffeTrustManager with a X509 bundle source used to provide the trusted
|
||||||
* bundles, and a Supplier of a List of accepted SpiffeIds to be used during peer SVID validation.
|
* bundles, and a Supplier of a List of accepted SpiffeIds to be used during peer SVID validation.
|
||||||
*
|
*
|
||||||
* @param X509BundleSource an implementation of a {@link X509BundleSource}
|
* @param x509BundleSource an implementation of a {@link X509BundleSource}
|
||||||
* @param acceptedSpiffeIdsSupplier a Supplier of a list of accepted SPIFFE IDs.
|
* @param acceptedSpiffeIdsSupplier a Supplier of a list of accepted SPIFFE IDs.
|
||||||
*/
|
*/
|
||||||
public SpiffeTrustManager(X509BundleSource X509BundleSource,
|
public SpiffeTrustManager(X509BundleSource x509BundleSource,
|
||||||
Supplier<List<SpiffeId>> acceptedSpiffeIdsSupplier) {
|
Supplier<List<SpiffeId>> acceptedSpiffeIdsSupplier) {
|
||||||
this.x509BundleSource = X509BundleSource;
|
this.x509BundleSource = x509BundleSource;
|
||||||
this.acceptedSpiffeIdsSupplier = acceptedSpiffeIdsSupplier;
|
this.acceptedSpiffeIdsSupplier = acceptedSpiffeIdsSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,9 +75,8 @@ public class HttpsClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<SpiffeId> listOfSpiffeIds() {
|
static List<SpiffeId> listOfSpiffeIds() {
|
||||||
try {
|
Path path = Paths.get("java-spiffe-provider/src/main/java/spiffe/provider/examples/spiffeIds.txt");
|
||||||
Path path = Paths.get("java-spiffe-provider/src/main/java/spiffe/provider/examples/spiffeIds.txt");
|
try (Stream<String> lines = Files.lines(path)) {
|
||||||
Stream<String> lines = Files.lines(path);
|
|
||||||
return lines
|
return lines
|
||||||
.map(SpiffeId::parse)
|
.map(SpiffeId::parse)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,14 @@ public class HttpsServer {
|
||||||
SSLContext sslContext = SpiffeSslContextFactory.getSslContext(sslContextOptions);
|
SSLContext sslContext = SpiffeSslContextFactory.getSslContext(sslContextOptions);
|
||||||
|
|
||||||
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
|
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
|
||||||
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
|
|
||||||
|
|
||||||
// Server will validate Client chain and SPIFFE ID
|
try (SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port)) {
|
||||||
sslServerSocket.setNeedClientAuth(true);
|
// Server will validate Client chain and SPIFFE ID
|
||||||
|
sslServerSocket.setNeedClientAuth(true);
|
||||||
|
|
||||||
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
|
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
|
||||||
new WorkloadThread(sslSocket, x509Source).start();
|
new WorkloadThread(sslSocket, x509Source).start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package spiffe.provider.examples;
|
package spiffe.provider.examples;
|
||||||
|
|
||||||
|
import lombok.extern.java.Log;
|
||||||
import spiffe.internal.CertificateUtils;
|
import spiffe.internal.CertificateUtils;
|
||||||
import spiffe.spiffeid.SpiffeId;
|
import spiffe.spiffeid.SpiffeId;
|
||||||
import spiffe.workloadapi.X509Source;
|
import spiffe.workloadapi.X509Source;
|
||||||
|
|
@ -8,7 +9,9 @@ import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Log
|
||||||
class WorkloadThread extends Thread {
|
class WorkloadThread extends Thread {
|
||||||
|
|
||||||
private final X509Source x509Source;
|
private final X509Source x509Source;
|
||||||
|
|
@ -19,15 +22,16 @@ class WorkloadThread extends Thread {
|
||||||
this.x509Source = x509Source;
|
this.x509Source = x509Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
sslSocket.startHandshake();
|
sslSocket.startHandshake();
|
||||||
SSLSession sslSession = sslSocket.getSession();
|
SSLSession sslSession = sslSocket.getSession();
|
||||||
|
|
||||||
System.out.println("SSLSession :");
|
log.info("SSLSession :\n");
|
||||||
System.out.println("\tProtocol : " + sslSession.getProtocol());
|
log.info("\tProtocol : \n" + sslSession.getProtocol());
|
||||||
System.out.println("\tCipher suite : " + sslSession.getCipherSuite());
|
log.info("\tCipher suite \n: " + sslSession.getCipherSuite());
|
||||||
System.out.println();
|
|
||||||
|
|
||||||
// Start handling application content
|
// Start handling application content
|
||||||
InputStream inputStream = sslSocket.getInputStream();
|
InputStream inputStream = sslSocket.getInputStream();
|
||||||
|
|
@ -50,14 +54,14 @@ class WorkloadThread extends Thread {
|
||||||
// Read message from peer
|
// Read message from peer
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
System.out.println("Message received: " + line);
|
log.info("Message received: " + line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
x509Source.close();
|
x509Source.close();
|
||||||
sslSocket.close();
|
sslSocket.close();
|
||||||
} catch (Exception ex) {
|
} catch (Exception e) {
|
||||||
ex.printStackTrace();
|
log.log(Level.SEVERE, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue