/** * Private key configuration for RSA based algorithms. * If called sets the algorithm to "rsa-sha256". Expects either explicit private key, or keystore and private key * alias. * * @param keyConfig private key configuration for outbound signatures * @return updated builder instance */ public Builder privateKeyConfig(KeyConfig keyConfig) { if (null == algorithm) { algorithm = HttpSignProvider.ALGORITHM_RSA; } // make sure this is a private key (signature of outbound requests) keyConfig.privateKey() .orElseThrow(() -> new HttpSignatureException("Configuration must contain a private key")); this.keyConfig = keyConfig; return this; }
private static KeyManagerFactory buildKmf(KeyConfig privateKeyConfig) throws IOException, GeneralSecurityException { String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); if (algorithm == null) { algorithm = "SunX509"; } byte[] passwordBytes = new byte[64]; RANDOM.nextBytes(passwordBytes); char[] password = Base64.getEncoder().encodeToString(passwordBytes).toCharArray(); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(null, null); ks.setKeyEntry("key", privateKeyConfig.privateKey().orElseThrow(() -> new RuntimeException("Private key not available")), password, privateKeyConfig.certChain().toArray(new Certificate[0])); KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); kmf.init(ks, password); return kmf; }
private byte[] signRsaSha256(SecurityEnvironment env, KeyConfig keyConfig, Map<String, List<String>> newHeaders) { try { Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(keyConfig.privateKey().orElseThrow(() -> new HttpSignatureException( "Private key is required, yet not " + "configured"))); signature.update(getBytesToSign(env, newHeaders)); return signature.sign(); } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) { throw new HttpSignatureException(e); } }
.updateWith(keystoreBuilder) .build() .privateKey();
private EncryptionFilter(Builder builder, Config config) { if (builder.fromConfig) { this.requireEncryption = OptionalHelper.from(EncryptionUtil.getEnv(ConfigProperties.REQUIRE_ENCRYPTION_ENV_VARIABLE) .map(Boolean::parseBoolean)) .or(() -> config.get(ConfigProperties.REQUIRE_ENCRYPTION_CONFIG_KEY).asBoolean().asOptional()) .asOptional() .orElse(true); this.masterPassword = EncryptionUtil.resolveMasterPassword(requireEncryption, config).orElse(null); this.privateKey = EncryptionUtil.resolvePrivateKey(config.get("security.config.rsa")) .orElse(null); } else { this.requireEncryption = builder.requireEncryption; this.privateKey = builder.privateKeyConfig.privateKey() .orElseThrow(() -> new ConfigEncryptionException("Private key configuration is invalid")); this.masterPassword = builder.masterPassword; } if (null != privateKey && !(privateKey instanceof RSAPrivateKey)) { throw new ConfigEncryptionException("Private key must be an RSA private key, but is: " + privateKey.getClass().getName()); } ConfigFilter noOp = (key, stringValue) -> stringValue; aesFilter = (null == masterPassword ? noOp : (key, stringValue) -> decryptAes(masterPassword, stringValue)); rsaFilter = (null == privateKey ? noOp : (key, stringValue) -> decryptRsa(privateKey, stringValue)); clearFilter = this::clearText; aliasFilter = (key, stringValue) -> aliased(stringValue, config); }
.updateWith(keystoreBuilder) .build() .privateKey();
private EncryptionFilter(Builder builder, Config config) { if (builder.fromConfig) { this.requireEncryption = OptionalHelper.from(EncryptionUtil.getEnv(ConfigProperties.REQUIRE_ENCRYPTION_ENV_VARIABLE) .map(Boolean::parseBoolean)) .or(() -> config.get(ConfigProperties.REQUIRE_ENCRYPTION_CONFIG_KEY).asBoolean().asOptional()) .asOptional() .orElse(true); this.masterPassword = EncryptionUtil.resolveMasterPassword(requireEncryption, config).orElse(null); this.privateKey = EncryptionUtil.resolvePrivateKey(config.get("security.config.rsa")) .orElse(null); } else { this.requireEncryption = builder.requireEncryption; this.privateKey = builder.privateKeyConfig.privateKey() .orElseThrow(() -> new ConfigEncryptionException("Private key configuration is invalid")); this.masterPassword = builder.masterPassword; } if (null != privateKey && !(privateKey instanceof RSAPrivateKey)) { throw new ConfigEncryptionException("Private key must be an RSA private key, but is: " + privateKey.getClass().getName()); } ConfigFilter noOp = (key, stringValue) -> stringValue; aesFilter = (null == masterPassword ? noOp : (key, stringValue) -> decryptAes(masterPassword, stringValue)); rsaFilter = (null == privateKey ? noOp : (key, stringValue) -> decryptRsa(privateKey, stringValue)); clearFilter = this::clearText; aliasFilter = (key, stringValue) -> aliased(stringValue, config); }