/** * Create an instance of {@link KeyConfig} based on this builder. * * @return new key config based on a keystore */ @Override public KeyConfig build() { return toFullBuilder().build(); }
/** * Create a builder for {@link KeyConfig} from this keystore builder. This allows you to enhance the config * with additional (explicit) fields. * * @return builder of {@link KeyConfig} */ public Builder toFullBuilder() { return updateBuilder(KeyConfig.fullBuilder()); }
/** * Build {@link KeyConfig} based on information from PEM files only. * * @return new instance configured from this builder */ @Override public KeyConfig build() { return toFullBuilder().build(); }
static Optional<PrivateKey> resolvePrivateKey(Config config) { KeyConfig.PemBuilder pemBuilder = KeyConfig.pemBuilder().config(config); KeyConfig.KeystoreBuilder keystoreBuilder = KeyConfig.keystoreBuilder().config(config); .ifPresent(path -> pemBuilder.key(Resource.create(path))); .ifPresent(path -> keystoreBuilder.keystore(Resource.create(path))); .ifPresent(keystoreBuilder::keyAlias); Optional<PrivateKey> result = KeyConfig.fullBuilder() .updateWith(pemBuilder) .updateWith(keystoreBuilder) .build() .privateKey();
/** * Updated this builder instance from configuration. * Keys configured will override existing fields in this builder, others will be left intact. * If certification path is already defined, configuration based cert-path will be added. * * @param config configuration to update this builder from * @return updated builder instance */ public Builder config(Config config) { updateWith(pemBuilder().config(config)); updateWith(keystoreBuilder().config(config)); return this; } }
/** * Load key config from config. * * @param config config instance located at keys configuration (expects "keystore-path" child) * @return KeyConfig loaded from config * @throws PkiException when keys or certificates fail to load from keystore or when misconfigured */ public static KeyConfig create(Config config) throws PkiException { try { return fullBuilder().config(config).build(); } catch (ResourceException e) { throw new PkiException("Failed to load from config", e); } }
private Builder updateBuilder(Builder builder) { if (privateKeyStream.isSet()) { builder.privateKey(PemReader.readPrivateKey(privateKeyStream.stream(), pemKeyPassphrase)); } if (publicKeyStream.isSet()) { builder.publicKey(PemReader.readPublicKey(publicKeyStream.stream())); } if (certChainStream.isSet()) { List<X509Certificate> chain = PemReader.readCertificates(certChainStream.stream()); chain.forEach(builder::addCertChain); if (!chain.isEmpty()) { builder.publicKeyCert(chain.get(0)); } } return builder; }
/** * Get a builder filled from this builder to add additional information (such as public key from certificate etc.). * * @return builder for {@link KeyConfig} */ public Builder toFullBuilder() { return updateBuilder(KeyConfig.fullBuilder()); }
static PrivateKey readPrivateKey(InputStream input, char[] password) { byte[] pkBytes = readPrivateKeyBytes(input); PKCS8EncodedKeySpec keySpec = generateKeySpec(pkBytes, password); try { return KeyFactory.getInstance("RSA").generatePrivate(keySpec); } catch (Exception ignore) { try { return KeyFactory.getInstance("DSA").generatePrivate(keySpec); } catch (Exception ignore2) { try { return KeyFactory.getInstance("EC").generatePrivate(keySpec); } catch (Exception e) { throw new PkiException("Failed to get private key. It is not RSA, DSA or EC.", e); } } } }
static PublicKey readPublicKey(InputStream input) { byte[] pkBytes = readPublicKeyBytes(input); X509EncodedKeySpec keySpec = generatePublicKeySpec(pkBytes); try { return KeyFactory.getInstance("RSA").generatePublic(keySpec); } catch (Exception ignore) { try { return KeyFactory.getInstance("DSA").generatePublic(keySpec); } catch (Exception ignore2) { try { return KeyFactory.getInstance("EC").generatePublic(keySpec); } catch (Exception e) { throw new PkiException("Failed to get public key. It is not RSA, DSA or EC.", e); } } } }
/** * For algorithms based on public/private key (such as rsa-sha256), this provides access to the public key of the client. * * @param keyConfig keys configured to access a public key to validate signature * @return updated builder instance */ public Builder publicKeyConfig(KeyConfig keyConfig) { if (null == algorithm) { algorithm = HttpSignProvider.ALGORITHM_RSA; } // make sure this is a public key (validation of inbound signatures) keyConfig.publicKey() .orElseThrow(() -> new HttpSignatureException("Configuration must contain a public key")); this.keyConfig = keyConfig; return this; }
static PrivateKey loadPrivateKey(KeyStore keyStore, String keyAlias, char[] keyPassphrase) { try { Key key = keyStore.getKey(keyAlias, keyPassphrase); if (key instanceof PrivateKey) { return (PrivateKey) key; } throw new PkiException("Key stored under alias " + keyAlias + " is not a private key, but: " + key); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) { throw new PkiException("Failed to load private key under alias " + keyAlias, e); } }
/** * Creates a new builder to configure instance. * * @return builder instance */ public static Builder fullBuilder() { return new Builder(); }
/** * If you want to build a trust store, call this method to add all * certificates present in the keystore to certificate list. * * @return updated builder instance */ public KeystoreBuilder trustStore() { return trustStore(true); }
/** * Build this instance from a java keystore (such as PKCS12 keystore). * Call {@link KeystoreBuilder#build()} to build the instance. * If you need to add additional information to {@link KeyConfig}, use {@link PemBuilder#toFullBuilder()}. * * @return builder for Keystore */ public static KeystoreBuilder keystoreBuilder() { return new KeystoreBuilder(); }
/** * Build this instance from PEM files (usually a pair of private key and certificate chain). * Call {@link PemBuilder#build()} to build the instance. * If you need to add additional information to {@link KeyConfig}, use {@link PemBuilder#toFullBuilder()}. * * @return builder for PEM files */ public static PemBuilder pemBuilder() { return new PemBuilder(); }
private void stream(Resource resource) { closeStream(); Objects.requireNonNull(resource, "Resource for \"" + message + "\" must not be null"); this.inputStream = resource.stream(); this.message = message + ":" + resource.sourceType() + ":" + resource.location(); }
static X509Certificate loadCertificate(KeyStore keyStore, String certAlias) { try { Certificate certificate = keyStore.getCertificate(certAlias); if (null == certificate) { throw new PkiException("There is no X.509 certificate under alias " + certAlias); } if (certificate instanceof X509Certificate) { return (X509Certificate) certificate; } throw new PkiException("Certificate under alias " + certAlias + " is not an X.509 certificate, but: " + certificate); } catch (KeyStoreException e) { throw new PkiException("Failed to load certificate under alias " + certAlias, e); } }
static KeyStore loadKeystore(String keystoreType, InputStream storeStream, char[] keystorePassphrase, String message) { Objects.requireNonNull(storeStream, "Keystore input stream must not be null"); try { KeyStore ks = KeyStore.getInstance(keystoreType); ks.load(storeStream, keystorePassphrase); return ks; } catch (Exception e) { throw new PkiException("Failed to read " + keystoreType + " keystore: " + message, e); } }
static List<X509Certificate> loadCertChain(KeyStore keyStore, String certAlias) { try { Certificate[] certificates = keyStore.getCertificateChain(certAlias); if (null == certificates) { throw new PkiException("There is no X.509 certificate chain under alias " + certAlias); } return Stream.of(certificates).map(it -> (X509Certificate) it).collect(Collectors.toList()); } catch (KeyStoreException e) { throw new PkiException("Failed to load certificate under alias " + certAlias, e); } }