diff --git a/README.md b/README.md index 294c406..8698994 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,53 @@ to get the X509-SVIDS whenever the Workload API has a new SVID to push. The gRPC channel is configured based on the Address (tcp or unix socket) and the OS detected. +### Build the JAR + +To create a fat JAR file that includes all the dependencies: + +``` + $ ./gradlew build + + BUILD SUCCESSFUL in 2s +``` + +In folder `build/libs` there will be a file `spiffe-provider--all.jar`. + + +To create a slim JAR file: + +``` + $ ./gradle jar + BUILD SUCCESSFUL in 1s +``` + +In folder `build/libs` there will be a file `spiffe-provider-.jar`. + + ### Use +The library provides a `SpiffeIdManager` that abstracts low level details related to the interaction with the WorkloadAPI and exposes +getter methods to obtain the SVID, Bundle and Key: + +``` +SpiffeIdManager spiffeIdManager = SpiffeIdManager.getInstance(); + +PrivateKey privateKey = spiffeIdManager.getPrivateKey(); +X509Certificate svid = spiffeIdManager.getCertificate(); +Set bundle = spiffeIdManager.TrustedCerts(); +``` + +The `SpiffeIdManager` gets the certificate updates automatically from the WorkloadAPI. + +It uses a `X509SVIDFetcher` that handles the interaction with the WorkloadAPI. + +The path to the Socket where the Workload API is listening needs to configured either by setting the system property `-Dspiffe.endpoint.socket` or +or an the environment variable `SPIFFE_ENDPOINT_SOCKET`. + + +Another way to use the library is by directly instantiating the `X509SVIDFetcher` and registering a callback (aka Consumer) +that will be invoked whenever there is an update pushed by the Workload API: + ``` Fetcher svidFetcher = new X509SVIDFetcher("/tmp/agent.sock"); @@ -39,6 +84,9 @@ Consumer xvidConsumer = x509SVIDResponse -> { svidFetcher.registerListener(xvidConsumer); ``` +In this case the path to the Socket is passed through a parameter in the constructor. If the parameter is not provided, it will +use the system property, if it is defined, or the environment variable. If neither is defined, it will throw an Exception. + The `X509SVIDFetcher` can be configured with a custom `RetryPolicy`. By default it uses a `RetryPolicy` with the following parameters: @@ -55,18 +103,18 @@ maxRetries = UNLIMITED_RETRIES; ### Install the SPIFFE Provider JAR -Generate the JAR: +Generate the JAR that includes all dependencies: ``` ./gradlew build ``` For installing the JAR file containing the provider classes as a bundled extension in the java platform, copy -`build/libs/spiffe-provider-0.1.0.jar` to `/jre/lib/ext` +`build/libs/spiffe-provider--all.jar` to `/jre/lib/ext` ### Configure `java.security` -Java Security Providers are configured in the master security properties file `/lib/security/java.security`. +Java Security Providers are configured in the master security properties file `/jre/lib/security/java.security`. The way to register a provider is to specify the Provider subclass name and priority in the format diff --git a/build.gradle b/build.gradle index d3a64ef..4aac64c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,5 @@ group 'spiffe' -version '0.3.0' - +version '0.4.0' buildscript { repositories { @@ -8,39 +7,44 @@ buildscript { jcenter() } + ext.protobufPluginVersion = '0.8.7' + ext.shadowPluginVersion = '4.0.3' + dependencies { - classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5" - classpath "com.github.jengelman.gradle.plugins:shadow:2.0.4" + classpath group: 'com.google.protobuf', name: 'protobuf-gradle-plugin', version: "${protobufPluginVersion}" + classpath group: 'com.github.jengelman.gradle.plugins', name: 'shadow', version: "${shadowPluginVersion}" } } -apply plugin: 'java' -apply plugin: "com.github.johnrengelman.shadow" -apply plugin: "com.google.protobuf" +ext { + grpcVersion = '1.17.1' + nettyVersion = '4.1.32.Final' + protobufProtocVersion = '3.6.1' + apacheCommonsVersion = '3.8.1' +} + +apply plugin: 'java-library' +apply plugin: 'com.github.johnrengelman.shadow' +apply plugin: 'com.google.protobuf' assemble.dependsOn shadowJar shadowJar { - classifier = null -} - -ext { - grpcVersion = "1.12.0" - nettyVersion = "4.1.25.Final" + classifier = "all" } sourceSets { main { java { - srcDirs "build/generated/source/proto/main/grpc" - srcDirs "build/generated/source/proto/main/java" + srcDirs 'build/generated/source/proto/main/grpc' + srcDirs 'build/generated/source/proto/main/java' } } } protobuf { protoc { - artifact = "com.google.protobuf:protoc:3.5.1" + artifact = "com.google.protobuf:protoc:${protobufProtocVersion}" } plugins { grpc { @@ -62,11 +66,11 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { - compile "io.grpc:grpc-netty:${grpcVersion}" - compile "io.grpc:grpc-protobuf:${grpcVersion}" - compile "io.grpc:grpc-stub:${grpcVersion}" - compile "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64" - compile "io.netty:netty-transport-native-kqueue:${nettyVersion}:osx-x86_64" - compile "org.apache.commons:commons-lang3:3.7" + implementation group: 'io.grpc', name: 'grpc-netty', version: "${grpcVersion}" + implementation group: 'io.grpc', name: 'grpc-protobuf', version: "${grpcVersion}" + implementation group: 'io.grpc', name: 'grpc-stub', version: "${grpcVersion}" + implementation group: 'io.netty', name: 'netty-transport-native-epoll', version: "${nettyVersion}", classifier: 'linux-x86_64' + implementation group: 'io.netty', name: 'netty-transport-native-kqueue', version: "${nettyVersion}", classifier: 'osx-x86_64' + implementation group: 'org.apache.commons', name: 'commons-lang3', version: "${apacheCommonsVersion}" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5006427..d02e11e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-all.zip diff --git a/src/main/java/spiffe/provider/SpiffeProvider.java b/src/main/java/spiffe/provider/SpiffeProvider.java index 0f0e139..a0b5584 100644 --- a/src/main/java/spiffe/provider/SpiffeProvider.java +++ b/src/main/java/spiffe/provider/SpiffeProvider.java @@ -24,9 +24,20 @@ public class SpiffeProvider extends Provider { * */ public SpiffeProvider() { - super(PROVIDER_NAME, 0.1, "SPIFFE based KeyStore and TrustStore"); + super(PROVIDER_NAME, 0.4, "SPIFFE based KeyStore and TrustStore"); super.put(SPIFFE_KEY_MANAGER_FACTORY, SpiffeKeyManagerFactory.class.getName()); super.put(SPIFFE_TRUST_MANAGER_FACTORY, SpiffeTrustManagerFactory.class.getName()); super.put(SPIFFE_KEYSTORE, SpiffeKeyStore.class.getName()); } + + + /** + * Install this provider + * + */ + public static void install() { + if (Security.getProvider(PROVIDER_NAME) == null) { + Security.addProvider(new SpiffeProvider()); + } + } } diff --git a/src/main/java/spiffe/provider/SpiffeProviderConstants.java b/src/main/java/spiffe/provider/SpiffeProviderConstants.java index 115733f..1ecf23c 100644 --- a/src/main/java/spiffe/provider/SpiffeProviderConstants.java +++ b/src/main/java/spiffe/provider/SpiffeProviderConstants.java @@ -1,10 +1,10 @@ package spiffe.provider; -class SpiffeProviderConstants { +public class SpiffeProviderConstants { - static final String PROVIDER_NAME = "Spiffe"; + public static final String PROVIDER_NAME = "Spiffe"; + public static final String ALGORITHM = "Spiffe"; static final String PUBLIC_KEY_INFRASTRUCTURE_ALGORITHM = "PKIX"; static final String X509_CERTIFICATE_TYPE = "X.509"; - static final String ALGORITHM = "Spiffe"; static final String ALIAS = "Spiffe"; }