From 9d27c8df1f0e11f314b58d21d2369d7331c13748 Mon Sep 17 00:00:00 2001 From: Harald Musum Date: Fri, 19 Oct 2018 12:07:23 +0200 Subject: Revert "Move classes in com.yahoo.security to security-utils" --- .../yahoo/security/BasicConstraintsExtension.java | 14 -- .../yahoo/security/BouncyCastleProviderHolder.java | 14 -- .../main/java/com/yahoo/security/Extension.java | 22 --- .../main/java/com/yahoo/security/KeyAlgorithm.java | 20 --- .../java/com/yahoo/security/KeyStoreBuilder.java | 121 --------------- .../main/java/com/yahoo/security/KeyStoreType.java | 23 --- .../java/com/yahoo/security/KeyStoreUtils.java | 34 ----- .../src/main/java/com/yahoo/security/KeyUtils.java | 129 ---------------- .../main/java/com/yahoo/security/Pkcs10Csr.java | 71 --------- .../java/com/yahoo/security/Pkcs10CsrBuilder.java | 106 ------------- .../java/com/yahoo/security/Pkcs10CsrUtils.java | 38 ----- .../com/yahoo/security/SignatureAlgorithm.java | 22 --- .../java/com/yahoo/security/SslContextBuilder.java | 137 ----------------- .../com/yahoo/security/SubjectAlternativeName.java | 114 -------------- .../com/yahoo/security/X509CertificateBuilder.java | 167 --------------------- .../com/yahoo/security/X509CertificateUtils.java | 136 ----------------- .../main/java/com/yahoo/security/package-info.java | 9 -- .../security/tls/TransportSecurityOptions.java | 90 ----------- .../yahoo/security/tls/TransportSecurityUtils.java | 66 -------- .../java/com/yahoo/security/tls/package-info.java | 8 - 20 files changed, 1341 deletions(-) delete mode 100644 security-utils/src/main/java/com/yahoo/security/BasicConstraintsExtension.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/BouncyCastleProviderHolder.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/Extension.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/KeyAlgorithm.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/KeyStoreBuilder.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/KeyStoreType.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/KeyStoreUtils.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/KeyUtils.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/Pkcs10CsrBuilder.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/Pkcs10CsrUtils.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/SignatureAlgorithm.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/SubjectAlternativeName.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/X509CertificateBuilder.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/X509CertificateUtils.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/package-info.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptions.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java delete mode 100644 security-utils/src/main/java/com/yahoo/security/tls/package-info.java (limited to 'security-utils/src/main/java') diff --git a/security-utils/src/main/java/com/yahoo/security/BasicConstraintsExtension.java b/security-utils/src/main/java/com/yahoo/security/BasicConstraintsExtension.java deleted file mode 100644 index d3c08ba27d0..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/BasicConstraintsExtension.java +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -/** - * @author bjorncs - */ -class BasicConstraintsExtension { - final boolean isCritical, isCertAuthorityCertificate; - - BasicConstraintsExtension(boolean isCritical, boolean isCertAuthorityCertificate) { - this.isCritical = isCritical; - this.isCertAuthorityCertificate = isCertAuthorityCertificate; - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/BouncyCastleProviderHolder.java b/security-utils/src/main/java/com/yahoo/security/BouncyCastleProviderHolder.java deleted file mode 100644 index 48a23a1fe7e..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/BouncyCastleProviderHolder.java +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -/** - * @author bjorncs - */ -class BouncyCastleProviderHolder { - - private static final BouncyCastleProvider bcProvider = new BouncyCastleProvider(); - - static BouncyCastleProvider getInstance() { return bcProvider; } -} diff --git a/security-utils/src/main/java/com/yahoo/security/Extension.java b/security-utils/src/main/java/com/yahoo/security/Extension.java deleted file mode 100644 index 46b781c9c86..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/Extension.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; - -/** - * @author bjorncs - */ -public enum Extension { - BASIC_CONSTRAINTS(org.bouncycastle.asn1.x509.Extension.basicConstraints), - SUBJECT_ALTERNATIVE_NAMES(org.bouncycastle.asn1.x509.Extension.subjectAlternativeName); - - final ASN1ObjectIdentifier extensionOId; - - Extension(ASN1ObjectIdentifier extensionOId) { - this.extensionOId = extensionOId; - } - - public String getOId() { - return extensionOId.getId(); - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/KeyAlgorithm.java b/security-utils/src/main/java/com/yahoo/security/KeyAlgorithm.java deleted file mode 100644 index 3218f81f0d6..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/KeyAlgorithm.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -/** - * @author bjorncs - */ -public enum KeyAlgorithm { - RSA("RSA"), - EC("EC"); - - final String algorithmName; - - KeyAlgorithm(String algorithmName) { - this.algorithmName = algorithmName; - } - - String getAlgorithmName() { - return algorithmName; - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/KeyStoreBuilder.java b/security-utils/src/main/java/com/yahoo/security/KeyStoreBuilder.java deleted file mode 100644 index 2160fbf6455..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/KeyStoreBuilder.java +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; - -import static java.util.Collections.singletonList; - -/** - * @author bjorncs - */ -public class KeyStoreBuilder { - - private final List keyEntries = new ArrayList<>(); - private final List certificateEntries = new ArrayList<>(); - - private final KeyStoreType keyStoreType; - private Path inputFile; - private char[] inputFilePassword; - - private KeyStoreBuilder(KeyStoreType keyStoreType) { - this.keyStoreType = keyStoreType; - } - - public static KeyStoreBuilder withType(KeyStoreType type) { - return new KeyStoreBuilder(type); - } - - public KeyStoreBuilder fromFile(Path file, char[] password) { - this.inputFile = file; - this.inputFilePassword = password; - return this; - } - - public KeyStoreBuilder fromFile(Path file) { - return fromFile(file, null); - } - - public KeyStoreBuilder withKeyEntry(String alias, PrivateKey privateKey, char[] password, List certificateChain) { - keyEntries.add(new KeyEntry(alias, privateKey, certificateChain, password)); - return this; - } - - public KeyStoreBuilder withKeyEntry(String alias, PrivateKey privateKey, char[] password, X509Certificate certificate) { - return withKeyEntry(alias, privateKey, password, singletonList(certificate)); - } - - public KeyStoreBuilder withKeyEntry(String alias, PrivateKey privateKey, X509Certificate certificate) { - return withKeyEntry(alias, privateKey, null, certificate); - } - - public KeyStoreBuilder withKeyEntry(String alias, PrivateKey privateKey, List certificateChain) { - return withKeyEntry(alias, privateKey, null, certificateChain); - } - - public KeyStoreBuilder withCertificateEntry(String alias, X509Certificate certificate) { - certificateEntries.add(new CertificateEntry(alias, certificate)); - return this; - } - - public KeyStore build() { - try { - KeyStore keystore = this.keyStoreType.createKeystore(); - if (this.inputFile != null) { - try (InputStream in = new BufferedInputStream(Files.newInputStream(this.inputFile))) { - keystore.load(in, this.inputFilePassword); - } - } else { - keystore.load(null); - } - for (KeyEntry entry : keyEntries) { - char[] password = entry.password != null ? entry.password : new char[0]; - Certificate[] certificateChain = entry.certificateChain.toArray(new Certificate[entry.certificateChain.size()]); - keystore.setKeyEntry(entry.alias, entry.privateKey, password, certificateChain); - } - for (CertificateEntry entry : certificateEntries) { - keystore.setCertificateEntry(entry.alias, entry.certificate); - } - return keystore; - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static class KeyEntry { - final String alias; - final PrivateKey privateKey; - final List certificateChain; - final char[] password; - - KeyEntry(String alias, PrivateKey privateKey, List certificateChain, char[] password) { - this.alias = alias; - this.privateKey = privateKey; - this.certificateChain = certificateChain; - this.password = password; - } - } - - private static class CertificateEntry { - final String alias; - final X509Certificate certificate; - - CertificateEntry(String alias, X509Certificate certificate) { - this.alias = alias; - this.certificate = certificate; - } - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/KeyStoreType.java b/security-utils/src/main/java/com/yahoo/security/KeyStoreType.java deleted file mode 100644 index 7fb8df35286..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/KeyStoreType.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; - -/** - * @author bjorncs - */ -public enum KeyStoreType { - JKS { - KeyStore createKeystore() throws KeyStoreException { - return KeyStore.getInstance("JKS"); - } - }, - PKCS12 { - KeyStore createKeystore() throws KeyStoreException { - return KeyStore.getInstance("PKCS12", BouncyCastleProviderHolder.getInstance()); - } - }; - abstract KeyStore createKeystore() throws GeneralSecurityException; -} diff --git a/security-utils/src/main/java/com/yahoo/security/KeyStoreUtils.java b/security-utils/src/main/java/com/yahoo/security/KeyStoreUtils.java deleted file mode 100644 index f0c4d99bf69..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/KeyStoreUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.KeyStore; - -/** - * @author bjorncs - */ -public class KeyStoreUtils { - private KeyStoreUtils() {} - - public static void writeKeyStoreToFile(KeyStore keyStore, Path file, char[] password) { - try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(file))) { - keyStore.store(out, password); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - - } - - public static void writeKeyStoreToFile(KeyStore keyStore, Path file) { - writeKeyStoreToFile(keyStore, file, new char[0]); - } - -} diff --git a/security-utils/src/main/java/com/yahoo/security/KeyUtils.java b/security-utils/src/main/java/com/yahoo/security/KeyUtils.java deleted file mode 100644 index 11fb0f432e4..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/KeyUtils.java +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; -import org.bouncycastle.jce.spec.ECParameterSpec; -import org.bouncycastle.jce.spec.ECPublicKeySpec; -import org.bouncycastle.math.ec.ECPoint; -import org.bouncycastle.math.ec.FixedPointCombMultiplier; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.util.io.pem.PemObject; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.UncheckedIOException; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAPublicKeySpec; - -import static com.yahoo.security.KeyAlgorithm.EC; -import static com.yahoo.security.KeyAlgorithm.RSA; - -/** - * @author bjorncs - */ -public class KeyUtils { - private KeyUtils() {} - - public static KeyPair generateKeypair(KeyAlgorithm algorithm, int keySize) { - try { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm.getAlgorithmName(), BouncyCastleProviderHolder.getInstance()); - if (keySize != -1) { - keyGen.initialize(keySize); - } - return keyGen.genKeyPair(); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - } - - public static KeyPair generateKeypair(KeyAlgorithm algorithm) { - return generateKeypair(algorithm, -1); - } - - public static PublicKey extractPublicKey(PrivateKey privateKey) { - String algorithm = privateKey.getAlgorithm(); - try { - if (algorithm.equals(RSA.getAlgorithmName())) { - KeyFactory keyFactory = KeyFactory.getInstance(RSA.getAlgorithmName(), BouncyCastleProviderHolder.getInstance()); - RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey) privateKey; - RSAPublicKeySpec keySpec = new RSAPublicKeySpec(rsaPrivateCrtKey.getModulus(), rsaPrivateCrtKey.getPublicExponent()); - return keyFactory.generatePublic(keySpec); - } else if (algorithm.equals(EC.getAlgorithmName())) { - KeyFactory keyFactory = KeyFactory.getInstance(EC.getAlgorithmName(), BouncyCastleProviderHolder.getInstance()); - BCECPrivateKey ecPrivateKey = (BCECPrivateKey) privateKey; - ECParameterSpec ecParameterSpec = ecPrivateKey.getParameters(); - ECPoint ecPoint = new FixedPointCombMultiplier().multiply(ecParameterSpec.getG(), ecPrivateKey.getD()); - ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, ecParameterSpec); - return keyFactory.generatePublic(keySpec); - } else { - throw new IllegalArgumentException("Unexpected key algorithm: " + algorithm); - } - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - } - - public static PrivateKey fromPemEncodedPrivateKey(String pem) { - try (PEMParser parser = new PEMParser(new StringReader(pem))) { - Object pemObject = parser.readObject(); - if (pemObject instanceof PrivateKeyInfo) { - PrivateKeyInfo keyInfo = (PrivateKeyInfo) pemObject; - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyInfo.getEncoded()); - return KeyFactory.getInstance(RSA.getAlgorithmName()).generatePrivate(keySpec); - } else if (pemObject instanceof PEMKeyPair) { - PEMKeyPair pemKeypair = (PEMKeyPair) pemObject; - PrivateKeyInfo keyInfo = pemKeypair.getPrivateKeyInfo(); - JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter().setProvider(BouncyCastleProviderHolder.getInstance()); - return pemConverter.getPrivateKey(keyInfo); - } - throw new IllegalArgumentException("Unexpected type of PEM type: " + pemObject); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - } - - public static String toPem(PrivateKey privateKey) { - try (StringWriter stringWriter = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) { - String algorithm = privateKey.getAlgorithm(); - // Note: Encoding using PKCS#1 as this is to be read by tools only supporting PKCS#1 - String type; - if (algorithm.equals(RSA.getAlgorithmName())) { - type = "RSA PRIVATE KEY"; - } else if (algorithm.equals(EC.getAlgorithmName())) { - type = "EC PRIVATE KEY"; - } else { - throw new IllegalArgumentException("Unexpected key algorithm: " + algorithm); - } - pemWriter.writeObject(new PemObject(type, getPkcs1Bytes(privateKey))); - pemWriter.flush(); - return stringWriter.toString(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static byte[] getPkcs1Bytes(PrivateKey privateKey) throws IOException{ - - byte[] privBytes = privateKey.getEncoded(); - PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privBytes); - ASN1Encodable encodable = pkInfo.parsePrivateKey(); - ASN1Primitive primitive = encodable.toASN1Primitive(); - return primitive.getEncoded(); - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java b/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java deleted file mode 100644 index e08ee117fcd..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/Pkcs10Csr.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.ASN1ObjectIdentifier; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.Extensions; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; - -import javax.security.auth.x500.X500Principal; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static java.util.Collections.emptyList; -import static java.util.stream.Collectors.toList; - -/** - * @author bjorncs - */ -public class Pkcs10Csr { - - private final PKCS10CertificationRequest csr; - - Pkcs10Csr(PKCS10CertificationRequest csr) { - this.csr = csr; - } - - PKCS10CertificationRequest getBcCsr() { - return csr; - } - - public X500Principal getSubject() { - return new X500Principal(csr.getSubject().toString()); - } - - public List getSubjectAlternativeNames() { - return getExtensions() - .map(extensions -> GeneralNames.fromExtensions(extensions, Extension.subjectAlternativeName)) - .map(SubjectAlternativeName::fromGeneralNames) - .orElse(emptyList()); - } - - /** - * @return If basic constraints extension is present: returns true if CA cert, false otherwise. Returns empty if the extension is not present. - */ - public Optional getBasicConstraints() { - return getExtensions() - .map(BasicConstraints::fromExtensions) - .map(BasicConstraints::isCA); - } - - public List getExtensionOIds() { - return getExtensions() - .map(extensions -> Arrays.stream(extensions.getExtensionOIDs()) - .map(ASN1ObjectIdentifier::getId) - .collect(toList())) - .orElse(emptyList()); - - } - - private Optional getExtensions() { - return Optional.of(csr.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) - .filter(attributes -> attributes.length > 0) - .map(attributes -> attributes[0]) - .map(attribute -> Extensions.getInstance(attribute.getAttrValues().getObjectAt(0))); - } - -} diff --git a/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrBuilder.java b/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrBuilder.java deleted file mode 100644 index 0fe6117ef2f..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrBuilder.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.BasicConstraints; -import org.bouncycastle.asn1.x509.Extension; -import org.bouncycastle.asn1.x509.ExtensionsGenerator; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorCreationException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder; - -import javax.security.auth.x500.X500Principal; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.security.KeyPair; -import java.util.ArrayList; -import java.util.List; - -import static com.yahoo.security.SubjectAlternativeName.Type.DNS_NAME; - -/** - * @author bjorncs - */ -public class Pkcs10CsrBuilder { - - private final X500Principal subject; - private final KeyPair keyPair; - private final List subjectAlternativeNames = new ArrayList<>(); - private final SignatureAlgorithm signatureAlgorithm; - private BasicConstraintsExtension basicConstraintsExtension; - - private Pkcs10CsrBuilder(X500Principal subject, - KeyPair keyPair, - SignatureAlgorithm signatureAlgorithm) { - this.subject = subject; - this.keyPair = keyPair; - this.signatureAlgorithm = signatureAlgorithm; - } - - public static Pkcs10CsrBuilder fromKeypair(X500Principal subject, - KeyPair keyPair, - SignatureAlgorithm signatureAlgorithm) { - return new Pkcs10CsrBuilder(subject, keyPair, signatureAlgorithm); - } - - public Pkcs10CsrBuilder addSubjectAlternativeName(String dns) { - this.subjectAlternativeNames.add(new SubjectAlternativeName(DNS_NAME, dns)); - return this; - } - - public Pkcs10CsrBuilder addSubjectAlternativeName(SubjectAlternativeName san) { - this.subjectAlternativeNames.add(san); - return this; - } - - public Pkcs10CsrBuilder addSubjectAlternativeName(SubjectAlternativeName.Type type, String value) { - this.subjectAlternativeNames.add(new SubjectAlternativeName(type, value)); - return this; - } - - public Pkcs10CsrBuilder setBasicConstraints(boolean isCritical, boolean isCertAuthorityCertificate) { - this.basicConstraintsExtension = new BasicConstraintsExtension(isCritical, isCertAuthorityCertificate); - return this; - } - - public Pkcs10CsrBuilder setIsCertAuthority(boolean isCertAuthority) { - return setBasicConstraints(true, isCertAuthority); - } - - public Pkcs10Csr build() { - try { - PKCS10CertificationRequestBuilder requestBuilder = - new JcaPKCS10CertificationRequestBuilder(new X500Name(subject.getName()), keyPair.getPublic()); - ExtensionsGenerator extGen = new ExtensionsGenerator(); - if (basicConstraintsExtension != null) { - extGen.addExtension( - Extension.basicConstraints, - basicConstraintsExtension.isCritical, - new BasicConstraints(basicConstraintsExtension.isCertAuthorityCertificate)); - } - if (!subjectAlternativeNames.isEmpty()) { - GeneralNames generalNames = new GeneralNames( - subjectAlternativeNames.stream() - .map(SubjectAlternativeName::toGeneralName) - .toArray(GeneralName[]::new)); - extGen.addExtension(Extension.subjectAlternativeName, false, generalNames); - } - requestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate()); - ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm.getAlgorithmName()) - .setProvider(BouncyCastleProviderHolder.getInstance()) - .build(keyPair.getPrivate()); - return new Pkcs10Csr(requestBuilder.build(contentSigner)); - } catch (OperatorCreationException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - - } - -} diff --git a/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrUtils.java b/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrUtils.java deleted file mode 100644 index 6f12450528d..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/Pkcs10CsrUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.util.io.pem.PemObject; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.UncheckedIOException; - -/** - * @author bjorncs - */ -public class Pkcs10CsrUtils { - - private Pkcs10CsrUtils() {} - - public static Pkcs10Csr fromPem(String pem) { - try (PEMParser pemParser = new PEMParser(new StringReader(pem))) { - return new Pkcs10Csr((PKCS10CertificationRequest) pemParser.readObject()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static String toPem(Pkcs10Csr csr) { - try (StringWriter stringWriter = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) { - pemWriter.writeObject(new PemObject("CERTIFICATE REQUEST", csr.getBcCsr().getEncoded())); - pemWriter.flush(); - return stringWriter.toString(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/SignatureAlgorithm.java b/security-utils/src/main/java/com/yahoo/security/SignatureAlgorithm.java deleted file mode 100644 index fbff18f5c12..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/SignatureAlgorithm.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -/** - * @author bjorncs - */ -public enum SignatureAlgorithm { - SHA256_WITH_RSA("SHA256withRSA"), - SHA512_WITH_RSA("SHA512withRSA"), - SHA256_WITH_ECDSA("SHA256withECDSA"), - SHA512_WITH_ECDSA("SHA512withECDSA"); - - private final String algorithmName; - - SignatureAlgorithm(String algorithmName) { - this.algorithmName = algorithmName; - } - - public String getAlgorithmName() { - return algorithmName; - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java b/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java deleted file mode 100644 index 75ab2417edf..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/SslContextBuilder.java +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.Collections; -import java.util.List; - -import static java.util.Collections.singletonList; - -/** - * @author bjorncs - */ -public class SslContextBuilder { - - private KeyStoreSupplier trustStoreSupplier; - private KeyStoreSupplier keyStoreSupplier; - private char[] keyStorePassword; - - public SslContextBuilder() {} - - public SslContextBuilder withTrustStore(Path file, KeyStoreType trustStoreType) { - this.trustStoreSupplier = () -> KeyStoreBuilder.withType(trustStoreType).fromFile(file).build(); - return this; - } - - public SslContextBuilder withTrustStore(KeyStore trustStore) { - this.trustStoreSupplier = () -> trustStore; - return this; - } - - public SslContextBuilder withTrustStore(X509Certificate caCertificate) { - return withTrustStore(singletonList(caCertificate)); - } - - public SslContextBuilder withTrustStore(List caCertificates) { - this.trustStoreSupplier = () -> createTrustStore(caCertificates); - return this; - } - - public SslContextBuilder withTrustStore(Path pemEncodedCaCertificates) { - this.trustStoreSupplier = () -> { - List caCertificates = - X509CertificateUtils.certificateListFromPem(new String(Files.readAllBytes(pemEncodedCaCertificates))); - return createTrustStore(caCertificates); - }; - return this; - } - - public SslContextBuilder withKeyStore(PrivateKey privateKey, X509Certificate certificate) { - char[] pwd = new char[0]; - this.keyStoreSupplier = () -> KeyStoreBuilder.withType(KeyStoreType.JKS).withKeyEntry("default", privateKey, certificate).build(); - this.keyStorePassword = pwd; - return this; - } - - public SslContextBuilder withKeyStore(KeyStore keyStore, char[] password) { - this.keyStoreSupplier = () -> keyStore; - this.keyStorePassword = password; - return this; - } - - public SslContextBuilder withKeyStore(Path file, char[] password, KeyStoreType keyStoreType) { - this.keyStoreSupplier = () -> KeyStoreBuilder.withType(keyStoreType).fromFile(file, password).build(); - this.keyStorePassword = password; - return this; - } - - public SslContextBuilder withKeyStore(Path privateKeyPemFile, Path certificatesPemFile) { - this.keyStoreSupplier = - () -> { - PrivateKey privateKey = KeyUtils.fromPemEncodedPrivateKey(new String(Files.readAllBytes(privateKeyPemFile))); - List certificates = X509CertificateUtils.certificateListFromPem(new String(Files.readAllBytes(certificatesPemFile))); - return KeyStoreBuilder.withType(KeyStoreType.JKS) - .withKeyEntry("default", privateKey, certificates) - .build(); - }; - this.keyStorePassword = new char[0]; - return this; - } - - public SSLContext build() { - try { - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - TrustManager[] trustManagers = - trustStoreSupplier != null ? createTrustManagers(trustStoreSupplier) : null; - KeyManager[] keyManagers = - keyStoreSupplier != null ? createKeyManagers(keyStoreSupplier, keyStorePassword) : null; - sslContext.init(keyManagers, trustManagers, null); - return sslContext; - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static TrustManager[] createTrustManagers(KeyStoreSupplier trustStoreSupplier) - throws GeneralSecurityException, IOException { - TrustManagerFactory trustManagerFactory = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(trustStoreSupplier.get()); - return trustManagerFactory.getTrustManagers(); - } - - private static KeyManager[] createKeyManagers(KeyStoreSupplier keyStoreSupplier, char[] password) - throws GeneralSecurityException, IOException { - KeyManagerFactory keyManagerFactory = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keyStoreSupplier.get(), password); - return keyManagerFactory.getKeyManagers(); - } - - private static KeyStore createTrustStore(List caCertificates) { - KeyStoreBuilder trustStoreBuilder = KeyStoreBuilder.withType(KeyStoreType.JKS); - for (int i = 0; i < caCertificates.size(); i++) { - trustStoreBuilder.withCertificateEntry("cert-" + i, caCertificates.get(i)); - } - return trustStoreBuilder.build(); - } - - private interface KeyStoreSupplier { - KeyStore get() throws IOException, GeneralSecurityException; - } - -} diff --git a/security-utils/src/main/java/com/yahoo/security/SubjectAlternativeName.java b/security-utils/src/main/java/com/yahoo/security/SubjectAlternativeName.java deleted file mode 100644 index 29395c75e70..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/SubjectAlternativeName.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.DERIA5String; -import org.bouncycastle.asn1.x500.X500Name; -import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x509.GeneralNames; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import static java.util.stream.Collectors.toList; - -/** - * @author bjorncs - */ -public class SubjectAlternativeName { - - private final Type type; - private final String value; - - public SubjectAlternativeName(Type type, String value) { - this.type = type; - this.value = value; - } - - SubjectAlternativeName(GeneralName bcGeneralName) { - this.type = Type.fromTag(bcGeneralName.getTagNo()); - this.value = getValue(bcGeneralName); - } - - public Type getType() { - return type; - } - - public String getValue() { - return value; - } - - GeneralName toGeneralName() { - return new GeneralName(type.tag, value); - } - - static List fromGeneralNames(GeneralNames generalNames) { - return Arrays.stream(generalNames.getNames()).map(SubjectAlternativeName::new).collect(toList()); - } - - private String getValue(GeneralName bcGeneralName) { - ASN1Encodable name = bcGeneralName.getName(); - switch (bcGeneralName.getTagNo()) { - case GeneralName.rfc822Name: - case GeneralName.dNSName: - case GeneralName.uniformResourceIdentifier: - return DERIA5String.getInstance(name).getString(); - case GeneralName.directoryName: - return X500Name.getInstance(name).toString(); - default: - return name.toString(); - } - } - - @Override - public String toString() { - return "SubjectAlternativeName{" + - "type=" + type + - ", value='" + value + '\'' + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SubjectAlternativeName that = (SubjectAlternativeName) o; - return type == that.type && - Objects.equals(value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(type, value); - } - - public enum Type { - OTHER_NAME(0), - RFC822_NAME(1), - DNS_NAME(2), - X400_ADDRESS(3), - DIRECTORY_NAME(4), - EDI_PARITY_NAME(5), - UNIFORM_RESOURCE_IDENTIFIER(6), - IP_ADDRESS(7), - REGISTERED_ID(8); - - final int tag; - - Type(int tag) { - this.tag = tag; - } - - public static Type fromTag(int tag) { - return Arrays.stream(Type.values()) - .filter(type -> type.tag == tag) - .findAny() - .orElseThrow(() -> new IllegalArgumentException("Invalid tag: " + tag)); - } - - public int getTag() { - return tag; - } - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/X509CertificateBuilder.java b/security-utils/src/main/java/com/yahoo/security/X509CertificateBuilder.java deleted file mode 100644 index 54d7d39253e..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/X509CertificateBuilder.java +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -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.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.OperatorException; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.pkcs.PKCS10CertificationRequest; -import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; - -import javax.security.auth.x500.X500Principal; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.sql.Date; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; - -import static com.yahoo.security.SubjectAlternativeName.Type.DNS_NAME; - - -/** - * @author bjorncs - */ -public class X509CertificateBuilder { - - private final BigInteger serialNumber; - private final SignatureAlgorithm signingAlgorithm; - private final PrivateKey caPrivateKey; - private final Instant notBefore; - private final Instant notAfter; - private final List subjectAlternativeNames = new ArrayList<>(); - private final X500Principal issuer; - private final X500Principal subject; - private final PublicKey certPublicKey; - private BasicConstraintsExtension basicConstraintsExtension; - - private X509CertificateBuilder(X500Principal issuer, - X500Principal subject, - Instant notBefore, - Instant notAfter, - PublicKey certPublicKey, - PrivateKey caPrivateKey, - SignatureAlgorithm signingAlgorithm, - BigInteger serialNumber) { - this.issuer = issuer; - this.subject = subject; - this.notBefore = notBefore; - this.notAfter = notAfter; - this.certPublicKey = certPublicKey; - this.caPrivateKey = caPrivateKey; - this.signingAlgorithm = signingAlgorithm; - this.serialNumber = serialNumber; - } - - public static X509CertificateBuilder fromCsr(Pkcs10Csr csr, - X500Principal caIssuer, - Instant notBefore, - Instant notAfter, - PrivateKey caPrivateKey, - SignatureAlgorithm signingAlgorithm, - BigInteger serialNumber) { - try { - PKCS10CertificationRequest bcCsr = csr.getBcCsr(); - PublicKey publicKey = new JcaPKCS10CertificationRequest(bcCsr) - .setProvider(BouncyCastleProviderHolder.getInstance()) - .getPublicKey(); - return new X509CertificateBuilder(caIssuer, - new X500Principal(bcCsr.getSubject().getEncoded()), - notBefore, - notAfter, - publicKey, - caPrivateKey, - signingAlgorithm, - serialNumber); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static X509CertificateBuilder fromKeypair(KeyPair keyPair, - X500Principal subject, - Instant notBefore, - Instant notAfter, - SignatureAlgorithm signingAlgorithm, - BigInteger serialNumber) { - return new X509CertificateBuilder(subject, - subject, - notBefore, - notAfter, - keyPair.getPublic(), - keyPair.getPrivate(), - signingAlgorithm, - serialNumber); - } - - /** - * @return generates a cryptographically secure positive serial number up to 128 bits - */ - public static BigInteger generateRandomSerialNumber() { - return new BigInteger(128, new SecureRandom()); - } - - public X509CertificateBuilder addSubjectAlternativeName(String dnsName) { - this.subjectAlternativeNames.add(new SubjectAlternativeName(DNS_NAME, dnsName)); - return this; - } - - public X509CertificateBuilder addSubjectAlternativeName(SubjectAlternativeName san) { - this.subjectAlternativeNames.add(san); - return this; - } - - public X509CertificateBuilder setBasicConstraints(boolean isCritical, boolean isCertAuthorityCertificate) { - this.basicConstraintsExtension = new BasicConstraintsExtension(isCritical, isCertAuthorityCertificate); - return this; - } - - public X509CertificateBuilder setIsCertAuthority(boolean isCertAuthority) { - return setBasicConstraints(true, isCertAuthority); - } - - public X509Certificate build() { - try { - JcaX509v3CertificateBuilder jcaCertBuilder = new JcaX509v3CertificateBuilder( - issuer, serialNumber, Date.from(notBefore), Date.from(notAfter), subject, certPublicKey); - if (basicConstraintsExtension != null) { - jcaCertBuilder.addExtension( - Extension.basicConstraints, - basicConstraintsExtension.isCritical, - new BasicConstraints(basicConstraintsExtension.isCertAuthorityCertificate)); - } - if (!subjectAlternativeNames.isEmpty()) { - GeneralNames generalNames = new GeneralNames( - subjectAlternativeNames.stream() - .map(SubjectAlternativeName::toGeneralName) - .toArray(GeneralName[]::new)); - jcaCertBuilder.addExtension(Extension.subjectAlternativeName, false, generalNames); - } - ContentSigner contentSigner = new JcaContentSignerBuilder(signingAlgorithm.getAlgorithmName()) - .setProvider(BouncyCastleProviderHolder.getInstance()) - .build(caPrivateKey); - return new JcaX509CertificateConverter() - .setProvider(BouncyCastleProviderHolder.getInstance()) - .getCertificate(jcaCertBuilder.build(contentSigner)); - } catch (OperatorException | GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - -} diff --git a/security-utils/src/main/java/com/yahoo/security/X509CertificateUtils.java b/security-utils/src/main/java/com/yahoo/security/X509CertificateUtils.java deleted file mode 100644 index 33bd750bac5..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/X509CertificateUtils.java +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security; - -import org.bouncycastle.asn1.ASN1Encodable; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.ASN1Primitive; -import org.bouncycastle.asn1.x509.GeneralNames; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMWriter; -import org.bouncycastle.util.io.pem.PemObject; - -import javax.naming.NamingException; -import javax.naming.ldap.LdapName; -import javax.security.auth.x500.X500Principal; -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.UncheckedIOException; -import java.security.GeneralSecurityException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static com.yahoo.security.Extension.SUBJECT_ALTERNATIVE_NAMES; -import static java.util.stream.Collectors.toList; - -/** - * @author bjorncs - */ -public class X509CertificateUtils { - - private X509CertificateUtils() {} - - public static X509Certificate fromPem(String pem) { - try (PEMParser parser = new PEMParser(new StringReader(pem))) { - return toX509Certificate(parser.readObject()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (CertificateException e) { - throw new RuntimeException(e); - } - } - - public static List certificateListFromPem(String pem) { - try (PEMParser parser = new PEMParser(new StringReader(pem))) { - List list = new ArrayList<>(); - Object pemObject; - while ((pemObject = parser.readObject()) != null) { - list.add(toX509Certificate(pemObject)); - } - return list; - } catch (IOException e) { - throw new UncheckedIOException(e); - } catch (CertificateException e) { - throw new RuntimeException(e); - } - } - - private static X509Certificate toX509Certificate(Object pemObject) throws CertificateException { - if (pemObject instanceof X509Certificate) { - return (X509Certificate) pemObject; - } - if (pemObject instanceof X509CertificateHolder) { - return new JcaX509CertificateConverter() - .setProvider(BouncyCastleProviderHolder.getInstance()) - .getCertificate((X509CertificateHolder) pemObject); - } - throw new IllegalArgumentException("Invalid type of PEM object: " + pemObject); - } - - public static String toPem(X509Certificate certificate) { - try (StringWriter stringWriter = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) { - pemWriter.writeObject(new PemObject("CERTIFICATE", certificate.getEncoded())); - pemWriter.flush(); - return stringWriter.toString(); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static String toPem(List certificates) { - try (StringWriter stringWriter = new StringWriter(); JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) { - for (X509Certificate certificate : certificates) { - pemWriter.writeObject(new PemObject("CERTIFICATE", certificate.getEncoded())); - } - pemWriter.flush(); - return stringWriter.toString(); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static List getSubjectCommonNames(X509Certificate certificate) { - return getCommonNames(certificate.getSubjectX500Principal()); - } - - public static List getIssuerCommonNames(X509Certificate certificate) { - return getCommonNames(certificate.getIssuerX500Principal()); - } - - public static List getCommonNames(X500Principal subject) { - try { - String subjectPrincipal = subject.getName(); - return new LdapName(subjectPrincipal).getRdns().stream() - .filter(rdn -> rdn.getType().equalsIgnoreCase("cn")) - .map(rdn -> rdn.getValue().toString()) - .collect(toList()); - } catch (NamingException e) { - throw new IllegalArgumentException("Invalid CN: " + e, e); - } - - } - - public static List getSubjectAlternativeNames(X509Certificate certificate) { - try { - byte[] extensionValue = certificate.getExtensionValue(SUBJECT_ALTERNATIVE_NAMES.getOId()); - if (extensionValue == null) return Collections.emptyList(); - ASN1Encodable asn1Encodable = ASN1Primitive.fromByteArray(extensionValue); - if (asn1Encodable instanceof ASN1OctetString) { - asn1Encodable = ASN1Primitive.fromByteArray(((ASN1OctetString) asn1Encodable).getOctets()); - } - GeneralNames names = GeneralNames.getInstance(asn1Encodable); - return SubjectAlternativeName.fromGeneralNames(names); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/package-info.java b/security-utils/src/main/java/com/yahoo/security/package-info.java deleted file mode 100644 index 10a4c9c0e0d..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * @author bjorncs - */ - -@ExportPackage -package com.yahoo.security; - -import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptions.java b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptions.java deleted file mode 100644 index f0d1edd6889..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityOptions.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security.tls; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Objects; -import java.util.Optional; - -/** - * Generic TLS configuration for Vespa - * - * @author bjorncs - */ -public class TransportSecurityOptions { - - private static final ObjectMapper mapper = new ObjectMapper(); - - private final Path privateKeyFile; - private final Path certificatesFile; - private final Path caCertificatesFile; - - public TransportSecurityOptions(String privateKeyFile, String certificatesFile, String caCertificatesFile) { - this(Paths.get(privateKeyFile), Paths.get(certificatesFile), Paths.get(caCertificatesFile)); - } - - public TransportSecurityOptions(Path privateKeyFile, Path certificatesFile, Path caCertificatesFile) { - this.privateKeyFile = privateKeyFile; - this.certificatesFile = certificatesFile; - this.caCertificatesFile = caCertificatesFile; - } - - public Path getPrivateKeyFile() { - return privateKeyFile; - } - - public Path getCertificatesFile() { - return certificatesFile; - } - - public Path getCaCertificatesFile() { - return caCertificatesFile; - } - - public static TransportSecurityOptions fromJsonFile(Path file) { - try { - JsonNode root = mapper.readTree(file.toFile()); - JsonNode filesNode = getField(root, "files"); - String privateKeyFile = getField(filesNode, "private-key").asText(); - String certificatesFile = getField(filesNode, "certificates").asText(); - String caCertificatesFile = getField(filesNode, "ca-certificates").asText(); - return new TransportSecurityOptions(privateKeyFile, certificatesFile, caCertificatesFile); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static JsonNode getField(JsonNode root, String fieldName) { - return Optional.ofNullable(root.get(fieldName)) - .orElseThrow(() -> new IllegalArgumentException(String.format("'%s' field missing", fieldName))); - } - - @Override - public String toString() { - return "TransportSecurityOptions{" + - "privateKeyFile=" + privateKeyFile + - ", certificatesFile=" + certificatesFile + - ", caCertificatesFile=" + caCertificatesFile + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TransportSecurityOptions that = (TransportSecurityOptions) o; - return Objects.equals(privateKeyFile, that.privateKeyFile) && - Objects.equals(certificatesFile, that.certificatesFile) && - Objects.equals(caCertificatesFile, that.caCertificatesFile); - } - - @Override - public int hashCode() { - return Objects.hash(privateKeyFile, certificatesFile, caCertificatesFile); - } -} \ No newline at end of file diff --git a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java b/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java deleted file mode 100644 index 5595d33a9b5..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/tls/TransportSecurityUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.security.tls; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Optional; - -/** - * Utility class for retrieving {@link TransportSecurityOptions} from the system. - * - * @author bjorncs - */ -public class TransportSecurityUtils { - - public static final String CONFIG_FILE_ENVIRONMENT_VARIABLE = "VESPA_TLS_CONFIG_FILE"; - public static final String INSECURE_MIXED_MODE_ENVIRONMENT_VARIABLE = "VESPA_TLS_INSECURE_MIXED_MODE"; - - public enum MixedMode { - PLAINTEXT_CLIENT_MIXED_SERVER("plaintext_client_mixed_server"), - TLS_CLIENT_MIXED_SERVER("tls_client_mixed_server"); - - final String configValue; - - MixedMode(String configValue) { - this.configValue = configValue; - } - - static MixedMode fromConfigValue(String configValue) { - return Arrays.stream(values()) - .filter(v -> v.configValue.equals(configValue)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Unknown value: " + configValue)); - } - } - - private TransportSecurityUtils() {} - - public static boolean isTransportSecurityEnabled() { - return getConfigFile().isPresent(); - } - - public static boolean isInsecureMixedModeEnabled() { - return getInsecureMixedMode().isPresent(); - } - - public static Optional getInsecureMixedMode() { - if (!isTransportSecurityEnabled()) return Optional.empty(); - return getEnvironmentVariable(INSECURE_MIXED_MODE_ENVIRONMENT_VARIABLE) - .map(MixedMode::fromConfigValue); - } - - public static Optional getConfigFile() { - return getEnvironmentVariable(CONFIG_FILE_ENVIRONMENT_VARIABLE).map(Paths::get); - } - - public static Optional getOptions() { - return getConfigFile() - .map(TransportSecurityOptions::fromJsonFile); - } - - private static Optional getEnvironmentVariable(String environmentVariable) { - return Optional.ofNullable(System.getenv(environmentVariable)) - .filter(var -> !var.isEmpty()); - } -} diff --git a/security-utils/src/main/java/com/yahoo/security/tls/package-info.java b/security-utils/src/main/java/com/yahoo/security/tls/package-info.java deleted file mode 100644 index b5668182f14..00000000000 --- a/security-utils/src/main/java/com/yahoo/security/tls/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * @author bjorncs - */ -@ExportPackage -package com.yahoo.security.tls; - -import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file -- cgit v1.2.3