Skip to content

Commit

Permalink
fix: remove dependency on internal sun.security.x509 classes (#564)
Browse files Browse the repository at this point in the history
* chore: use bouncycastle instead of sun.security.x509
  • Loading branch information
shubha-rajan committed Jul 23, 2021
1 parent 18ae8d9 commit 79250e2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 32 deletions.
11 changes: 10 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand Down Expand Up @@ -75,6 +77,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.69</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -90,22 +91,20 @@
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import javax.security.auth.x500.X500Principal;
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.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

// TODO(berezv): add multithreaded test
@RunWith(JUnit4.class)
Expand Down Expand Up @@ -136,8 +135,9 @@ public class CoreSocketFactoryTest {
private ListenableFuture<KeyPair> clientKeyPair;

@Before
public void setup() throws IOException, GeneralSecurityException, ExecutionException {
MockitoAnnotations.initMocks(this);
public void setup()
throws IOException, GeneralSecurityException, ExecutionException, OperatorCreationException {
MockitoAnnotations.openMocks(this);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec =
Expand Down Expand Up @@ -306,7 +306,7 @@ public void create_successfulDomainScopedConnection() throws IOException, Interr
// TODO(berezv): figure out why the test server produces a different error on an expired
// certificate
public void create_expiredCertificateOnFirstConnection_certificateRenewed()
throws IOException, GeneralSecurityException, ExecutionException, InterruptedException {
throws IOException, GeneralSecurityException, ExecutionException, InterruptedException, OperatorCreationException {
FakeSslServer sslServer = new FakeSslServer();
int port = sslServer.start();

Expand Down Expand Up @@ -451,39 +451,43 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
}

private String createEphemeralCert(Duration shiftIntoPast)
throws GeneralSecurityException, ExecutionException, IOException {
throws GeneralSecurityException, ExecutionException, IOException, OperatorCreationException {
Duration validFor = Duration.ofHours(1);
ZonedDateTime notBefore = ZonedDateTime.now().minus(shiftIntoPast);
ZonedDateTime notAfter = notBefore.plus(validFor);

CertificateValidity interval =
new CertificateValidity(Date.from(notBefore.toInstant()), Date.from(notAfter.toInstant()));

X509CertInfo info = new X509CertInfo();
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(1));
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get("SHA1withRSA")));
info.set(X509CertInfo.SUBJECT, new X500Name("C = US, O = Google\\, Inc, CN=temporary-subject"));
info.set(X509CertInfo.KEY, new CertificateX509Key(Futures.getDone(clientKeyPair).getPublic()));
info.set(X509CertInfo.VALIDITY, interval);
info.set(
X509CertInfo.ISSUER,
new X500Name("C = US, O = Google\\, Inc, CN=Google Cloud SQL Signing CA foo:baz"));

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec =
new PKCS8EncodedKeySpec(decodeBase64StripWhitespace(TestKeys.SIGNING_CA_PRIVATE_KEY));
PrivateKey signingKey = keyFactory.generatePrivate(keySpec);

X509CertImpl cert = new X509CertImpl(info);
cert.sign(signingKey, "SHA1withRSA");
final ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA")
.build(signingKey);

X500Principal issuer = new X500Principal(
"C = US, O = Google\\, Inc, CN=Google Cloud SQL Signing CA foo:baz");
X500Principal subject = new X500Principal("C = US, O = Google\\, Inc, CN=temporary-subject");

JcaX509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
issuer,
BigInteger.ONE,
Date.from(notBefore.toInstant()),
Date.from(notAfter.toInstant()),
subject,
Futures.getDone(clientKeyPair).getPublic()
);

X509CertificateHolder certificateHolder = certificateBuilder.build(signer);

Certificate cert = new JcaX509CertificateConverter()
.getCertificate(certificateHolder);

StringBuilder sb = new StringBuilder();
sb.append("-----BEGIN CERTIFICATE-----\n");
sb.append(Base64.getEncoder().encodeToString(cert.getEncoded()).replaceAll("(.{64})", "$1\n"));
sb.append(Base64.getEncoder().encodeToString(cert.getEncoded())
.replaceAll("(.{64})", "$1\n"));
sb.append("\n");
sb.append("-----END CERTIFICATE-----\n");

return sb.toString();
}

Expand Down

0 comments on commit 79250e2

Please sign in to comment.