Browse Source

Merge remote-tracking branch 'origin/main'

pull/1255/head
Olga MaciaszekSharma 1 year ago
parent
commit
72c526549f
  1. 2
      spring-cloud-commons-dependencies/pom.xml
  2. 93
      spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/KeyAndCert.java
  3. 113
      spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/KeyTool.java
  4. 58
      spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java
  5. BIN
      spring-cloud-commons/src/test/resources/MyCA.p12
  6. BIN
      spring-cloud-commons/src/test/resources/MyCert.p12
  7. 2
      spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java

2
spring-cloud-commons-dependencies/pom.xml

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
<name>spring-cloud-commons-dependencies</name>
<description>Spring Cloud Commons Dependencies</description>
<properties>
<spring-security-rsa.version>1.1.0</spring-security-rsa.version>
<spring-security-rsa.version>1.1.1</spring-security-rsa.version>
</properties>
<dependencyManagement>
<dependencies>

93
spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/KeyAndCert.java

@ -1,93 +0,0 @@ @@ -1,93 +0,0 @@
/*
* Copyright 2018-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.configuration;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
public class KeyAndCert {
private KeyPair keyPair;
private X509Certificate certificate;
public KeyAndCert(KeyPair keyPair, X509Certificate certificate) {
this.keyPair = keyPair;
this.certificate = certificate;
}
public KeyPair keyPair() {
return keyPair;
}
public PublicKey publicKey() {
return keyPair.getPublic();
}
public PrivateKey privateKey() {
return keyPair.getPrivate();
}
public X509Certificate certificate() {
return certificate;
}
public String subject() {
String dn = certificate.getSubjectX500Principal().getName();
int index = dn.indexOf('=');
return dn.substring(index + 1);
}
public KeyAndCert sign(String subject) throws Exception {
KeyTool tool = new KeyTool();
return tool.signCertificate(subject, this);
}
public KeyAndCert sign(KeyPair keyPair, String subject) throws Exception {
KeyTool tool = new KeyTool();
return tool.signCertificate(keyPair, subject, this);
}
public KeyStore storeKeyAndCert(String keyPassword) throws Exception {
KeyStore result = KeyStore.getInstance("PKCS12");
result.load(null);
result.setKeyEntry(subject(), keyPair.getPrivate(), keyPassword.toCharArray(), certChain());
return result;
}
private Certificate[] certChain() {
return new Certificate[] { certificate() };
}
public KeyStore storeCert() throws Exception {
return storeCert("PKCS12");
}
public KeyStore storeCert(String storeType) throws Exception {
KeyStore result = KeyStore.getInstance(storeType);
result.load(null);
result.setCertificateEntry(subject(), certificate());
return result;
}
}

113
spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/KeyTool.java

@ -1,113 +0,0 @@ @@ -1,113 +0,0 @@
/*
* Copyright 2018-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.configuration;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.X500Name;
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.KeyUsage;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
public class KeyTool {
private static final long ONE_DAY = 1000L * 60L * 60L * 24L;
private static final long TEN_YEARS = ONE_DAY * 365L * 10L;
public KeyAndCert createCA(String ca) throws Exception {
KeyPair keyPair = createKeyPair();
X509Certificate certificate = createCert(keyPair, ca);
return new KeyAndCert(keyPair, certificate);
}
public KeyAndCert signCertificate(String subject, KeyAndCert signer) throws Exception {
return signCertificate(createKeyPair(), subject, signer);
}
public KeyAndCert signCertificate(KeyPair keyPair, String subject, KeyAndCert signer) throws Exception {
X509Certificate certificate = createCert(keyPair.getPublic(), signer.privateKey(), signer.subject(), subject);
KeyAndCert result = new KeyAndCert(keyPair, certificate);
return result;
}
public KeyPair createKeyPair() throws Exception {
return createKeyPair(1024);
}
public KeyPair createKeyPair(int keySize) throws Exception {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(keySize, new SecureRandom());
return gen.generateKeyPair();
}
public X509Certificate createCert(KeyPair keyPair, String ca) throws Exception {
JcaX509v3CertificateBuilder builder = certBuilder(keyPair.getPublic(), ca, ca);
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.keyCertSign));
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(true));
return signCert(builder, keyPair.getPrivate());
}
public X509Certificate createCert(PublicKey publicKey, PrivateKey privateKey, String issuer, String subject)
throws Exception {
JcaX509v3CertificateBuilder builder = certBuilder(publicKey, issuer, subject);
builder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature));
builder.addExtension(Extension.basicConstraints, false, new BasicConstraints(false));
GeneralName[] names = new GeneralName[] { new GeneralName(GeneralName.dNSName, "localhost") };
builder.addExtension(Extension.subjectAlternativeName, false, GeneralNames.getInstance(new DERSequence(names)));
return signCert(builder, privateKey);
}
private JcaX509v3CertificateBuilder certBuilder(PublicKey publicKey, String issuer, String subject) {
X500Name issuerName = new X500Name(String.format("dc=%s", issuer));
X500Name subjectName = new X500Name(String.format("dc=%s", subject));
long now = System.currentTimeMillis();
BigInteger serialNum = BigInteger.valueOf(now);
Date notBefore = new Date(now - ONE_DAY);
Date notAfter = new Date(now + TEN_YEARS);
return new JcaX509v3CertificateBuilder(issuerName, serialNum, notBefore, notAfter, subjectName, publicKey);
}
private X509Certificate signCert(JcaX509v3CertificateBuilder builder, PrivateKey privateKey) throws Exception {
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
X509CertificateHolder holder = builder.build(signer);
return new JcaX509CertificateConverter().getCertificate(holder);
}
}

58
spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java

@ -16,10 +16,7 @@ @@ -16,10 +16,7 @@
package org.springframework.cloud.configuration;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
@ -27,11 +24,10 @@ import java.security.cert.Certificate; @@ -27,11 +24,10 @@ import java.security.cert.Certificate;
import javax.net.ssl.SSLContext;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import static org.assertj.core.api.Assertions.assertThat;
@ -42,60 +38,22 @@ public class SSHContextFactoryTests { @@ -42,60 +38,22 @@ public class SSHContextFactoryTests {
private static final String KEY_PASSWORD = "test-key-password";
private static KeyAndCert ca;
private static KeyAndCert cert;
private static File keyStore;
private static File trustStore;
private TlsProperties properties;
@BeforeAll
public static void createKeyStoreAndTrustStore() throws Exception {
KeyTool tool = new KeyTool();
ca = tool.createCA("MyCA");
cert = ca.sign("MyCert");
keyStore = saveKeyAndCert(cert);
trustStore = saveCert(ca);
}
private static File saveKeyAndCert(KeyAndCert keyCert) throws Exception {
return saveKeyStore(keyCert.subject(), () -> keyCert.storeKeyAndCert(KEY_PASSWORD));
}
private static File saveCert(KeyAndCert keyCert) throws Exception {
return saveKeyStore(keyCert.subject(), keyCert::storeCert);
}
private static File saveKeyStore(String prefix, KeyStoreSupplier func) throws Exception {
File result = File.createTempFile(prefix, ".p12");
result.deleteOnExit();
try (OutputStream output = new FileOutputStream(result)) {
KeyStore store = func.createKeyStore();
store.store(output, KEY_STORE_PASSWORD.toCharArray());
}
return result;
}
@BeforeEach
public void createProperties() {
properties = new TlsProperties();
properties.setEnabled(true);
properties.setKeyStore(resourceOf(keyStore));
properties.setKeyStore(resourceOf("MyCert.p12"));
properties.setKeyStorePassword(KEY_STORE_PASSWORD);
properties.setKeyPassword(KEY_PASSWORD);
properties.setTrustStore(resourceOf(trustStore));
properties.setTrustStore(resourceOf("MyCA.p12"));
properties.setTrustStorePassword(KEY_STORE_PASSWORD);
}
private Resource resourceOf(File file) {
return new FileSystemResource(file);
private Resource resourceOf(String path) {
return new ClassPathResource(path);
}
@Test
@ -104,10 +62,10 @@ public class SSHContextFactoryTests { @@ -104,10 +62,10 @@ public class SSHContextFactoryTests {
KeyStore store = factory.createKeyStore();
Certificate c = store.getCertificate("MyCert");
assertThat(c).isEqualTo(cert.certificate());
assertThat(c).isNotNull();
Key key = store.getKey("MyCert", KEY_PASSWORD.toCharArray());
assertThat(key).isEqualTo(cert.privateKey());
assertThat(key).isNotNull();
}
@Test
@ -116,7 +74,7 @@ public class SSHContextFactoryTests { @@ -116,7 +74,7 @@ public class SSHContextFactoryTests {
KeyStore store = factory.createTrustStore();
Certificate c = store.getCertificate("MyCA");
assertThat(c).isEqualTo(ca.certificate());
assertThat(c).isNotNull();
}
@Test

BIN
spring-cloud-commons/src/test/resources/MyCA.p12

Binary file not shown.

BIN
spring-cloud-commons/src/test/resources/MyCert.p12

Binary file not shown.

2
spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java

@ -39,7 +39,7 @@ public class EncryptorFactory { @@ -39,7 +39,7 @@ public class EncryptorFactory {
TextEncryptor encryptor;
if (data.contains("RSA PRIVATE KEY")) {
encryptor = new RsaSecretEncryptor(data);
encryptor = new RsaSecretEncryptor(data.replaceAll("\\n *", ""));
}
else if (data.startsWith("ssh-rsa") || data.contains("RSA PUBLIC KEY")) {
throw new KeyFormatException();

Loading…
Cancel
Save