Addressing PR comments:

- replace private key format and algorithm guessing by parameters
- refactor a few ifs to switch case
- add spiffeid and trust domain validations and tests
- remove all imports wildcards
- other minor changes to improve quality

Signed-off-by: Max Lambrecht <maxlambrecht@gmail.com>
This commit is contained in:
Max Lambrecht 2020-06-22 16:08:17 -03:00
parent 538be3fa09
commit c92c90e7ea
48 changed files with 432 additions and 255 deletions

View File

@ -188,20 +188,17 @@ 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 = null;
if (Algorithm.Family.EC.equals(family)) {
PublicKey publicKey;
switch (family) {
case EC:
publicKey = ECKey.parse(jwk.toJSONString()).toPublicKey();
}
if (Algorithm.Family.RSA.equals(family)) {
break;
case RSA:
publicKey = RSAKey.parse(jwk.toJSONString()).toPublicKey();
}
if (publicKey == null) {
break;
default:
throw new KeyException(String.format("Key Type not supported: %s", jwk.getKeyType().getValue()));
}
return publicKey;
}
}

View File

@ -7,8 +7,8 @@ import lombok.NonNull;
import lombok.Value;
import lombok.val;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -27,10 +27,10 @@ public class JwtBundleSet implements BundleSource<JwtBundle> {
/**
* Creates a JWT bundle set from the list of JWT bundles.
*
* @param bundles List of {@link JwtBundle}
* @param bundles Collection of {@link JwtBundle}
* @return a {@link JwtBundleSet}
*/
public static JwtBundleSet of(@NonNull final List<JwtBundle> bundles) {
public static JwtBundleSet of(@NonNull final Collection<JwtBundle> bundles) {
Map<TrustDomain, JwtBundle> bundleMap = new ConcurrentHashMap<>();
for (JwtBundle bundle : bundles) {
bundleMap.put(bundle.getTrustDomain(), bundle);

View File

@ -7,8 +7,8 @@ import lombok.NonNull;
import lombok.Value;
import lombok.val;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -27,10 +27,10 @@ public class X509BundleSet implements BundleSource<X509Bundle> {
/**
* Creates a new X.509 bundle set from a list of X.509 bundles.
*
* @param bundles a list of {@link X509Bundle}
* @param bundles Collection of {@link X509Bundle}
* @return a {@link X509BundleSet} initialized with the list of bundles
*/
public static X509BundleSet of(@NonNull final List<X509Bundle> bundles) {
public static X509BundleSet of(@NonNull final Collection<X509Bundle> bundles) {
Map<TrustDomain, X509Bundle> bundleMap = new ConcurrentHashMap<>();
for (X509Bundle bundle : bundles) {
bundleMap.put(bundle.getTrustDomain(), bundle);

View File

@ -5,20 +5,38 @@ import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.TrustDomain;
import lombok.NonNull;
import lombok.val;
import org.apache.commons.lang3.RandomStringUtils;
import java.io.ByteArrayInputStream;
import java.security.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertPathValidator;
import java.security.cert.CertPathValidatorException;
import java.security.cert.Certificate;
import java.security.cert.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Collections.EMPTY_LIST;
import static io.spiffe.internal.KeyUsages.CRL_SIGN;
import static io.spiffe.internal.KeyUsages.DIGITAL_SIGNATURE;
import static io.spiffe.internal.KeyUsages.KEY_CERT_SIGN;
import static org.apache.commons.lang3.StringUtils.startsWith;
/**
@ -35,17 +53,6 @@ public class CertificateUtils {
private static final String PUBLIC_KEY_INFRASTRUCTURE_ALGORITHM = "PKIX";
private static final String X509_CERTIFICATE_TYPE = "X.509";
// X509Certificate Key Usage indexes
private static final int DIGITAL_SIGNATURE = 0;
private static final int NON_REPUDIATION = 1;
private static final int KEY_ENCIPHERMENT = 2;
private static final int DATA_ENCIPHERMENT = 3;
private static final int KEY_AGREEMENT = 4;
private static final int KEY_CERT_SIGN = 5;
private static final int CRL_SIGN = 6;
private static final int ENCIPHER_ONLY = 7;
private static final int DECIPHER_ONLY = 8;
private CertificateUtils() {
}
@ -60,12 +67,7 @@ public class CertificateUtils {
throw new CertificateParsingException("No certificates found");
}
CertificateFactory certificateFactory = null;
try {
certificateFactory = getCertificateFactory();
} catch (CertificateException e) {
throw new IllegalStateException("Could not create Certificate Factory", e);
}
val certificateFactory = getCertificateFactory();
Collection<? extends Certificate> certificates;
try {
@ -87,17 +89,9 @@ public class CertificateUtils {
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
*/
public static PrivateKey generatePrivateKey(final byte[] privateKeyBytes) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException {
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = null;
try {
privateKey = generatePrivateKeyWithSpec(kspec);
} catch (InvalidKeySpecException e) {
byte[] keyDer = toDerFormat(privateKeyBytes);
kspec = new PKCS8EncodedKeySpec(keyDer);
privateKey = generatePrivateKeyWithSpec(kspec);
}
return privateKey;
public static PrivateKey generatePrivateKey(final byte[] privateKeyBytes, Algorithm.Family algorithm, KeyFileFormat keyFileFormat) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException {
EncodedKeySpec kspec = getEncodedKeySpec(privateKeyBytes, keyFileFormat);
return generatePrivateKeyWithSpec(kspec, algorithm);
}
/**
@ -110,7 +104,7 @@ public class CertificateUtils {
*/
public static void validate(final List<X509Certificate> chain, final List<X509Certificate> trustedCerts) throws CertificateException, CertPathValidatorException {
val certificateFactory = getCertificateFactory();
PKIXParameters pkixParameters = null;
PKIXParameters pkixParameters;
try {
pkixParameters = toPkixParameters(trustedCerts);
val certPath = certificateFactory.generateCertPath(chain);
@ -121,7 +115,7 @@ public class CertificateUtils {
}
/**
* Extracts the SPIFE ID from an X.509 certificate.
* Extracts the SPIFFE ID from an X.509 certificate.
* <p>
* It iterates over the list of SubjectAlternativesNames, read each entry, takes the value from the index
* defined in SAN_VALUE_INDEX and filters the entries that starts with the SPIFFE_PREFIX and returns the first.
@ -165,11 +159,15 @@ public class CertificateUtils {
*/
public static void validatePrivateKey(final PrivateKey privateKey, final X509Certificate x509Certificate) throws InvalidKeyException {
Algorithm.Family algorithm = Algorithm.Family.parse(privateKey.getAlgorithm());
if (Algorithm.Family.RSA.equals(algorithm)) {
switch (algorithm) {
case RSA:
verifyKeys(privateKey, x509Certificate.getPublicKey(), SHA_512_WITH_RSA);
} else if (Algorithm.Family.EC.equals(algorithm)) {
break;
case EC:
verifyKeys(privateKey, x509Certificate.getPublicKey(), SHA_512_WITH_ECDSA);
} else {
break;
default:
throw new InvalidKeyException(String.format("Private Key algorithm not supported: %s", algorithm));
}
}
@ -180,23 +178,32 @@ public class CertificateUtils {
public static boolean hasKeyUsageCertSign(final X509Certificate cert) {
boolean[] keyUsage = cert.getKeyUsage();
return keyUsage[KEY_CERT_SIGN];
return keyUsage[KEY_CERT_SIGN.index()];
}
public static boolean hasKeyUsageDigitalSignature(final X509Certificate cert) {
boolean[] keyUsage = cert.getKeyUsage();
return keyUsage[DIGITAL_SIGNATURE];
return keyUsage[DIGITAL_SIGNATURE.index()];
}
public static boolean hasKeyUsageCRLSign(final X509Certificate cert) {
boolean[] keyUsage = cert.getKeyUsage();
return keyUsage[CRL_SIGN];
return keyUsage[CRL_SIGN.index()];
}
private static EncodedKeySpec getEncodedKeySpec(final byte[] privateKeyBytes, KeyFileFormat keyFileFormat) throws InvalidKeyException {
EncodedKeySpec keySpec;
if (keyFileFormat == KeyFileFormat.PEM) {
byte[] keyDer = toDerFormat(privateKeyBytes);
keySpec = new PKCS8EncodedKeySpec(keyDer);
} else {
keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
}
return keySpec;
}
private static void verifyKeys(final PrivateKey privateKey, final PublicKey publicKey, final String algorithm) throws InvalidKeyException {
final String randomString = RandomStringUtils.random(100, 0, 0, true, true, null, new SecureRandom());
byte[] challenge = randomString.getBytes();
final byte[] challenge = new SecureRandom().generateSeed(100);
try {
Signature sig = Signature.getInstance(algorithm);
sig.initSign(privateKey);
@ -214,7 +221,7 @@ public class CertificateUtils {
private static List<String> getSpiffeIds(final X509Certificate certificate) throws CertificateParsingException {
if (certificate.getSubjectAlternativeNames() == null) {
return EMPTY_LIST;
return Collections.emptyList();
}
return certificate.getSubjectAlternativeNames()
.stream()
@ -223,12 +230,19 @@ public class CertificateUtils {
.collect(Collectors.toList());
}
private static PrivateKey generatePrivateKeyWithSpec(final PKCS8EncodedKeySpec kspec) throws NoSuchAlgorithmException, InvalidKeySpecException {
try {
return KeyFactory.getInstance("EC").generatePrivate(kspec);
} catch (InvalidKeySpecException e) {
return KeyFactory.getInstance("RSA").generatePrivate(kspec);
private static PrivateKey generatePrivateKeyWithSpec(final EncodedKeySpec keySpec, Algorithm.Family algorithm) throws NoSuchAlgorithmException, InvalidKeySpecException {
PrivateKey privateKey;
switch (algorithm) {
case EC:
privateKey = KeyFactory.getInstance("EC").generatePrivate(keySpec);
break;
case RSA:
privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
break;
default:
throw new NoSuchAlgorithmException(String.format("Private Key algorithm is not supported: %s", algorithm));
}
return privateKey;
}
// Create an instance of PKIXParameters used as input for the PKIX CertPathValidator
@ -250,8 +264,12 @@ public class CertificateUtils {
}
// Get the X.509 Certificate Factory
private static CertificateFactory getCertificateFactory() throws CertificateException {
private static CertificateFactory getCertificateFactory() {
try {
return CertificateFactory.getInstance(X509_CERTIFICATE_TYPE);
} catch (CertificateException e) {
throw new IllegalStateException("Could not create Certificate Factory", e);
}
}
// Given a private key in PEM format, encode it as DER

View File

@ -0,0 +1,6 @@
package io.spiffe.internal;
public enum KeyFileFormat {
PEM,
DER
}

View File

@ -0,0 +1,24 @@
package io.spiffe.internal;
public enum KeyUsages {
DIGITAL_SIGNATURE(0),
NON_REPUDIATION(1),
KEY_ENCIPHERMENT(2),
DATA_ENCIPHERMENT(3),
KEY_AGREEMENT(4),
KEY_CERT_SIGN(5),
CRL_SIGN(6),
ENCIPHER_ONLY(7),
DECIPHER_ONLY(8);
private final int index;
public int index() {
return index;
}
KeyUsages(final int index) {
this.index = index;
}
}

View File

@ -18,6 +18,7 @@ import java.util.stream.Collectors;
public class SpiffeId {
public static final String SPIFFE_SCHEME = "spiffe";
public static final int SPIFFE_ID_MAX_LENGTH = 2048;
TrustDomain trustDomain;
@ -59,10 +60,7 @@ public class SpiffeId {
}
val uri = URI.create(normalize(spiffeIdAsString));
if (!SPIFFE_SCHEME.equals(uri.getScheme())) {
throw new IllegalArgumentException("Invalid SPIFFE schema");
}
validateUri(uri);
val trustDomain = TrustDomain.of(uri.getHost());
val path = uri.getPath();
@ -91,4 +89,35 @@ public class SpiffeId {
private static String normalize(final String s) {
return s.toLowerCase().trim();
}
private static void validateUri(final URI uri) {
val scheme = uri.getScheme();
if (!SpiffeId.SPIFFE_SCHEME.equals(scheme)) {
throw new IllegalArgumentException("SPIFFE ID: invalid scheme");
}
if (uri.getUserInfo() != null) {
throw new IllegalArgumentException("SPIFFE ID: user info is not allowed");
}
if (StringUtils.isBlank(uri.getHost())) {
throw new IllegalArgumentException("SPIFFE ID: trust domain is empty");
}
if (uri.getPort() != -1) {
throw new IllegalArgumentException("SPIFFE ID: port is not allowed");
}
if (StringUtils.isNotBlank(uri.getFragment())) {
throw new IllegalArgumentException("SPIFFE ID: fragment is not allowed");
}
if (StringUtils.isNotBlank(uri.getRawQuery())) {
throw new IllegalArgumentException("SPIFFE ID: query is not allowed");
}
if (uri.toString().length() > SPIFFE_ID_MAX_LENGTH) {
throw new IllegalArgumentException("SPIFFE ID: too long, maximum is 2048 bytes");
}
}
}

View File

@ -6,11 +6,11 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
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;
/**
@ -49,7 +49,7 @@ public class SpiffeIdUtils {
*/
public static List<SpiffeId> toListOfSpiffeIds(final String spiffeIds, final char separator) {
if (isBlank(spiffeIds)) {
return EMPTY_LIST;
return Collections.emptyList();
}
val array = spiffeIds.split(String.valueOf(separator));

View File

@ -15,6 +15,7 @@ import java.net.URISyntaxException;
@Value
public class TrustDomain {
public static final int TRUST_DOMAIN_MAX_LENGTH = 255;
String name;
private TrustDomain(final String trustDomain) {
@ -37,11 +38,11 @@ public class TrustDomain {
try {
val normalized = normalize(trustDomain);
uri = new URI(normalized);
validateUri(uri);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
validateUri(uri);
val host = uri.getHost();
validateHost(host);
return new TrustDomain(host);
@ -81,7 +82,11 @@ public class TrustDomain {
val port = uri.getPort();
if (port != -1) {
throw new IllegalArgumentException("Port is not allowed");
throw new IllegalArgumentException("Trust Domain: port is not allowed");
}
if (uri.toString().length() > TRUST_DOMAIN_MAX_LENGTH) {
throw new IllegalArgumentException("Trust Domain: too long, maximum is 255 bytes");
}
}

View File

@ -1,7 +1,9 @@
package io.spiffe.svid.x509svid;
import io.spiffe.Algorithm;
import io.spiffe.exception.X509SvidException;
import io.spiffe.internal.CertificateUtils;
import io.spiffe.internal.KeyFileFormat;
import io.spiffe.spiffeid.SpiffeId;
import lombok.NonNull;
import lombok.Value;
@ -68,7 +70,7 @@ public class X509Svid implements X509SvidSource {
} catch (IOException e) {
throw new X509SvidException("Cannot read private key file", e);
}
return createX509Svid(certsBytes, privateKeyBytes);
return createX509Svid(certsBytes, privateKeyBytes, KeyFileFormat.PEM);
}
/**
@ -81,7 +83,20 @@ public class X509Svid implements X509SvidSource {
* @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 {
return createX509Svid(certsBytes, privateKeyBytes);
return createX509Svid(certsBytes, privateKeyBytes, KeyFileFormat.PEM);
}
/**
* Parses the X509-SVID from certificate and key bytes. The certificate must be ASN.1 DER (concatenated with
* no intermediate padding if there are more than one certificate). The key must be a PKCS#8 ASN.1 DER.
*
* @param certsBytes chain of certificates as a byte array
* @param privateKeyBytes private key as byte array
* @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 {
return createX509Svid(certsBytes, privateKeyBytes, KeyFileFormat.DER);
}
/**
@ -91,7 +106,7 @@ public class X509Svid implements X509SvidSource {
return chain.toArray(new X509Certificate[0]);
}
private static X509Svid createX509Svid(final byte[] certsBytes, final byte[] privateKeyBytes) throws X509SvidException {
private static X509Svid createX509Svid(final byte[] certsBytes, final byte[] privateKeyBytes, KeyFileFormat keyFileFormat) throws X509SvidException {
List<X509Certificate> x509Certificates;
try {
@ -100,9 +115,10 @@ public class X509Svid implements X509SvidSource {
throw new X509SvidException("Certificate could not be parsed from cert bytes", e);
}
Algorithm.Family algorithm = Algorithm.Family.parse(x509Certificates.get(0).getPublicKey().getAlgorithm());
PrivateKey privateKey;
try {
privateKey = CertificateUtils.generatePrivateKey(privateKeyBytes);
privateKey = CertificateUtils.generatePrivateKey(privateKeyBytes, algorithm, keyFileFormat);
} catch (InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
throw new X509SvidException("Private Key could not be parsed from key bytes", e);
}

View File

@ -57,9 +57,7 @@ class GrpcConversionUtils {
List<X509Svid> x509SvidList = new ArrayList<>();
for (Workload.X509SVID x509SVID : x509SVIDResponse.getSvidsList()) {
val svid = X509Svid.parse(
x509SVID.getX509Svid().toByteArray(),
x509SVID.getX509SvidKey().toByteArray());
val svid = X509Svid.parseRaw(x509SVID.getX509Svid().toByteArray(), x509SVID.getX509SvidKey().toByteArray());
x509SvidList.add(svid);
if (!x509SVID.getSpiffeId().equals(svid.getSpiffeId().toString())) {

View File

@ -4,7 +4,11 @@ import io.grpc.Context;
import io.grpc.Status;
import io.grpc.stub.StreamObserver;
import io.spiffe.bundle.jwtbundle.JwtBundleSet;
import io.spiffe.exception.*;
import io.spiffe.exception.JwtBundleException;
import io.spiffe.exception.JwtSvidException;
import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.exception.X509ContextException;
import io.spiffe.exception.X509SvidException;
import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.svid.jwtsvid.JwtSvid;
import io.spiffe.workloadapi.grpc.SpiffeWorkloadAPIGrpc;

View File

@ -1,6 +1,13 @@
package io.spiffe.workloadapi.internal;
import io.grpc.*;
import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ClientInterceptor;
import io.grpc.ForwardingClientCall;
import io.grpc.ForwardingClientCallListener;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
/**
* ClientInterceptor implementation to add a security header required to connect to the Workload API.

View File

@ -9,7 +9,11 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class JwtBundleSetTest {

View File

@ -20,7 +20,11 @@ import java.security.KeyPair;
import java.security.PublicKey;
import java.util.HashMap;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class JwtBundleTest {

View File

@ -1,15 +1,18 @@
package io.spiffe.bundle.x509bundle;
import io.spiffe.exception.BundleNotFoundException;
import org.junit.jupiter.api.Test;
import io.spiffe.internal.DummyX509Certificate;
import io.spiffe.spiffeid.TrustDomain;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class X509BundleSetTest {

View File

@ -22,7 +22,11 @@ import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class X509BundleTest {

View File

@ -1,11 +1,12 @@
package io.spiffe.internal;
import com.nimbusds.jose.jwk.Curve;
import io.spiffe.Algorithm;
import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.TrustDomain;
import io.spiffe.utils.TestUtils;
import lombok.val;
import org.junit.jupiter.api.Test;
import io.spiffe.utils.TestUtils;
import java.io.IOException;
import java.net.URI;
@ -23,9 +24,11 @@ import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static io.spiffe.utils.X509CertificateTestUtils.createCertificate;
import static io.spiffe.utils.X509CertificateTestUtils.createRootCA;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
public class CertificateUtilsTest {
@ -71,7 +74,7 @@ public class CertificateUtilsTest {
val keyBytes = Files.readAllBytes(keyPath);
try {
PrivateKey privateKey = CertificateUtils.generatePrivateKey(keyBytes);
PrivateKey privateKey = CertificateUtils.generatePrivateKey(keyBytes, Algorithm.Family.RSA, KeyFileFormat.PEM);
assertNotNull(privateKey);
assertEquals("RSA", privateKey.getAlgorithm());
} catch (InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {
@ -85,7 +88,7 @@ public class CertificateUtilsTest {
byte[] keyBytes = ecKeyPair.getPrivate().getEncoded();
try {
PrivateKey privateKey = CertificateUtils.generatePrivateKey(keyBytes);
PrivateKey privateKey = CertificateUtils.generatePrivateKey(keyBytes, Algorithm.Family.EC, KeyFileFormat.DER);
assertNotNull(privateKey);
assertEquals("EC", privateKey.getAlgorithm());
} catch (InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) {

View File

@ -1,8 +1,17 @@
package io.spiffe.internal;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Set;

View File

@ -2,8 +2,17 @@ package io.spiffe.spiffeid;
import lombok.val;
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;
import static org.junit.jupiter.api.Assertions.*;
import java.util.stream.Stream;
import static io.spiffe.utils.TestUtils.getLongString;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SpiffeIdTest {
@ -109,80 +118,82 @@ public class SpiffeIdTest {
);
}
@Test
void parse_pathWithColons() {
val spiffeIdAsString = " spiffe://domain.test/pa:th/element: ";
val spiffeId = SpiffeId.parse(spiffeIdAsString);
assertAll("SpiffeId",
() -> assertEquals("domain.test", spiffeId.getTrustDomain().toString()),
() -> assertEquals("/pa:th/element:", spiffeId.getPath())
);
}
@Test
void parse_aStringContainingInvalidSchema_throwsIllegalArgumentException() {
val invalidadSpiffeId = "siffe://trust-domain.org/path1/path2";
void parse_pathWithAt() {
val spiffeIdAsString = "spiffe://domain.test/pa@th/element:";
val spiffeId = SpiffeId.parse(spiffeIdAsString);
assertAll("SpiffeId",
() -> assertEquals("domain.test", spiffeId.getTrustDomain().toString()),
() -> assertEquals("/pa@th/element:", spiffeId.getPath())
);
}
@Test
void parse_pathHasEncodedSubdelims() {
val spiffeIdAsString = "spiffe://domain.test/p!a$t&h'/(e)l*e+m,e;n=t";
val spiffeId = SpiffeId.parse(spiffeIdAsString);
assertAll("SpiffeId",
() -> assertEquals("domain.test", spiffeId.getTrustDomain().toString()),
() -> assertEquals("/p!a$t&h'/(e)l*e+m,e;n=t", spiffeId.getPath())
);
}
@Test
void parse_spiffeId_maxLength() {
val path = "/" + getLongString(2027);
val spiffeIdAsString = "spiffe://domain.test" + path;
val spiffeId = SpiffeId.parse(spiffeIdAsString);
assertAll("SpiffeId",
() -> assertEquals("domain.test", spiffeId.getTrustDomain().toString()),
() -> assertEquals(path, spiffeId.getPath())
);
}
@ParameterizedTest
@MethodSource("provideTestInvalidSpiffeIds")
void testParseTrustDomain(String input, Object expected) {
SpiffeId result;
try {
SpiffeId.parse(invalidadSpiffeId);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertEquals("Invalid SPIFFE schema", e.getMessage());
result = SpiffeId.parse(input);
assertEquals(expected, result.toString());
} catch (Exception e) {
assertEquals(expected, e.getMessage());
}
}
@Test
void parse_aBlankString_throwsIllegalArgumentException() {
try {
SpiffeId.parse("");
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertEquals("SPIFFE ID cannot be empty", e.getMessage());
}
static Stream<Arguments> provideTestInvalidSpiffeIds() {
return Stream.of(
Arguments.of("", "SPIFFE ID cannot be empty"),
Arguments.of("192.168.2.2:6688", "Illegal character in scheme name at index 0: 192.168.2.2:6688"),
Arguments.of("http://domain.test/path/element", "SPIFFE ID: invalid scheme"),
Arguments.of("spiffe:///path/element", "SPIFFE ID: trust domain is empty"),
Arguments.of("spiffe://domain.test/path/element?query=1", "SPIFFE ID: query is not allowed"),
Arguments.of("spiffe://domain.test/path/element?#fragment-1", "SPIFFE ID: fragment is not allowed"),
Arguments.of("spiffe://domain.test:8080/path/element", "SPIFFE ID: port is not allowed"),
Arguments.of("spiffe://user:password@test.org/path/element", "SPIFFE ID: user info is not allowed"),
Arguments.of("spiffe:path/element", "SPIFFE ID: trust domain is empty"),
Arguments.of("spiffe:/path/element", "SPIFFE ID: trust domain is empty"),
Arguments.of("spiffe://domain.test/path/elem%5uent", "Malformed escape pair at index 30: spiffe://domain.test/path/elem%5uent"),
Arguments.of("spiffe://domain.test/"+getLongString(2028), "SPIFFE ID: too long, maximum is 2048 bytes")
);
}
@Test
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");
} catch (NullPointerException e) {
assertEquals("trustDomain is marked non-null but is null", e.getMessage());
}
}
@Test
void equals_twoSpiffeIdsWithSameTrustDomainAndPath_returnsTrue() {
val spiffeId1 = SpiffeId.of(TrustDomain.of("example.org"), "path1");
val spiffeId2 = SpiffeId.of(TrustDomain.of("example.org"), "path1");
assertEquals(spiffeId1, spiffeId2);
}
@Test
void equals_twoSpiffeIdsWithSameTrustDomainAndDifferentPath_returnsFalse() {
val spiffeId1 = SpiffeId.of(TrustDomain.of("example.org"), "path1");
val spiffeId2 = SpiffeId.of(TrustDomain.of("example.org"), "other");
assertNotEquals(spiffeId1, spiffeId2);
}
@Test
void equals_twoSpiffeIdsWithDifferentTrustDomainAndSamePath_returnsFalse() {
val spiffeId1 = SpiffeId.of(TrustDomain.of("example.org"), "path1");
val spiffeId2 = SpiffeId.of(TrustDomain.of("other.org"), "path1");
assertNotEquals(spiffeId1, spiffeId2);
}
}

View File

@ -10,7 +10,9 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class SpiffeIdUtilsTest {

View File

@ -7,6 +7,7 @@ import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static io.spiffe.utils.TestUtils.getLongString;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TrustDomainTest {
@ -37,6 +38,12 @@ public class TrustDomainTest {
TrustDomain trustDomain = TrustDomain.of("test.domain");
assertEquals("test.domain", trustDomain.toString());
}
@Test
void testFromMaxLength() {
final String longString = getLongString(246); // 246 = 255(max) - 9('spiffe://' bytes)
TrustDomain trustDomain = TrustDomain.of(longString);
assertEquals(longString, trustDomain.toString());
}
@Test
void testGetName() {
@ -58,7 +65,8 @@ public class TrustDomainTest {
Arguments.of("://domain.test", "Expected scheme name at index 0: ://domain.test"),
Arguments.of("spiffe:///path/element", "Trust domain cannot be empty"),
Arguments.of("/path/element", "Trust domain cannot be empty"),
Arguments.of("spiffe://domain.test:80", "Port is not allowed")
Arguments.of("spiffe://domain.test:80", "Trust Domain: port is not allowed"),
Arguments.of(getLongString(256), "Trust Domain: too long, maximum is 255 bytes")
);
}
}

View File

@ -1,6 +1,8 @@
package io.spiffe.svid.x509svid;
import io.spiffe.exception.X509SvidException;
import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.TrustDomain;
import lombok.Builder;
import lombok.Value;
import org.junit.jupiter.api.Test;
@ -8,9 +10,8 @@ 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 io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.TrustDomain;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
@ -19,7 +20,9 @@ import java.nio.file.Paths;
import java.security.cert.X509Certificate;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
public class X509SvidTest {
@ -37,6 +40,8 @@ public class X509SvidTest {
static String certMultiple = "testdata/x509svid/good-leaf-and-intermediate.pem";
static String corrupted = "testdata/x509svid/corrupted";
static String keyECDSAOther = "testdata/x509svid/key-ecdsa-other.pem";
static String keyDER = "testdata/x509svid/keyEC.der";
static String certDER = "testdata/x509svid/cert.der";
static Stream<Arguments> provideX509SvidScenarios() {
return Stream.of(
@ -180,6 +185,22 @@ public class X509SvidTest {
}
}
@Test
void testParseRaw() throws URISyntaxException, IOException {
Path certPath = Paths.get(toUri(certDER));
Path keyPath = Paths.get(toUri(keyDER));
byte[] certBytes = Files.readAllBytes(certPath);
byte[] keyBytes = Files.readAllBytes(keyPath);
try {
X509Svid x509Svid = X509Svid.parseRaw(certBytes, keyBytes);
assertEquals("spiffe://example.org/workload-server", x509Svid.getSpiffeId().toString());
} catch (X509SvidException e) {
fail(e);
}
}
@Test
void testLoad_FailsCannotReadCertFile() throws URISyntaxException {
Path keyPath = Paths.get(toUri(keyRSA));

View File

@ -11,12 +11,19 @@ import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import java.lang.reflect.Field;
import java.security.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Stream.generate;
/**
* Util methods for generating KeyPairs, tokens, and other functionality used only to be used in testing.
*/
@ -96,6 +103,10 @@ public class TestUtils {
.build();
}
public static String getLongString(int nBytes) {
return generate(() -> "a").limit(nBytes).collect(joining());
}
public static void setEnvironmentVariable(String variableName, String value) throws Exception {
Class<?> processEnvironment = Class.forName("java.lang.ProcessEnvironment");

View File

@ -5,7 +5,13 @@ import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;

View File

@ -9,11 +9,11 @@ import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.stub.StreamObserver;
import io.spiffe.exception.JwtSvidException;
import org.junit.platform.commons.util.StringUtils;
import io.spiffe.svid.jwtsvid.JwtSvid;
import io.spiffe.utils.TestUtils;
import io.spiffe.workloadapi.grpc.SpiffeWorkloadAPIGrpc.SpiffeWorkloadAPIImplBase;
import io.spiffe.workloadapi.grpc.Workload;
import org.junit.platform.commons.util.StringUtils;
import java.io.IOException;
import java.net.URI;
@ -22,13 +22,18 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
class FakeWorkloadApi extends SpiffeWorkloadAPIImplBase {
final String privateKey = "testdata/workloadapi/svid.key";
final String svid = "testdata/workloadapi/svid.pem";
final String x509Bundle = "testdata/workloadapi/bundle.pem";
final String privateKey = "testdata/workloadapi/svid.key.der";
final String svid = "testdata/workloadapi/svid.der";
final String x509Bundle = "testdata/workloadapi/bundle.der";
final String jwtBundle = "testdata/workloadapi/bundle.json";

View File

@ -24,7 +24,9 @@ import io.spiffe.workloadapi.internal.SecurityHeaderInterceptor;
import java.io.IOException;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class JwtSourceTest {

View File

@ -6,33 +6,39 @@ import io.grpc.Server;
import io.grpc.inprocess.InProcessChannelBuilder;
import io.grpc.inprocess.InProcessServerBuilder;
import io.grpc.testing.GrpcCleanupRule;
import io.spiffe.bundle.jwtbundle.JwtBundle;
import io.spiffe.bundle.jwtbundle.JwtBundleSet;
import io.spiffe.bundle.x509bundle.X509Bundle;
import io.spiffe.exception.BundleNotFoundException;
import io.spiffe.exception.JwtBundleException;
import io.spiffe.exception.JwtSvidException;
import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.spiffeid.SpiffeId;
import io.spiffe.spiffeid.TrustDomain;
import org.junit.Rule;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import io.spiffe.bundle.jwtbundle.JwtBundle;
import io.spiffe.bundle.jwtbundle.JwtBundleSet;
import io.spiffe.bundle.x509bundle.X509Bundle;
import io.spiffe.svid.jwtsvid.JwtSvid;
import io.spiffe.utils.TestUtils;
import io.spiffe.workloadapi.grpc.SpiffeWorkloadAPIGrpc;
import io.spiffe.workloadapi.internal.ManagedChannelWrapper;
import io.spiffe.workloadapi.internal.SecurityHeaderInterceptor;
import io.spiffe.workloadapi.retry.BackoffPolicy;
import org.junit.Rule;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.security.KeyPair;
import java.util.*;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class WorkloadApiClientTest {

View File

@ -22,7 +22,9 @@ import io.spiffe.workloadapi.internal.SecurityHeaderInterceptor;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class X509SourceTest {

View File

@ -4,7 +4,9 @@ import org.junit.jupiter.api.Test;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class BackoffPolicyTest {

Binary file not shown.

View File

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBjjCCATSgAwIBAgIBADAKBggqhkjOPQQDAjAeMQswCQYDVQQGEwJVUzEPMA0G
A1UEChMGU1BJRkZFMB4XDTIwMDUxNjE3MDUyNFoXDTIwMDUyMzE3MDUzNFowHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABCQyshZ+HhyfaordIzoupU4qFd07uTRNysO6z9i0WMGzhIAA06z6JXat
rFBsHJYXbmuXp9afh+Ivr/RcGHj08PSjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBToJDrI0vnnlhn7EmooEWe43+hPajAfBgNV
HREEGDAWhhRzcGlmZmU6Ly9leGFtcGxlLm9yZzAKBggqhkjOPQQDAgNIADBFAiEA
+mM9GONpM1L6QYw8c+IvWgXgr+aGoOVpmo0wWcZbc7oCIBiF1NN8p5DeU12wxoUy
ycQCammceo4hcYLQAYGi/5Q5
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBjjCCATSgAwIBAgIBADAKBggqhkjOPQQDAjAeMQswCQYDVQQGEwJVUzEPMA0G
A1UEChMGU1BJRkZFMB4XDTIwMDUyMDE3MDc1N1oXDTIwMDUyNzE3MDgwN1owHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABO3/qXKapLzDi3wgqW8Lkjm35WrJclRr8aN7IF8Px2jeJpV4KG+wdLa7
rXSOJH8xCotu9QnQcGo4FuinMsJPlZKjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQEOa83CNDa8BcLL/mU3ep//rxyNjAfBgNV
HREEGDAWhhRzcGlmZmU6Ly9leGFtcGxlLm9yZzAKBggqhkjOPQQDAgNIADBFAiBC
RTRaKR1nphUMjFcLfopHk+VJgB97yZ8TEZRlNF8vLQIhAJchfcPmlOk9OFiAnSoU
th2m6yJcLC3axw94n1fg0qcd
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBjjCCATSgAwIBAgIBADAKBggqhkjOPQQDAjAeMQswCQYDVQQGEwJVUzEPMA0G
A1UEChMGU1BJRkZFMB4XDTIwMDUyNTExNDEyMVoXDTIwMDYwMTExNDEzMVowHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTBZMBMGByqGSM49AgEGCCqGSM49
AwEHA0IABAED6MJ6JluKjEVjKiOP8gPgcqxdJpQKI7iJLDTTd8Ums1/bXTvUxQXG
PmMcqYAtEvTgs1ew/FDSh5L8XNvaghWjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQtAHWFv+CwKHD7G/VNm6oke6CTtTAfBgNV
HREEGDAWhhRzcGlmZmU6Ly9leGFtcGxlLm9yZzAKBggqhkjOPQQDAgNIADBFAiAn
VJkxslbz+KJMvsenGo9id3FllKxK1edi2gdyQay62gIhANK6B1ExwDYzUOB5KQUH
XZg4m88DL41Jn2b6k+fQggVh
-----END CERTIFICATE-----

Binary file not shown.

View File

@ -1,5 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg+p4+LW7wmMYquxWg
Z75Bwl5dA+mIrfSRbD2+gQuZkuehRANCAASFtDAPsZg187ijRjpKPv78HfshnAVx
rgdoCkxIs3OgoPPVULfvPslALF3sWQrLUxzIk33dQ/P46o9LsweBN2Hs
-----END PRIVATE KEY-----

View File

@ -1,13 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIB6zCCAZKgAwIBAgIRANwM7+XYWJtefDH9WtDULHkwCgYIKoZIzj0EAwIwHjEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBlNQSUZGRTAeFw0yMDA1MjYwODI1MjlaFw0y
MDA1MjYwOTI1MzlaMB0xCzAJBgNVBAYTAlVTMQ4wDAYDVQQKEwVTUElSRTBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABIW0MA+xmDXzuKNGOko+/vwd+yGcBXGuB2gK
TEizc6Cg89VQt+8+yUAsXexZCstTHMiTfd1D8/jqj0uzB4E3YeyjgbEwga4wDgYD
VR0PAQH/BAQDAgOoMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNV
HRMBAf8EAjAAMB0GA1UdDgQWBBQ+TzaTKiKtWiSN5vya0vck9T8OfjAfBgNVHSME
GDAWgBQEOa83CNDa8BcLL/mU3ep//rxyNjAvBgNVHREEKDAmhiRzcGlmZmU6Ly9l
eGFtcGxlLm9yZy93b3JrbG9hZC1zZXJ2ZXIwCgYIKoZIzj0EAwIDRwAwRAIgQEcc
FThD3vJxp6QpOGIJaWxxSF3B2JqF4A2nc0M3Vz8CICYg750Fw8GCr0K8+Ip5dAcV
0k1Or5t/ev63uOGy9oIz
-----END CERTIFICATE-----

Binary file not shown.

Binary file not shown.

View File

@ -5,7 +5,12 @@ import io.spiffe.helper.keystore.KeyStoreHelper;
import io.spiffe.helper.keystore.KeyStoreType;
import lombok.extern.java.Log;
import lombok.val;
import org.apache.commons.cli.*;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;

View File

@ -14,9 +14,9 @@ import java.nio.file.Paths;
class FakeWorkloadApi extends SpiffeWorkloadAPIImplBase {
final String privateKey = "testdata/svid.key";
final String svid = "testdata/svid.pem";
final String x509Bundle = "testdata/bundle.pem";
final String privateKey = "testdata/svid.key.der";
final String svid = "testdata/svid.der";
final String x509Bundle = "testdata/bundle.der";
// Loads cert, bundle and key from files and generates a X509SVIDResponse.

View File

@ -30,7 +30,9 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
class KeyStoreHelperTest {

View File

@ -25,7 +25,10 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
public class KeyStoreTest {

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -17,7 +17,9 @@ import java.nio.file.Paths;
import java.security.cert.CertificateException;
import static io.spiffe.provider.SpiffeProviderConstants.DEFAULT_ALIAS;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.when;
public class SpiffeKeyManagerTest {

View File

@ -2,10 +2,14 @@ package io.spiffe.provider.examples.mtls;
import io.spiffe.exception.SocketEndpointAddressException;
import io.spiffe.exception.X509SourceException;
import io.spiffe.provider.*;
import io.spiffe.provider.SpiffeKeyManager;
import io.spiffe.provider.SpiffeProviderException;
import io.spiffe.provider.SpiffeSslContextFactory;
import io.spiffe.provider.SpiffeSslContextFactory.SslContextOptions;
import io.spiffe.provider.SpiffeTrustManager;
import io.spiffe.provider.X509SourceManager;
import io.spiffe.workloadapi.X509Source;
import lombok.val;
import io.spiffe.provider.SpiffeSslContextFactory.SslContextOptions;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;

View File

@ -7,7 +7,12 @@ import lombok.extern.java.Log;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.security.cert.X509Certificate;
import java.util.logging.Level;