Adding tests to improve coverage for X509Svid, X509SvidValidator, X509BundleSet, SpiffeId, JwtSvid.
Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
parent
fa50d55dd0
commit
11d00e191c
|
|
@ -53,7 +53,7 @@ public class X509BundleSet implements X509BundleSource {
|
|||
* @throws BundleNotFoundException if no bundle could be found for the given trust domain
|
||||
*/
|
||||
@Override
|
||||
public X509Bundle getX509BundleForTrustDomain(final TrustDomain trustDomain) throws BundleNotFoundException {
|
||||
public X509Bundle getX509BundleForTrustDomain(@NonNull final TrustDomain trustDomain) throws BundleNotFoundException {
|
||||
val bundle = bundles.get(trustDomain);
|
||||
if (bundle == null){
|
||||
throw new BundleNotFoundException(String.format("No X509 bundle for trust domain %s", trustDomain));
|
||||
|
|
|
|||
|
|
@ -101,11 +101,16 @@ public class CertificateUtils {
|
|||
* @throws NoSuchAlgorithmException
|
||||
* @throws CertPathValidatorException
|
||||
*/
|
||||
public static void validate(List<X509Certificate> chain, List<X509Certificate> trustedCerts) throws CertificateException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, CertPathValidatorException {
|
||||
public static void validate(List<X509Certificate> chain, List<X509Certificate> trustedCerts) throws CertificateException, CertPathValidatorException {
|
||||
val certificateFactory = getCertificateFactory();
|
||||
val pkixParameters = toPkixParameters(trustedCerts);
|
||||
val certPath = certificateFactory.generateCertPath(chain);
|
||||
getCertPathValidator().validate(certPath, pkixParameters);
|
||||
PKIXParameters pkixParameters = null;
|
||||
try {
|
||||
pkixParameters = toPkixParameters(trustedCerts);
|
||||
val certPath = certificateFactory.generateCertPath(chain);
|
||||
getCertPathValidator().validate(certPath, pkixParameters);
|
||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
|
||||
throw new CertificateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -151,28 +156,32 @@ public class CertificateUtils {
|
|||
*
|
||||
* @throws InvalidKeyException if the keys don't match
|
||||
*/
|
||||
public static void validatePrivateKey(PrivateKey privateKey, X509Certificate x509Certificate) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException {
|
||||
public static void validatePrivateKey(PrivateKey privateKey, X509Certificate x509Certificate) throws InvalidKeyException {
|
||||
// create a challenge
|
||||
byte[] challenge = new byte[1000];
|
||||
ThreadLocalRandom.current().nextBytes(challenge);
|
||||
|
||||
Signature sig = null;
|
||||
|
||||
if ("RSA".equals(privateKey.getAlgorithm())) {
|
||||
sig = Signature.getInstance("SHA256withRSA");
|
||||
} else {
|
||||
sig = Signature.getInstance("SHA1withECDSA");
|
||||
}
|
||||
try {
|
||||
if ("RSA".equals(privateKey.getAlgorithm())) {
|
||||
sig = Signature.getInstance("SHA256withRSA");
|
||||
} else {
|
||||
sig = Signature.getInstance("SHA1withECDSA");
|
||||
}
|
||||
|
||||
sig.initSign(privateKey);
|
||||
sig.update(challenge);
|
||||
byte[] signature = sig.sign();
|
||||
sig.initSign(privateKey);
|
||||
sig.update(challenge);
|
||||
byte[] signature = sig.sign();
|
||||
|
||||
sig.initVerify(x509Certificate.getPublicKey());
|
||||
sig.update(challenge);
|
||||
sig.initVerify(x509Certificate.getPublicKey());
|
||||
sig.update(challenge);
|
||||
|
||||
if (!sig.verify(signature)) {
|
||||
throw new InvalidKeyException("Private Key does not match Certificate Public Key");
|
||||
if (!sig.verify(signature)) {
|
||||
throw new InvalidKeyException("Private Key does not match Certificate Public Key");
|
||||
}
|
||||
} catch (SignatureException | NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("Could not validate private keys", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ public class SpiffeId {
|
|||
throw new IllegalArgumentException("SPIFFE ID cannot be empty");
|
||||
}
|
||||
|
||||
val uri = URI.create(spiffeIdAsString);
|
||||
val uri = URI.create(normalize(spiffeIdAsString));
|
||||
|
||||
if (!SPIFFE_SCHEME.equals(uri.getScheme())) {
|
||||
throw new IllegalArgumentException("Invalid SPIFFE schema");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package spiffe.spiffeid;
|
||||
|
||||
import lombok.val;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
|
@ -11,6 +12,7 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Collections.EMPTY_LIST;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
|
|
@ -24,7 +26,8 @@ public class SpiffeIdUtils {
|
|||
* Reads the Accepted SPIFFE IDs from a system property and parses them to {@link SpiffeId} instances.
|
||||
*
|
||||
* @param systemProperty name of the system property that contains a list of SPIFFE IDs separated by a commas.
|
||||
* @return a list of {@link SpiffeId} parsed from the values read from the security property
|
||||
* @return a list of {@link SpiffeId} parsed from the values read from the security property, in case there's no values
|
||||
* in the System property, it returns an emtpy list
|
||||
*
|
||||
* @throws IllegalArgumentException if the given system property is empty or if any of the SPIFFE IDs
|
||||
* cannot be parsed
|
||||
|
|
@ -35,6 +38,9 @@ public class SpiffeIdUtils {
|
|||
}
|
||||
|
||||
val spiffeIds = System.getProperty(systemProperty);
|
||||
if (StringUtils.isBlank(spiffeIds)) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +58,12 @@ public class SpiffeIdUtils {
|
|||
if (isBlank(securityProperty)) {
|
||||
throw new IllegalArgumentException("Argument securityProperty cannot be empty");
|
||||
}
|
||||
|
||||
val spiffeIds = Security.getProperty(securityProperty);
|
||||
if (StringUtils.isBlank(spiffeIds)) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
|
||||
return toListOfSpiffeIds(spiffeIds, DEFAULT_CHAR_SEPARATOR);
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +99,7 @@ public class SpiffeIdUtils {
|
|||
*/
|
||||
public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds, final char separator) {
|
||||
if (isBlank(spiffeIds)) {
|
||||
throw new IllegalArgumentException("Argument spiffeIds cannot be emtpy");
|
||||
throw new IllegalArgumentException("Argument spiffeIds cannot be empty");
|
||||
}
|
||||
|
||||
val array = spiffeIds.split(String.valueOf(separator));
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class JwtSvid {
|
|||
* 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 cannot be parsed
|
||||
* @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
|
||||
* in the JwtBundleSource
|
||||
|
|
@ -93,6 +93,10 @@ public class JwtSvid {
|
|||
// to find the Authority in the jwtBundleSource. Once the Authority
|
||||
// is found, the token signature is verified
|
||||
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new IllegalArgumentException("Token cannot be blank");
|
||||
}
|
||||
|
||||
Jwt<?, ?> jwt = decodeToken(token);
|
||||
Claims claims = (Claims) jwt.getBody();
|
||||
List<String> aud = claims.get("aud", List.class);
|
||||
|
|
@ -130,7 +134,11 @@ public class JwtSvid {
|
|||
* the 'aud' has an audience that is not in the audience provided as parameter
|
||||
* @throws IllegalArgumentException when the token cannot be parsed
|
||||
*/
|
||||
public static JwtSvid parseInsecure(@NonNull final String token, List<String> audience) throws JwtSvidException {
|
||||
public static JwtSvid parseInsecure(@NonNull final String token, @NonNull List<String> audience) throws JwtSvidException {
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new IllegalArgumentException("Token cannot be blank");
|
||||
|
||||
}
|
||||
Jwt<?, ?> jwt = decodeToken(token);
|
||||
Claims claims = (Claims) jwt.getBody();
|
||||
List<String> aud = claims.get("aud", List.class);
|
||||
|
|
@ -160,7 +168,7 @@ public class JwtSvid {
|
|||
return new Date(expiry.getTime());
|
||||
}
|
||||
|
||||
private static void verifySignature(@NonNull String token, String keyId, PublicKey jwtAuthority) throws JwtSvidException {
|
||||
private static void verifySignature(String token, String keyId, PublicKey jwtAuthority) throws JwtSvidException {
|
||||
JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(jwtAuthority).build();
|
||||
try {
|
||||
// parse token with signature verification using the jwt authority (public key)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import java.nio.file.Path;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
|
@ -41,9 +40,9 @@ public class X509Svid implements X509SvidSource {
|
|||
PrivateKey privateKey;
|
||||
|
||||
private X509Svid(
|
||||
@NonNull SpiffeId spiffeId,
|
||||
@NonNull List<X509Certificate> chain,
|
||||
@NonNull PrivateKey privateKey) {
|
||||
SpiffeId spiffeId,
|
||||
List<X509Certificate> chain,
|
||||
PrivateKey privateKey) {
|
||||
this.spiffeId = spiffeId;
|
||||
this.chain = chain;
|
||||
this.privateKey = privateKey;
|
||||
|
|
@ -163,8 +162,6 @@ public class X509Svid implements X509SvidSource {
|
|||
CertificateUtils.validatePrivateKey(privateKey, x509Certificates.get(0));
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new X509SvidException("Private Key does not match Certificate Public Key", e);
|
||||
} catch (NoSuchAlgorithmException | SignatureException e) {
|
||||
throw new IllegalStateException("Could not validate private key", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import spiffe.exception.BundleNotFoundException;
|
|||
import spiffe.internal.CertificateUtils;
|
||||
import spiffe.spiffeid.SpiffeId;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
|
@ -42,8 +40,6 @@ public class X509SvidValidator {
|
|||
CertificateUtils.validate(chain, new ArrayList<>(x509Bundle.getX509Authorities()));
|
||||
} catch (CertPathValidatorException e) {
|
||||
throw new CertificateException("Cert chain cannot be verified", e);
|
||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
|
||||
throw new CertificateException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
package spiffe.bundle.x509bundle;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import spiffe.exception.BundleNotFoundException;
|
||||
import spiffe.internal.DummyX509Certificate;
|
||||
import spiffe.spiffeid.TrustDomain;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class X509BundleSetTest {
|
||||
|
||||
@Test
|
||||
void testOf_listOfBundles_Success() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("other.org"));
|
||||
List<X509Bundle> bundleList = Arrays.asList(x509Bundle1, x509Bundle2);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle1));
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOf_null_throwsNullPointerException() {
|
||||
try {
|
||||
X509BundleSet.of(null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("bundles is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdd() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
List<X509Bundle> bundleList = Collections.singletonList(x509Bundle1);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("other.org"));
|
||||
bundleSet.add(x509Bundle2);
|
||||
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle1));
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdd_sameBundleAgain_noDuplicate() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
List<X509Bundle> bundleList = Collections.singletonList(x509Bundle1);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
bundleSet.add(x509Bundle1);
|
||||
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle1));
|
||||
assertEquals(1, bundleSet.getBundles().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdd_aDifferentBundleForSameTrustDomain_replacesWithNewBundle() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
List<X509Bundle> bundleList = Collections.singletonList(x509Bundle1);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
x509Bundle2.addX509Authority(new DummyX509Certificate());
|
||||
bundleSet.add(x509Bundle2);
|
||||
|
||||
assertTrue(bundleSet.getBundles().contains(x509Bundle2));
|
||||
assertFalse(bundleSet.getBundles().contains(x509Bundle1));
|
||||
assertEquals(1, bundleSet.getBundles().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAdd_nullBundle_throwsNullPointerException() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
List<X509Bundle> bundleList = Collections.singletonList(x509Bundle1);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
try {
|
||||
bundleSet.add(null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("x509Bundle is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509BundleForTrustDomain_Success() throws BundleNotFoundException {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("other.org"));
|
||||
List<X509Bundle> bundleList = Arrays.asList(x509Bundle1, x509Bundle2);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
assertEquals(x509Bundle1, bundleSet.getX509BundleForTrustDomain(TrustDomain.of("example.org")));
|
||||
assertEquals(x509Bundle2, bundleSet.getX509BundleForTrustDomain(TrustDomain.of("other.org")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509BundleForTrustDomain_notFoundTrustDomain() {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("other.org"));
|
||||
List<X509Bundle> bundleList = Arrays.asList(x509Bundle1, x509Bundle2);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
try {
|
||||
bundleSet.getX509BundleForTrustDomain(TrustDomain.of("unknown.org"));
|
||||
fail("expected BundleNotFoundException");
|
||||
} catch (BundleNotFoundException e) {
|
||||
assertEquals("No X509 bundle for trust domain unknown.org", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509BundleForTrustDomain_nullTrustDomain_throwsException() throws BundleNotFoundException {
|
||||
X509Bundle x509Bundle1 = new X509Bundle(TrustDomain.of("example.org"));
|
||||
X509Bundle x509Bundle2 = new X509Bundle(TrustDomain.of("other.org"));
|
||||
List<X509Bundle> bundleList = Arrays.asList(x509Bundle1, x509Bundle2);
|
||||
X509BundleSet bundleSet = X509BundleSet.of(bundleList);
|
||||
|
||||
try {
|
||||
bundleSet.getX509BundleForTrustDomain(null);
|
||||
fail("expected exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBundles() {
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.platform.commons.util.StringUtils;
|
||||
import spiffe.exception.BundleNotFoundException;
|
||||
import spiffe.internal.DummyX509Certificate;
|
||||
import spiffe.spiffeid.TrustDomain;
|
||||
|
||||
|
|
@ -26,12 +27,42 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||
public class X509BundleTest {
|
||||
|
||||
@Test
|
||||
void TestNewBunlde() {
|
||||
void TestNewBundle() {
|
||||
X509Bundle x509Bundle = new X509Bundle(TrustDomain.of("example.org"));
|
||||
assertEquals(0, x509Bundle.getX509Authorities().size());
|
||||
assertEquals(TrustDomain.of("example.org"), x509Bundle.getTrustDomain());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNewBundle_nullTrustDomain_throwsNullPointerException() {
|
||||
try {
|
||||
new X509Bundle(null );
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNewBundleWithAuthorities_nullTrustDomain_throwsNullPointerException() {
|
||||
try {
|
||||
new X509Bundle(null, new HashSet<>());
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNewBundleAuthorities_nullAuthorities_throwsNullPointerException() {
|
||||
try {
|
||||
new X509Bundle(TrustDomain.of("example.org"), null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("x509Authorities is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void TestFromAuthorities() {
|
||||
X509Certificate x509Cert1 = new DummyX509Certificate();
|
||||
|
|
@ -46,10 +77,26 @@ public class X509BundleTest {
|
|||
assertEquals(authorities, x509Bundle.getX509Authorities());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509BundleForTrustDomain() throws BundleNotFoundException {
|
||||
X509Bundle x509Bundle = new X509Bundle(TrustDomain.of("example.org"));
|
||||
assertEquals(x509Bundle, x509Bundle.getX509BundleForTrustDomain(TrustDomain.of("example.org")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509BundleForTrustDomain_notBundleFound_throwsBundleNotFoundException() {
|
||||
X509Bundle x509Bundle = new X509Bundle(TrustDomain.of("example.org"));
|
||||
try {
|
||||
x509Bundle.getX509BundleForTrustDomain(TrustDomain.of("other.org"));
|
||||
} catch (BundleNotFoundException e) {
|
||||
assertEquals("No X509 bundle found for trust domain other.org", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void TestLoad_Succeeds() {
|
||||
try {
|
||||
X509Bundle x509Bundle = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(loadResource("testdata/x509bundle/certs.pem")));
|
||||
X509Bundle x509Bundle = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(toUri("testdata/x509bundle/certs.pem")));
|
||||
assertEquals(2, x509Bundle.getX509Authorities().size());
|
||||
} catch (IOException | CertificateException | URISyntaxException e) {
|
||||
fail(e);
|
||||
|
|
@ -59,24 +106,64 @@ public class X509BundleTest {
|
|||
@Test
|
||||
void TestLoad_Fails() {
|
||||
try {
|
||||
X509Bundle x509Bundle = X509Bundle.load(TrustDomain.of("example.org"), Paths.get("testdata/x509bundle/non-existent.pem"));
|
||||
X509Bundle.load(TrustDomain.of("example.org"), Paths.get("testdata/x509bundle/non-existent.pem"));
|
||||
fail("should have thrown exception");
|
||||
} catch (IOException | CertificateException e) {
|
||||
assertEquals("Unable to load X.509 bundle file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoad_nullTrustDomain_throwsNullPointerException() throws IOException, CertificateException {
|
||||
try {
|
||||
X509Bundle.load(null,Paths.get("testdata/x509bundle/non-existent.pem"));
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoad_nullBundlePath_throwsNullPointerException() throws IOException, CertificateException {
|
||||
try {
|
||||
X509Bundle.load(TrustDomain.of("example.org"), null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("bundlePath is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParse_nullTrustDomain_throwsNullPointerException() throws IOException, CertificateException {
|
||||
try {
|
||||
X509Bundle.parse(null, "bytes".getBytes());
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParse_nullBundlePath_throwsNullPointerException() throws IOException, CertificateException {
|
||||
try {
|
||||
X509Bundle.parse(TrustDomain.of("example.org"), null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("bundleBytes is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void TestX509AuthoritiesCRUD() {
|
||||
X509Bundle bundle1 = null;
|
||||
X509Bundle bundle2 = null;
|
||||
try {
|
||||
// Load bundle1, which contains a single certificate
|
||||
bundle1 = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(loadResource("testdata/x509bundle/cert.pem")));
|
||||
bundle1 = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(toUri("testdata/x509bundle/cert.pem")));
|
||||
|
||||
// Load bundle2, which contains 2 certificates
|
||||
// The first certificate is the same than the one used in bundle1
|
||||
bundle2 = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(loadResource("testdata/x509bundle/certs.pem")));
|
||||
bundle2 = X509Bundle.load(TrustDomain.of("example.org"), Paths.get(toUri("testdata/x509bundle/certs.pem")));
|
||||
} catch (IOException | CertificateException | URISyntaxException e) {
|
||||
fail(e);
|
||||
}
|
||||
|
|
@ -115,7 +202,7 @@ public class X509BundleTest {
|
|||
@MethodSource("provideX509BundleScenarios")
|
||||
void parseX509Bundle(TestCase testCase) {
|
||||
try {
|
||||
Path path = Paths.get(loadResource(testCase.path));
|
||||
Path path = Paths.get(toUri(testCase.path));
|
||||
byte[] bytes = Files.readAllBytes(path);
|
||||
X509Bundle x509Bundle = X509Bundle.parse(testCase.trustDomain, bytes);
|
||||
|
||||
|
|
@ -205,7 +292,7 @@ public class X509BundleTest {
|
|||
}
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
|
@ -23,7 +21,7 @@ public class CertificateUtilsTest {
|
|||
|
||||
@Test
|
||||
void generateCertificates_ofPEMByteArray_returnsListWithOneX509Certificate() throws IOException, URISyntaxException {
|
||||
val path = Paths.get(loadResource("testdata/internal/cert.pem"));
|
||||
val path = Paths.get(toUri("testdata/internal/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(path);
|
||||
|
||||
List<X509Certificate> x509CertificateList = null;
|
||||
|
|
@ -40,8 +38,8 @@ public class CertificateUtilsTest {
|
|||
|
||||
@Test
|
||||
void validate_certificateThatIsExpired_throwsCertificateException() throws IOException, CertificateException, URISyntaxException {
|
||||
val certPath = Paths.get(loadResource("testdata/internal/cert2.pem"));
|
||||
val certBundle = Paths.get(loadResource("testdata/internal/bundle.pem"));
|
||||
val certPath = Paths.get(toUri("testdata/internal/cert2.pem"));
|
||||
val certBundle = Paths.get(toUri("testdata/internal/bundle.pem"));
|
||||
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val bundleBytes = Files.readAllBytes(certBundle);
|
||||
|
|
@ -52,12 +50,12 @@ public class CertificateUtilsTest {
|
|||
try {
|
||||
CertificateUtils.validate(chain, trustedCert);
|
||||
fail("Expected exception");
|
||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | CertPathValidatorException e) {
|
||||
} catch (CertPathValidatorException e) {
|
||||
assertEquals("validity check failed", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,9 +95,21 @@ public class SpiffeIdTest {
|
|||
() -> assertEquals("trust-domain.org", spiffeId.getTrustDomain().toString()),
|
||||
() -> assertEquals("/path1/path2", spiffeId.getPath())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void parse_aStringContainingLeadingAndTrailingBlanks_ReturnsASpiffeIdThatHasTrustDomainAndPathSegments() {
|
||||
val spiffeIdAsString = " spiffe://trust-domain.org/path1/path2 ";
|
||||
|
||||
val spiffeId = SpiffeId.parse(spiffeIdAsString);
|
||||
|
||||
assertAll("SpiffeId",
|
||||
() -> assertEquals("trust-domain.org", spiffeId.getTrustDomain().toString()),
|
||||
() -> assertEquals("/path1/path2", spiffeId.getPath())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void parse_aStringContainingInvalidSchema_throwsIllegalArgumentException() {
|
||||
val invalidadSpiffeId = "siffe://trust-domain.org/path1/path2";
|
||||
|
|
@ -121,7 +133,27 @@ public class SpiffeIdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void of_nullTrustDomain_throwsIllegalArgumentException() {
|
||||
void parse_Null_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeId.parse(null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("spiffeIdAsString is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_nullTrustDomain_throwsNullPointerException() {
|
||||
try {
|
||||
SpiffeId.of(null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void of_nullTrustDomainNotNullPath_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeId.of(null, "path");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
package spiffe.spiffeid;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.Security;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class piffeIdUtilsTest {
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromSystemProperty() {
|
||||
System.setProperty("spiffe.property", " spiffe://example.org/workload1, spiffe://example.org/workload2 ");
|
||||
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSystemProperty("spiffe.property");
|
||||
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(2, spiffeIdList.size());
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromSystemPropertyThatHasNoValue_returnsEmptyList() {
|
||||
System.setProperty("spiffe.property", "");
|
||||
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSystemProperty("spiffe.property");
|
||||
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(0, spiffeIdList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromBlankSystemProperty_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeIdUtils.getSpiffeIdsFromSystemProperty("");
|
||||
fail("should have thrown exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromNullSystemProperty_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeIdUtils.getSpiffeIdsFromSystemProperty(null);
|
||||
fail("should have thrown exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromSecurityProperty() {
|
||||
Security.setProperty("spiffe.property", " spiffe://example.org/workload1, spiffe://example.org/workload2 ");
|
||||
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("spiffe.property");
|
||||
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(2, spiffeIdList.size());
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromSecurityPropertyThatHasNoValue_returnsEmptyList() {
|
||||
Security.setProperty("spiffe.property", "");
|
||||
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("spiffe.property");
|
||||
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(0, spiffeIdList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromBlankSecurityProperty_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeIdUtils.getSpiffeIdsFromSecurityProperty("");
|
||||
fail("should have thrown exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdsFromNullSecurityProperty_throwsIllegalArgumentException() {
|
||||
try {
|
||||
SpiffeIdUtils.getSpiffeIdsFromSecurityProperty(null);
|
||||
fail("should have thrown exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdListFromFile() throws URISyntaxException {
|
||||
Path path = Paths.get(toUri("testdata/spiffeid/spiffeIds.txt"));
|
||||
|
||||
try {
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.getSpiffeIdListFromFile(path);
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(3, spiffeIdList.size());
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
|
||||
assertEquals(SpiffeId.parse("spiffe://example2.org/workload1"), spiffeIdList.get(2));
|
||||
} catch (IOException e) {
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpiffeIdListFromNonExistenFile_throwsException() throws IOException {
|
||||
Path path = Paths.get("testdata/spiffeid/non-existent-file");
|
||||
|
||||
try {
|
||||
SpiffeIdUtils.getSpiffeIdListFromFile(path);
|
||||
fail("should have thrown exception");
|
||||
} catch (NoSuchFileException e) {
|
||||
assertEquals("testdata/spiffeid/non-existent-file", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void toListOfSpiffeIds() {
|
||||
String spiffeIdsAsString = " spiffe://example.org/workload1, spiffe://example.org/workload2 ";
|
||||
|
||||
List<SpiffeId> spiffeIdList = SpiffeIdUtils.toListOfSpiffeIds(spiffeIdsAsString, ',');
|
||||
|
||||
assertNotNull(spiffeIdList);
|
||||
assertEquals(2, spiffeIdList.size());
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload1"), spiffeIdList.get(0));
|
||||
assertEquals(SpiffeId.parse("spiffe://example.org/workload2"), spiffeIdList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void toListOfSPiffeIds_blankStringParameter() {
|
||||
try {
|
||||
SpiffeIdUtils.toListOfSpiffeIds("", ',');
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Argument spiffeIds cannot be empty", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import io.jsonwebtoken.impl.DefaultClaims;
|
|||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
|
@ -34,7 +35,7 @@ class JwtSvidParseAndValidateTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideJwtScenarios")
|
||||
void parseJwt(TestCase testCase) {
|
||||
void parseAndValidateJwt(TestCase testCase) {
|
||||
|
||||
try {
|
||||
String token = testCase.generateToken.get();
|
||||
|
|
@ -44,13 +45,61 @@ class JwtSvidParseAndValidateTest {
|
|||
assertEquals(testCase.expectedJwtSvid.getAudience(), jwtSvid.getAudience());
|
||||
assertEquals(testCase.expectedJwtSvid.getExpiry().toInstant().getEpochSecond(), jwtSvid.getExpiry().toInstant().getEpochSecond());
|
||||
assertEquals(token, jwtSvid.getToken());
|
||||
assertEquals(token, jwtSvid.marshall());
|
||||
} catch (Exception e) {
|
||||
assertEquals(testCase.expectedException.getClass(), e.getClass());
|
||||
assertEquals(testCase.expectedException.getMessage(), e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseAndValidate_nullToken_throwsNullPointerException() throws JwtSvidException, AuthorityNotFoundException, BundleNotFoundException {
|
||||
TrustDomain trustDomain = TrustDomain.of("test.domain");
|
||||
JwtBundle jwtBundle = new JwtBundle(trustDomain);
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
|
||||
try {
|
||||
JwtSvid.parseAndValidate(null, jwtBundle, audience);
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("token is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseAndValidate_emptyToken_throwsIllegalArgumentException() throws JwtSvidException, AuthorityNotFoundException, BundleNotFoundException {
|
||||
TrustDomain trustDomain = TrustDomain.of("test.domain");
|
||||
JwtBundle jwtBundle = new JwtBundle(trustDomain);
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
|
||||
try {
|
||||
JwtSvid.parseAndValidate("", jwtBundle, audience);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Token cannot be blank", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseAndValidate_nullBundle_throwsNullPointerException() throws JwtSvidException, AuthorityNotFoundException, BundleNotFoundException {
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
try {
|
||||
JwtSvid.parseAndValidate("token", null, audience);
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("jwtBundleSource is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseAndValidate_nullAudience_throwsNullPointerException() throws JwtSvidException, AuthorityNotFoundException, BundleNotFoundException {
|
||||
TrustDomain trustDomain = TrustDomain.of("test.domain");
|
||||
JwtBundle jwtBundle = new JwtBundle(trustDomain);
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
|
||||
try {
|
||||
JwtSvid.parseAndValidate("token", jwtBundle, null);
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("audience is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static Stream<Arguments> provideJwtScenarios() {
|
||||
KeyPair key1 = Keys.keyPairFor(SignatureAlgorithm.ES384);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import io.jsonwebtoken.impl.DefaultClaims;
|
|||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
|
@ -49,6 +50,42 @@ class JwtSvidParseInsecureTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseInsecure_nullToken_throwsNullPointerException() throws JwtSvidException {
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
|
||||
try {
|
||||
JwtSvid.parseInsecure(null, audience);
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("token is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseAndValidate_emptyToken_throwsIllegalArgumentException() throws JwtSvidException {
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
try {
|
||||
JwtSvid.parseInsecure("", audience);
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Token cannot be blank", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseInsecure_nullAudience_throwsNullPointerException() throws JwtSvidException {
|
||||
try {
|
||||
KeyPair key1 = Keys.keyPairFor(SignatureAlgorithm.ES384);
|
||||
TrustDomain trustDomain = TrustDomain.of("test.domain");
|
||||
SpiffeId spiffeId = trustDomain.newSpiffeId("host");
|
||||
List<String> audience = Collections.singletonList("audience");
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600000);
|
||||
Claims claims = buildClaims(audience, spiffeId.toString(), expiration);
|
||||
JwtSvid.parseInsecure(generateToken(claims, key1, "authority1"), null);
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("audience is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Stream<Arguments> provideJwtScenarios() {
|
||||
KeyPair key1 = Keys.keyPairFor(SignatureAlgorithm.ES384);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import java.net.URISyntaxException;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
|
@ -38,8 +39,8 @@ public class X509SvidTest {
|
|||
@Test
|
||||
void testLoad_Success() throws URISyntaxException {
|
||||
|
||||
Path certPath = Paths.get(loadResource(certSingle));
|
||||
Path keyPath = Paths.get(loadResource(keyRSA));
|
||||
Path certPath = Paths.get(toUri(certSingle));
|
||||
Path keyPath = Paths.get(toUri(keyRSA));
|
||||
try {
|
||||
X509Svid x509Svid = X509Svid.load(certPath, keyPath);
|
||||
assertEquals("spiffe://example.org/workload-1", x509Svid.getSpiffeId().toString());
|
||||
|
|
@ -50,7 +51,7 @@ public class X509SvidTest {
|
|||
|
||||
@Test
|
||||
void testLoad_FailsCannotReadCertFile() throws URISyntaxException {
|
||||
Path keyPath = Paths.get(loadResource(keyRSA));
|
||||
Path keyPath = Paths.get(toUri(keyRSA));
|
||||
try {
|
||||
X509Svid.load(Paths.get("not-existent-cert"), keyPath);
|
||||
fail("should have thrown IOException");
|
||||
|
|
@ -61,7 +62,7 @@ public class X509SvidTest {
|
|||
|
||||
@Test
|
||||
void testLoad_FailsCannotReadKeyFile() throws URISyntaxException {
|
||||
Path certPath = Paths.get(loadResource(certSingle));
|
||||
Path certPath = Paths.get(toUri(certSingle));
|
||||
try {
|
||||
X509Svid.load(certPath, Paths.get("not-existent-key"));
|
||||
fail("should have thrown IOException");
|
||||
|
|
@ -70,13 +71,72 @@ public class X509SvidTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoad_nullCertFilePath_throwsNullPointerException() throws URISyntaxException {
|
||||
try {
|
||||
X509Svid.load(null, Paths.get(toUri(keyRSA)));
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException | X509SvidException e) {
|
||||
assertEquals("certsFilePath is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoad_nullKeyFilePath_throwsNullPointerException() throws URISyntaxException, X509SvidException {
|
||||
try {
|
||||
X509Svid.load(Paths.get(toUri(certSingle)), null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("privateKeyFilePath is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParse_nullByteArray_throwsNullPointerException() throws X509SvidException {
|
||||
try {
|
||||
X509Svid.parse(null, "key".getBytes());
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("certsBytes is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParse_nullKeyByteArray_throwsNullPointerException() throws X509SvidException {
|
||||
try {
|
||||
X509Svid.parse("cert".getBytes(), null);
|
||||
fail("should have thrown exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("privateKeyBytes is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetX509Svid() throws URISyntaxException, X509SvidException {
|
||||
Path certPath = Paths.get(toUri(certSingle));
|
||||
Path keyPath = Paths.get(toUri(keyRSA));
|
||||
X509Svid x509Svid = X509Svid.load(certPath, keyPath);
|
||||
assertEquals(x509Svid, x509Svid.getX509Svid());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetChainArray() throws URISyntaxException, X509SvidException {
|
||||
Path certPath = Paths.get(toUri(certMultiple));
|
||||
Path keyPath = Paths.get(toUri(keyECDSA));
|
||||
X509Svid x509Svid = X509Svid.load(certPath, keyPath);
|
||||
X509Certificate[] x509CertificatesArray = x509Svid.getChainArray();
|
||||
assertEquals(x509Svid.getChain().get(0), x509CertificatesArray[0]);
|
||||
assertEquals(x509Svid.getChain().get(1), x509CertificatesArray[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideX509SvidScenarios")
|
||||
void parseX509Svid(TestCase testCase) {
|
||||
try {
|
||||
Path certPath = Paths.get(loadResource(testCase.certsPath));
|
||||
Path keyPath = Paths.get(loadResource(testCase.keyPath));
|
||||
Path certPath = Paths.get(toUri(testCase.certsPath));
|
||||
Path keyPath = Paths.get(toUri(testCase.keyPath));
|
||||
byte[] certBytes = Files.readAllBytes(certPath);
|
||||
byte[] keyBytes = Files.readAllBytes(keyPath);
|
||||
|
||||
|
|
@ -246,7 +306,7 @@ public class X509SvidTest {
|
|||
}
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.security.cert.CertificateException;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.EMPTY_LIST;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
|
@ -37,11 +38,11 @@ public class X509SvidValidatorTest {
|
|||
|
||||
@Test
|
||||
void verifyChain_certificateExpired_throwsCertificateException() throws IOException, CertificateException, BundleNotFoundException, URISyntaxException {
|
||||
val certPath = Paths.get(loadResource("testdata/x509svid/cert.pem"));
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val chain = CertificateUtils.generateCertificates(certBytes);
|
||||
|
||||
val bundlePath = Paths.get(loadResource("testdata/x509svid/bundle.pem"));
|
||||
val bundlePath = Paths.get(toUri("testdata/x509svid/bundle.pem"));
|
||||
X509Bundle x509Bundle=
|
||||
X509Bundle.load(
|
||||
TrustDomain.of("example.org"),
|
||||
|
|
@ -63,11 +64,11 @@ public class X509SvidValidatorTest {
|
|||
|
||||
@Test
|
||||
void verifyChain_noBundleForTrustDomain_throwsBundleNotFoundException() throws IOException, CertificateException, BundleNotFoundException, URISyntaxException {
|
||||
val certPath = Paths.get(loadResource("testdata/x509svid/cert.pem"));
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val chain = CertificateUtils.generateCertificates(certBytes);
|
||||
|
||||
val bundlePath = Paths.get(loadResource("testdata/x509svid/bundle.pem"));
|
||||
val bundlePath = Paths.get(toUri("testdata/x509svid/bundle.pem"));
|
||||
X509Bundle x509Bundle=
|
||||
X509Bundle.load(
|
||||
TrustDomain.of("example.org"),
|
||||
|
|
@ -92,7 +93,7 @@ public class X509SvidValidatorTest {
|
|||
val spiffeId1 = SpiffeId.parse("spiffe://example.org/test");
|
||||
val spiffeId2 = SpiffeId.parse("spiffe://example.org/test2");
|
||||
|
||||
val certPath = Paths.get(loadResource("testdata/x509svid/cert.pem"));
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val x509Certificate = CertificateUtils.generateCertificates(certBytes);
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ public class X509SvidValidatorTest {
|
|||
val spiffeId2 = SpiffeId.parse("spiffe://example.org/other2");
|
||||
List<SpiffeId> spiffeIdList = Arrays.asList(spiffeId1, spiffeId2);
|
||||
|
||||
val certPath = Paths.get(loadResource("testdata/x509svid/cert.pem"));
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val x509Certificate = CertificateUtils.generateCertificates(certBytes);
|
||||
|
||||
|
|
@ -119,7 +120,53 @@ public class X509SvidValidatorTest {
|
|||
}
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
@Test
|
||||
void checkSpiffeId_nullX509Certificate_throwsNullPointerException() throws CertificateException {
|
||||
try {
|
||||
X509SvidValidator.verifySpiffeId(null, () -> EMPTY_LIST);
|
||||
fail("should have thrown an exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("x509Certificate is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkSpiffeId_nullAcceptedSpiffeIdsSuppplier_throwsNullPointerException() throws CertificateException, URISyntaxException, IOException {
|
||||
try {
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val x509Certificate = CertificateUtils.generateCertificates(certBytes);
|
||||
X509SvidValidator.verifySpiffeId(x509Certificate.get(0), null);
|
||||
fail("should have thrown an exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("acceptedSpiffedIdsSupplier is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyChain_nullChain_throwsNullPointerException() throws CertificateException, BundleNotFoundException {
|
||||
try {
|
||||
X509SvidValidator.verifyChain(null, bundleSourceMock);
|
||||
fail("should have thrown an exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("chain is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifyChain_nullBundleSource_throwsNullPointerException() throws CertificateException, BundleNotFoundException, URISyntaxException, IOException {
|
||||
try {
|
||||
val certPath = Paths.get(toUri("testdata/x509svid/cert.pem"));
|
||||
val certBytes = Files.readAllBytes(certPath);
|
||||
val chain = CertificateUtils.generateCertificates(certBytes);
|
||||
X509SvidValidator.verifyChain(chain, null);
|
||||
fail("should have thrown an exception");
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals("x509BundleSource is marked non-null but is null", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
spiffe://example.org/workload1
|
||||
spiffe://example.org/workload2
|
||||
spiffe://example2.org/workload1
|
||||
|
|
@ -38,8 +38,8 @@ public class KeyStoreTest {
|
|||
void setup() throws X509SvidException, URISyntaxException {
|
||||
x509Svid = X509Svid
|
||||
.load(
|
||||
Paths.get(loadResource("testdata/x509cert.pem")),
|
||||
Paths.get(loadResource("testdata/pkcs8key.pem"))
|
||||
Paths.get(toUri("testdata/x509cert.pem")),
|
||||
Paths.get(toUri("testdata/pkcs8key.pem"))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ public class KeyStoreTest {
|
|||
}
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ public class SpiffeKeyManagerTest {
|
|||
keyManager = (X509KeyManager) new SpiffeKeyManagerFactory().engineGetKeyManagers(x509SvidSource)[0];
|
||||
x509Svid = X509Svid
|
||||
.load(
|
||||
Paths.get(loadResource("testdata/cert.pem")),
|
||||
Paths.get(loadResource("testdata/key.pem")));
|
||||
Paths.get(toUri("testdata/cert.pem")),
|
||||
Paths.get(toUri("testdata/key.pem")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -60,7 +60,7 @@ public class SpiffeKeyManagerTest {
|
|||
assertNotNull(privateKey);
|
||||
}
|
||||
|
||||
private URI loadResource(String path) throws URISyntaxException {
|
||||
private URI toUri(String path) throws URISyntaxException {
|
||||
return getClass().getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,16 +43,16 @@ public class SpiffeTrustManagerTest {
|
|||
static void setupClass() throws IOException, CertificateException, X509SvidException, URISyntaxException {
|
||||
x509Svid = X509Svid
|
||||
.load(
|
||||
Paths.get(loadResource("testdata/cert.pem")),
|
||||
Paths.get(loadResource("testdata/key.pem")));
|
||||
Paths.get(toUri("testdata/cert.pem")),
|
||||
Paths.get(toUri("testdata/key.pem")));
|
||||
otherX509Svid = X509Svid
|
||||
.load(
|
||||
Paths.get(loadResource("testdata/cert2.pem")),
|
||||
Paths.get(loadResource("testdata/key2.pem")));
|
||||
Paths.get(toUri("testdata/cert2.pem")),
|
||||
Paths.get(toUri("testdata/key2.pem")));
|
||||
x509Bundle = X509Bundle
|
||||
.load(
|
||||
TrustDomain.of("example.org"),
|
||||
Paths.get(loadResource("testdata/bundle.pem")));
|
||||
Paths.get(toUri("testdata/bundle.pem")));
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
|
@ -206,7 +206,7 @@ public class SpiffeTrustManagerTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static URI loadResource(String path) throws URISyntaxException {
|
||||
private static URI toUri(String path) throws URISyntaxException {
|
||||
return SpiffeTrustManagerTest.class.getClassLoader().getResource(path).toURI();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue