Fixing checkstyle issues.
Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
parent
3e81bee7ff
commit
7268c54a28
|
|
@ -55,7 +55,7 @@ public enum Algorithm {
|
|||
PS512("PS512"),
|
||||
|
||||
/**
|
||||
* Non-Supported algorithm
|
||||
* Non-Supported algorithm.
|
||||
*/
|
||||
OTHER("OTHER");
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ public enum Algorithm {
|
|||
}
|
||||
|
||||
public static Family parse(final String s) {
|
||||
Family family;
|
||||
final Family family;
|
||||
if (s.equals(RSA.getName())) {
|
||||
family = RSA;
|
||||
} else if (s.equals(EC.getName())) {
|
||||
|
|
@ -108,7 +108,7 @@ public enum Algorithm {
|
|||
}
|
||||
|
||||
public static Algorithm parse(final String s) {
|
||||
Algorithm algorithm;
|
||||
final Algorithm algorithm;
|
||||
if (s.equals(RS256.getName())) {
|
||||
algorithm = RS256;
|
||||
} else if (s.equals(RS384.getName())) {
|
||||
|
|
|
|||
|
|
@ -67,12 +67,14 @@ public class JwtBundle implements BundleSource<JwtBundle> {
|
|||
* @throws JwtBundleException if there is an error reading or parsing the file, or if a keyId is empty
|
||||
* @throws KeyException if the bundle file contains a key type that is not supported
|
||||
*/
|
||||
public static JwtBundle load(@NonNull final TrustDomain trustDomain, @NonNull final Path bundlePath) throws KeyException, JwtBundleException {
|
||||
public static JwtBundle load(@NonNull final TrustDomain trustDomain, @NonNull final Path bundlePath)
|
||||
throws KeyException, JwtBundleException {
|
||||
try {
|
||||
val jwkSet = JWKSet.load(bundlePath.toFile());
|
||||
return toJwtBundle(trustDomain, jwkSet);
|
||||
} catch (IOException | ParseException | JOSEException e) {
|
||||
throw new JwtBundleException(String.format("Could not load bundle from file: %s", bundlePath.toString()), e);
|
||||
val error = "Could not load bundle from file: %s";
|
||||
throw new JwtBundleException(String.format(error, bundlePath.toString()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +129,7 @@ public class JwtBundle implements BundleSource<JwtBundle> {
|
|||
* @throws AuthorityNotFoundException if no Authority is found associated to the Key ID
|
||||
*/
|
||||
public PublicKey findJwtAuthority(final String keyId) throws AuthorityNotFoundException {
|
||||
PublicKey key = jwtAuthorities.get(keyId);
|
||||
val key = jwtAuthorities.get(keyId);
|
||||
if (key != null) {
|
||||
return key;
|
||||
}
|
||||
|
|
@ -168,7 +170,7 @@ public class JwtBundle implements BundleSource<JwtBundle> {
|
|||
}
|
||||
|
||||
private static JwtBundle toJwtBundle(final TrustDomain trustDomain, final JWKSet jwkSet) throws JwtBundleException, JOSEException, ParseException, KeyException {
|
||||
Map<String, PublicKey> authorities = new ConcurrentHashMap<>();
|
||||
final Map<String, PublicKey> authorities = new ConcurrentHashMap<>();
|
||||
for (JWK jwk : jwkSet.getKeys()) {
|
||||
String keyId = getKeyId(jwk);
|
||||
PublicKey publicKey = getPublicKey(jwk);
|
||||
|
|
@ -188,7 +190,7 @@ public class JwtBundle implements BundleSource<JwtBundle> {
|
|||
private static PublicKey getPublicKey(final JWK jwk) throws JOSEException, ParseException, KeyException {
|
||||
val family = Algorithm.Family.parse(jwk.getKeyType().getValue());
|
||||
|
||||
PublicKey publicKey;
|
||||
final PublicKey publicKey;
|
||||
switch (family) {
|
||||
case EC:
|
||||
publicKey = ECKey.parse(jwk.toJSONString()).toPublicKey();
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class JwtBundleSet implements BundleSource<JwtBundle> {
|
|||
* @return a {@link JwtBundleSet}
|
||||
*/
|
||||
public static JwtBundleSet of(@NonNull final Collection<JwtBundle> bundles) {
|
||||
Map<TrustDomain, JwtBundle> bundleMap = new ConcurrentHashMap<>();
|
||||
final Map<TrustDomain, JwtBundle> bundleMap = new ConcurrentHashMap<>();
|
||||
for (JwtBundle bundle : bundles) {
|
||||
bundleMap.put(bundle.getTrustDomain(), bundle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,13 +61,16 @@ public class X509Bundle implements BundleSource<X509Bundle> {
|
|||
* @throws IOException in case of failure accessing the given bundle path
|
||||
* @throws CertificateException if the bundle cannot be parsed
|
||||
*/
|
||||
public static X509Bundle load(@NonNull final TrustDomain trustDomain, @NonNull final Path bundlePath) throws IOException, CertificateException {
|
||||
byte[] bundleBytes;
|
||||
public static X509Bundle load(@NonNull final TrustDomain trustDomain, @NonNull final Path bundlePath)
|
||||
throws IOException, CertificateException {
|
||||
|
||||
final byte[] bundleBytes;
|
||||
try {
|
||||
bundleBytes = Files.readAllBytes(bundlePath);
|
||||
} catch (NoSuchFileException e) {
|
||||
throw new IOException("Unable to load X.509 bundle file", e);
|
||||
}
|
||||
|
||||
val x509Certificates = CertificateUtils.generateCertificates(bundleBytes);
|
||||
val x509CertificateSet = new HashSet<>(x509Certificates);
|
||||
return new X509Bundle(trustDomain, x509CertificateSet);
|
||||
|
|
@ -84,7 +87,8 @@ public class X509Bundle implements BundleSource<X509Bundle> {
|
|||
*
|
||||
* @throws CertificateException if the bundle cannot be parsed
|
||||
*/
|
||||
public static X509Bundle parse(@NonNull final TrustDomain trustDomain, @NonNull final byte[] bundleBytes) throws CertificateException {
|
||||
public static X509Bundle parse(@NonNull final TrustDomain trustDomain, @NonNull final byte[] bundleBytes)
|
||||
throws CertificateException {
|
||||
val x509Certificates = CertificateUtils.generateCertificates(bundleBytes);
|
||||
val x509CertificateSet = new HashSet<>(x509Certificates);
|
||||
return new X509Bundle(trustDomain, x509CertificateSet);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class X509BundleSet implements BundleSource<X509Bundle> {
|
|||
* @return a {@link X509BundleSet} initialized with the list of bundles
|
||||
*/
|
||||
public static X509BundleSet of(@NonNull final Collection<X509Bundle> bundles) {
|
||||
Map<TrustDomain, X509Bundle> bundleMap = new ConcurrentHashMap<>();
|
||||
final Map<TrustDomain, X509Bundle> bundleMap = new ConcurrentHashMap<>();
|
||||
for (X509Bundle bundle : bundles) {
|
||||
bundleMap.put(bundle.getTrustDomain(), bundle);
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ public class X509BundleSet implements BundleSource<X509Bundle> {
|
|||
@Override
|
||||
public X509Bundle getBundleForTrustDomain(@NonNull final TrustDomain trustDomain) throws BundleNotFoundException {
|
||||
val bundle = bundles.get(trustDomain);
|
||||
if (bundle == null){
|
||||
if (bundle == null) {
|
||||
throw new BundleNotFoundException(String.format("No X.509 bundle for trust domain %s", trustDomain));
|
||||
}
|
||||
return bundle;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import java.util.stream.Collectors;
|
|||
* @see <a href="https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md">https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md</a>
|
||||
*/
|
||||
@Value
|
||||
public class SpiffeId {
|
||||
public final class SpiffeId {
|
||||
|
||||
public static final String SPIFFE_SCHEME = "spiffe";
|
||||
|
||||
|
|
@ -70,7 +70,8 @@ public class SpiffeId {
|
|||
* Returns true if the trust domain of this SPIFFE ID is the same as trust domain given as parameter.
|
||||
*
|
||||
* @param trustDomain an instance of a {@link TrustDomain}
|
||||
* @return <code>true</code> if the given trust domain equals the trust domain of this object, <code>false</code> otherwise
|
||||
* @return <code>true</code> if the given trust domain equals the trust domain of this object,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean memberOf(final TrustDomain trustDomain) {
|
||||
return this.trustDomain.equals(trustDomain);
|
||||
|
|
|
|||
|
|
@ -9,17 +9,19 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
* Utility class with methods to read SPIFFE IDs using different mechanisms.
|
||||
*/
|
||||
public class SpiffeIdUtils {
|
||||
public final class SpiffeIdUtils {
|
||||
|
||||
private static final char DEFAULT_CHAR_SEPARATOR = ',';
|
||||
|
||||
private SpiffeIdUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file containing a list of SPIFFE IDs and parses them to {@link SpiffeId} instances.
|
||||
* <p>
|
||||
|
|
@ -31,7 +33,7 @@ public class SpiffeIdUtils {
|
|||
* @throws IllegalArgumentException if any of the SPIFFE IDs in the file cannot be parsed
|
||||
*/
|
||||
public static Set<SpiffeId> getSpiffeIdSetFromFile(final Path spiffeIdsFile) throws IOException {
|
||||
try (Stream<String> lines = Files.lines(spiffeIdsFile)) {
|
||||
try (val lines = Files.lines(spiffeIdsFile)) {
|
||||
return lines
|
||||
.map(SpiffeId::parse)
|
||||
.collect(Collectors.toSet());
|
||||
|
|
@ -68,7 +70,4 @@ public class SpiffeIdUtils {
|
|||
public static Set<SpiffeId> toSetOfSpiffeIds(final String spiffeIds) {
|
||||
return toSetOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
|
||||
}
|
||||
|
||||
private SpiffeIdUtils() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class TrustDomain {
|
|||
}
|
||||
}
|
||||
|
||||
private static String normalize(String s) {
|
||||
private static String normalize(final String s) {
|
||||
String result = s.toLowerCase().trim();
|
||||
if (!result.contains("://")) {
|
||||
result = SpiffeId.SPIFFE_SCHEME.concat("://").concat(result);
|
||||
|
|
|
|||
|
|
@ -88,17 +88,22 @@ public class JwtSvid {
|
|||
* The JWT-SVID signature is verified using the JWT bundle source.
|
||||
*
|
||||
* @param token a token as a string that is parsed and validated
|
||||
* @param jwtBundleSource an implementation of a {@link BundleSource} that provides the JWT authorities to verify the signature
|
||||
* @param jwtBundleSource an implementation of a {@link BundleSource} that provides the JWT authorities to
|
||||
* verify the signature
|
||||
* @param audience audience as a list of strings used to validate the 'aud' claim
|
||||
* @return an instance of a {@link JwtSvid} with a SPIFFE ID parsed from the 'sub', audience from 'aud', and expiry
|
||||
* from 'exp' claim.
|
||||
* @throws JwtSvidException when the token expired or the expiration claim is missing,
|
||||
* when the algorithm is not supported, when the header 'kid' is missing, when the signature cannot be verified, or
|
||||
* when the 'aud' claim has an audience that is not in the audience list provided as parameter
|
||||
* when the algorithm is not supported, when the header 'kid' is missing,
|
||||
* when the signature cannot be verified, or
|
||||
* when the 'aud' claim has an audience that is not in the audience list
|
||||
* provided as parameter
|
||||
* @throws IllegalArgumentException when the token is blank or cannot be parsed
|
||||
* @throws BundleNotFoundException if the bundle for the trust domain of the spiffe id from the 'sub' cannot be found
|
||||
* @throws BundleNotFoundException if the bundle for the trust domain of the spiffe id from the 'sub'
|
||||
* cannot be found
|
||||
* in the JwtBundleSource
|
||||
* @throws AuthorityNotFoundException if the authority cannot be found in the bundle using the value from the 'kid' header
|
||||
* @throws AuthorityNotFoundException if the authority cannot be found in the bundle using the value from
|
||||
* the 'kid' header
|
||||
*/
|
||||
public static JwtSvid parseAndValidate(@NonNull final String token,
|
||||
@NonNull final BundleSource<JwtBundle> jwtBundleSource,
|
||||
|
|
@ -230,7 +235,7 @@ public class JwtSvid {
|
|||
|
||||
private static JWSVerifier getJwsVerifier(final PublicKey jwtAuthority, final String algorithm) throws JOSEException, JwtSvidException {
|
||||
JWSVerifier verifier;
|
||||
final Algorithm alg = Algorithm.parse(algorithm);
|
||||
val alg = Algorithm.parse(algorithm);
|
||||
if (Algorithm.Family.EC.contains(alg)) {
|
||||
verifier = new ECDSAVerifier((ECPublicKey) jwtAuthority);
|
||||
} else if (Algorithm.Family.RSA.contains(alg)) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
package io.spiffe.svid.x509svid;
|
||||
|
||||
import io.spiffe.exception.X509SvidException;
|
||||
import io.spiffe.internal.AsymmetricKeyAlgorithm;
|
||||
import io.spiffe.internal.CertificateUtils;
|
||||
import io.spiffe.internal.KeyFileFormat;
|
||||
import io.spiffe.internal.AsymmetricKeyAlgorithm;
|
||||
import io.spiffe.spiffeid.SpiffeId;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import lombok.val;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
|
@ -73,15 +74,16 @@ public class X509Svid {
|
|||
* @return an instance of {@link X509Svid}
|
||||
* @throws X509SvidException if there is an error parsing the given certsFilePath or the privateKeyFilePath
|
||||
*/
|
||||
public static X509Svid load(@NonNull final Path certsFilePath, @NonNull final Path privateKeyFilePath) throws X509SvidException {
|
||||
byte[] certsBytes;
|
||||
public static X509Svid load(@NonNull final Path certsFilePath, @NonNull final Path privateKeyFilePath)
|
||||
throws X509SvidException {
|
||||
final byte[] certsBytes;
|
||||
try {
|
||||
certsBytes = Files.readAllBytes(certsFilePath);
|
||||
} catch (IOException e) {
|
||||
throw new X509SvidException("Cannot read certificate file", e);
|
||||
}
|
||||
|
||||
byte[] privateKeyBytes;
|
||||
final byte[] privateKeyBytes;
|
||||
try {
|
||||
privateKeyBytes = Files.readAllBytes(privateKeyFilePath);
|
||||
} catch (IOException e) {
|
||||
|
|
@ -101,7 +103,8 @@ public class X509Svid {
|
|||
* @return a {@link X509Svid} parsed from the given certBytes and privateKeyBytes
|
||||
* @throws X509SvidException if the given certsBytes or privateKeyBytes cannot be parsed
|
||||
*/
|
||||
public static X509Svid parse(@NonNull final byte[] certsBytes, @NonNull final byte[] privateKeyBytes) throws X509SvidException {
|
||||
public static X509Svid parse(@NonNull final byte[] certsBytes, @NonNull final byte[] privateKeyBytes)
|
||||
throws X509SvidException {
|
||||
return createX509Svid(certsBytes, privateKeyBytes, KeyFileFormat.PEM);
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +119,8 @@ public class X509Svid {
|
|||
* @return a {@link X509Svid} parsed from the given certBytes and privateKeyBytes
|
||||
* @throws X509SvidException if the given certsBytes or privateKeyBytes cannot be parsed
|
||||
*/
|
||||
public static X509Svid parseRaw(@NonNull final byte[] certsBytes, @NonNull final byte[] privateKeyBytes) throws X509SvidException {
|
||||
public static X509Svid parseRaw(@NonNull final byte[] certsBytes,
|
||||
@NonNull final byte[] privateKeyBytes) throws X509SvidException {
|
||||
return createX509Svid(certsBytes, privateKeyBytes, KeyFileFormat.DER);
|
||||
}
|
||||
|
||||
|
|
@ -127,10 +131,13 @@ public class X509Svid {
|
|||
return chain.toArray(new X509Certificate[0]);
|
||||
}
|
||||
|
||||
private static X509Svid createX509Svid(final byte[] certsBytes, final byte[] privateKeyBytes, KeyFileFormat keyFileFormat) throws X509SvidException {
|
||||
List<X509Certificate> x509Certificates = generateX509Certificates(certsBytes);
|
||||
PrivateKey privateKey = generatePrivateKey(privateKeyBytes, keyFileFormat, x509Certificates);
|
||||
SpiffeId spiffeId = getSpiffeId(x509Certificates);
|
||||
private static X509Svid createX509Svid(final byte[] certsBytes,
|
||||
final byte[] privateKeyBytes,
|
||||
final KeyFileFormat keyFileFormat) throws X509SvidException {
|
||||
|
||||
val x509Certificates = generateX509Certificates(certsBytes);
|
||||
val privateKey = generatePrivateKey(privateKeyBytes, keyFileFormat, x509Certificates);
|
||||
val spiffeId = getSpiffeId(x509Certificates);
|
||||
|
||||
validatePrivateKey(privateKey, x509Certificates);
|
||||
validateLeafCertificate(x509Certificates.get(0));
|
||||
|
|
@ -144,7 +151,7 @@ public class X509Svid {
|
|||
}
|
||||
|
||||
private static SpiffeId getSpiffeId(final List<X509Certificate> x509Certificates) throws X509SvidException {
|
||||
SpiffeId spiffeId;
|
||||
final SpiffeId spiffeId;
|
||||
try {
|
||||
spiffeId = CertificateUtils.getSpiffeId(x509Certificates.get(0));
|
||||
} catch (CertificateException e) {
|
||||
|
|
@ -153,9 +160,14 @@ public class X509Svid {
|
|||
return spiffeId;
|
||||
}
|
||||
|
||||
private static PrivateKey generatePrivateKey(final byte[] privateKeyBytes, final KeyFileFormat keyFileFormat, final List<X509Certificate> x509Certificates) throws X509SvidException {
|
||||
AsymmetricKeyAlgorithm algorithm = AsymmetricKeyAlgorithm.parse(x509Certificates.get(0).getPublicKey().getAlgorithm());
|
||||
PrivateKey privateKey;
|
||||
private static PrivateKey generatePrivateKey(final byte[] privateKeyBytes,
|
||||
final KeyFileFormat keyFileFormat,
|
||||
final List<X509Certificate> x509Certificates)
|
||||
throws X509SvidException {
|
||||
|
||||
val publicKeyCertAlgorithm = x509Certificates.get(0).getPublicKey().getAlgorithm();
|
||||
val algorithm = AsymmetricKeyAlgorithm.parse(publicKeyCertAlgorithm);
|
||||
final PrivateKey privateKey;
|
||||
try {
|
||||
privateKey = CertificateUtils.generatePrivateKey(privateKeyBytes, algorithm, keyFileFormat);
|
||||
} catch (InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
|
||||
|
|
@ -208,7 +220,8 @@ public class X509Svid {
|
|||
}
|
||||
}
|
||||
|
||||
private static void validatePrivateKey(final PrivateKey privateKey, final List<X509Certificate> x509Certificates) throws X509SvidException {
|
||||
private static void validatePrivateKey(final PrivateKey privateKey, final List<X509Certificate> x509Certificates)
|
||||
throws X509SvidException {
|
||||
try {
|
||||
CertificateUtils.validatePrivateKey(privateKey, x509Certificates.get(0));
|
||||
} catch (InvalidKeyException e) {
|
||||
|
|
|
|||
|
|
@ -19,16 +19,19 @@ import java.util.function.Supplier;
|
|||
/**
|
||||
* Provides methods to validate a chain of X.509 certificates using an X.509 bundle source.
|
||||
*/
|
||||
public class X509SvidValidator {
|
||||
public final class X509SvidValidator {
|
||||
|
||||
private X509SvidValidator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a chain of certificates can be chained to one authority in the given X.509 bundle source.
|
||||
*
|
||||
* @param chain a list representing the chain of X.509 certificates to be validated
|
||||
* @param x509BundleSource a {@link BundleSource } to provide the authorities
|
||||
* @throws CertificateException is the chain cannot be verified with an authority from the X.509 bundle source
|
||||
* @throws CertificateException is the chain cannot be verified with an authority from the X.509 bundle source
|
||||
* @throws BundleNotFoundException if no X.509 bundle for the trust domain could be found in the X.509 bundle source
|
||||
* @throws NullPointerException if the given chain or 509BundleSource are null
|
||||
* @throws NullPointerException if the given chain or 509BundleSource are null
|
||||
*/
|
||||
public static void verifyChain(
|
||||
@NonNull final List<X509Certificate> chain,
|
||||
|
|
@ -48,10 +51,11 @@ public class X509SvidValidator {
|
|||
/**
|
||||
* Checks that the X.509 SVID provided has a SPIFFE ID that is in the Set of accepted SPIFFE IDs supplied.
|
||||
*
|
||||
* @param x509Certificate a {@link X509Svid} with a SPIFFE ID to be verified
|
||||
* @param x509Certificate a {@link X509Svid} with a SPIFFE ID to be verified
|
||||
* @param acceptedSpiffeIdsSupplier a {@link Supplier} of a Set of SPIFFE IDs that are accepted
|
||||
* @throws CertificateException if the SPIFFE ID in x509Certificate is not in the Set supplied by acceptedSpiffeIdsSupplier,
|
||||
* or if the SPIFFE ID cannot be parsed from the x509Certificate
|
||||
* @throws CertificateException if the SPIFFE ID in x509Certificate is not in the Set supplied by
|
||||
* acceptedSpiffeIdsSupplier, or if the SPIFFE ID cannot be parsed from the
|
||||
* x509Certificate
|
||||
* @throws NullPointerException if the given x509Certificate or acceptedSpiffeIdsSupplier are null
|
||||
*/
|
||||
public static void verifySpiffeId(@NonNull final X509Certificate x509Certificate,
|
||||
|
|
@ -60,10 +64,8 @@ public class X509SvidValidator {
|
|||
val spiffeIdSet = acceptedSpiffeIdsSupplier.get();
|
||||
val spiffeId = CertificateUtils.getSpiffeId(x509Certificate);
|
||||
if (!spiffeIdSet.contains(spiffeId)) {
|
||||
throw new CertificateException(String.format("SPIFFE ID %s in X.509 certificate is not accepted", spiffeId));
|
||||
final String error = "SPIFFE ID %s in X.509 certificate is not accepted";
|
||||
throw new CertificateException(String.format(error, spiffeId));
|
||||
}
|
||||
}
|
||||
|
||||
private X509SvidValidator() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ public class Address {
|
|||
private static final String TCP_SCHEME = "tcp";
|
||||
private static final Set<String> VALID_SCHEMES = Sets.newHashSet(UNIX_SCHEME, TCP_SCHEME);
|
||||
|
||||
private Address() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default Workload API address hold by the system environment variable
|
||||
* defined by SOCKET_ENV_VARIABLE.
|
||||
|
|
@ -43,7 +46,8 @@ public class Address {
|
|||
* The scheme and path components are mandatory, and no other component may be set.
|
||||
* <p>
|
||||
* If the scheme is set to tcp, then the host component of the authority MUST be set to an IP address,
|
||||
* and the port component of the authority MUST be set to the TCP port number of the SPIFFE Workload Endpoint TCP listen socket.
|
||||
* and the port component of the authority MUST be set to the TCP port number of the
|
||||
* SPIFFE Workload Endpoint TCP listen socket.
|
||||
* The scheme, host, and port components are mandatory, and no other component may be set.
|
||||
* As an example, tcp://127.0.0.1:8000 is valid, and tcp://127.0.0.1:8000/foo is not.
|
||||
*
|
||||
|
|
@ -58,7 +62,8 @@ public class Address {
|
|||
val parsedAddress = parseUri(address);
|
||||
val scheme = parsedAddress.getScheme();
|
||||
if (isSchemeNotValid(scheme)) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint socket URI must have a tcp:// or unix:// scheme: %s", address));
|
||||
val error = "Workload endpoint socket URI must have a tcp:// or unix:// scheme: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, address));
|
||||
}
|
||||
|
||||
if (UNIX_SCHEME.equals(scheme)) {
|
||||
|
|
@ -75,77 +80,88 @@ public class Address {
|
|||
try {
|
||||
parsedAddress = new URI(address);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint socket is not a valid URI: %s", address), e);
|
||||
val error = "Workload endpoint socket is not a valid URI: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, address), e);
|
||||
}
|
||||
return parsedAddress;
|
||||
}
|
||||
|
||||
private static void validateUnixAddress(final URI parsedAddress) throws SocketEndpointAddressException {
|
||||
if (parsedAddress.isOpaque()) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint unix socket URI must not be opaque: %s", parsedAddress));
|
||||
val error = "Workload endpoint unix socket URI must not be opaque: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getRawAuthority())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint unix socket URI must not include authority component: %s", parsedAddress));
|
||||
val error = "Workload endpoint unix socket URI must not include authority component: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (hasEmptyPath(parsedAddress.getPath())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint unix socket path cannot be blank: %s", parsedAddress));
|
||||
val error = "Workload endpoint unix socket path cannot be blank: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint unix socket URI must not include query values: %s", parsedAddress));
|
||||
val error = "Workload endpoint unix socket URI must not include query values: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint unix socket URI must not include a fragment: %s", parsedAddress));
|
||||
val error = "Workload endpoint unix socket URI must not include a fragment: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateTcpAddress(final URI parsedAddress) throws SocketEndpointAddressException {
|
||||
if (parsedAddress.isOpaque()) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must not be opaque: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI must not be opaque: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getUserInfo())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must not include user info: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI must not include user info: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(parsedAddress.getHost())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must include a host: %s", parsedAddress));
|
||||
final String error = "Workload endpoint tcp socket URI must include a host: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getPath())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must not include a path: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI must not include a path: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getRawQuery())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must not include query values: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI must not include query values: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(parsedAddress.getFragment())) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI must not include a fragment: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI must not include a fragment: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
val ipValid = InetAddressValidator.getInstance().isValid(parsedAddress.getHost());
|
||||
if (!ipValid) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI host component must be an IP:port: %s", parsedAddress));
|
||||
val error = "Workload endpoint tcp socket URI host component must be an IP:port: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
|
||||
int port = parsedAddress.getPort();
|
||||
if (port == -1) {
|
||||
throw new SocketEndpointAddressException(String.format("Workload endpoint tcp socket URI host component must include a port: %s", parsedAddress));
|
||||
final String error = "Workload endpoint tcp socket URI host component must include a port: %s";
|
||||
throw new SocketEndpointAddressException(String.format(error, parsedAddress));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasEmptyPath(final String path) {
|
||||
return StringUtils.isBlank(path) || path.equals("/");
|
||||
return StringUtils.isBlank(path) || "/".equals(path);
|
||||
}
|
||||
|
||||
private static boolean isSchemeNotValid(final String scheme) {
|
||||
return !VALID_SCHEMES.contains(scheme);
|
||||
}
|
||||
|
||||
private Address() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,31 +22,32 @@ import java.util.Map;
|
|||
/**
|
||||
* Utility methods for converting GRPC objects to JAVA-SPIFFE domain objects.
|
||||
*/
|
||||
class GrpcConversionUtils {
|
||||
final class GrpcConversionUtils {
|
||||
|
||||
private GrpcConversionUtils() {}
|
||||
private GrpcConversionUtils() {
|
||||
}
|
||||
|
||||
static X509Context toX509Context(final Workload.X509SVIDResponse x509SVIDResponse)
|
||||
static X509Context toX509Context(final Workload.X509SVIDResponse x509SvidResponse)
|
||||
throws CertificateException, X509SvidException {
|
||||
|
||||
val x509SvidList = getListOfX509Svid(x509SVIDResponse);
|
||||
val x509BundleList = getListOfX509Bundles(x509SVIDResponse);
|
||||
val x509SvidList = getListOfX509Svid(x509SvidResponse);
|
||||
val x509BundleList = getListOfX509Bundles(x509SvidResponse);
|
||||
val bundleSet = X509BundleSet.of(x509BundleList);
|
||||
return new X509Context(x509SvidList, bundleSet);
|
||||
}
|
||||
|
||||
static List<X509Bundle> getListOfX509Bundles(final Workload.X509SVIDResponse x509SVIDResponse)
|
||||
static List<X509Bundle> getListOfX509Bundles(final Workload.X509SVIDResponse x509SvidResponse)
|
||||
throws CertificateException {
|
||||
|
||||
final List<X509Bundle> x509BundleList = new ArrayList<>();
|
||||
for (Workload.X509SVID x509Svid : x509SVIDResponse.getSvidsList()) {
|
||||
for (Workload.X509SVID x509Svid : x509SvidResponse.getSvidsList()) {
|
||||
val spiffeId = SpiffeId.parse(x509Svid.getSpiffeId());
|
||||
val bundle = X509Bundle.parse(spiffeId.getTrustDomain(), x509Svid.getBundle().toByteArray());
|
||||
x509BundleList.add(bundle);
|
||||
}
|
||||
|
||||
// Process federated bundles
|
||||
for (Map.Entry<String, ByteString> bundleEntry : x509SVIDResponse.getFederatedBundlesMap().entrySet()) {
|
||||
for (Map.Entry<String, ByteString> bundleEntry : x509SvidResponse.getFederatedBundlesMap().entrySet()) {
|
||||
val bundle = X509Bundle.parse(TrustDomain.of(bundleEntry.getKey()), bundleEntry.getValue().toByteArray());
|
||||
x509BundleList.add(bundle);
|
||||
}
|
||||
|
|
@ -54,12 +55,12 @@ class GrpcConversionUtils {
|
|||
return x509BundleList;
|
||||
}
|
||||
|
||||
private static List<X509Svid> getListOfX509Svid(final Workload.X509SVIDResponse x509SVIDResponse)
|
||||
private static List<X509Svid> getListOfX509Svid(final Workload.X509SVIDResponse x509SvidResponse)
|
||||
throws X509SvidException {
|
||||
|
||||
final List<X509Svid> x509SvidList = new ArrayList<>();
|
||||
|
||||
for (Workload.X509SVID x509SVID : x509SVIDResponse.getSvidsList()) {
|
||||
for (Workload.X509SVID x509SVID : x509SvidResponse.getSvidsList()) {
|
||||
val svid = X509Svid.parseRaw(x509SVID.getX509Svid().toByteArray(), x509SVID.getX509SvidKey().toByteArray());
|
||||
x509SvidList.add(svid);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue