Skip to content

Commit f3edcd7

Browse files
committed
add ability to create keystores
1 parent 8c63c6d commit f3edcd7

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

jmx-scraper/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ testing {
3737
implementation("com.linecorp.armeria:armeria-junit5")
3838
implementation("com.linecorp.armeria:armeria-grpc")
3939
implementation("io.opentelemetry.proto:opentelemetry-proto:1.5.0-alpha")
40+
implementation("org.bouncycastle:bcprov-jdk18on:1.80")
41+
implementation("org.bouncycastle:bcpkix-jdk18on:1.80")
4042
}
4143
}
4244
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.jmxscraper;
7+
8+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
9+
import java.io.FileInputStream;
10+
import java.io.FileOutputStream;
11+
import java.math.BigInteger;
12+
import java.nio.file.Path;
13+
import java.security.KeyPair;
14+
import java.security.KeyPairGenerator;
15+
import java.security.KeyStore;
16+
import java.security.PrivateKey;
17+
import java.security.PublicKey;
18+
import java.security.cert.X509Certificate;
19+
import java.time.Instant;
20+
import java.time.temporal.ChronoUnit;
21+
import java.util.Date;
22+
import org.bouncycastle.asn1.x500.X500Name;
23+
import org.bouncycastle.cert.X509v3CertificateBuilder;
24+
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
25+
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
26+
import org.bouncycastle.operator.ContentSigner;
27+
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
28+
29+
/** Utility that allows to manage keystores programmatically without using 'keytool' CLI program */
30+
class TestKeyStoreUtil {
31+
32+
private TestKeyStoreUtil() {}
33+
34+
/**
35+
* Creates a keystore with a public/private key pair
36+
*
37+
* @param path path to key store
38+
* @param password key store password
39+
* @return self-signed certificate of the public/private key pair
40+
*/
41+
@CanIgnoreReturnValue
42+
static X509Certificate createKeyStore(Path path, String password) {
43+
44+
try {
45+
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
46+
keyPairGenerator.initialize(2048);
47+
KeyPair keyPair = keyPairGenerator.generateKeyPair();
48+
PrivateKey privateKey = keyPair.getPrivate();
49+
50+
X509Certificate certificate = createSelfSignedCertificate(keyPair);
51+
52+
KeyStore keyStore = KeyStore.getInstance("JKS");
53+
keyStore.load(null, null);
54+
55+
// for convenience reuse keystore password for key password
56+
keyStore.setKeyEntry(
57+
"key", privateKey, password.toCharArray(), new X509Certificate[] {certificate});
58+
59+
try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
60+
keyStore.store(fos, password.toCharArray());
61+
}
62+
63+
return certificate;
64+
} catch (Exception e) {
65+
throw new IllegalStateException(e);
66+
}
67+
}
68+
69+
private static X509Certificate createSelfSignedCertificate(KeyPair keyPair) {
70+
try {
71+
PublicKey publicKey = keyPair.getPublic();
72+
PrivateKey privateKey = keyPair.getPrivate();
73+
74+
Instant now = Instant.now();
75+
76+
X500Name issuer = new X500Name("CN=Self-Signed Certificate");
77+
X500Name subject = new X500Name("CN=Self-Signed Certificate");
78+
BigInteger serial = BigInteger.valueOf(now.toEpochMilli());
79+
80+
X509v3CertificateBuilder certBuilder =
81+
new JcaX509v3CertificateBuilder(
82+
issuer,
83+
serial,
84+
Date.from(now.minus(1, ChronoUnit.DAYS)), // 1 day ago
85+
Date.from(now.plus(1, ChronoUnit.DAYS)), // 1 day from now
86+
subject,
87+
publicKey);
88+
89+
ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey);
90+
return new JcaX509CertificateConverter().getCertificate(certBuilder.build(signer));
91+
} catch (Exception e) {
92+
throw new IllegalStateException(e);
93+
}
94+
}
95+
96+
/**
97+
* Adds trusted certificate
98+
*
99+
* @param path path to key store
100+
* @param password key store password
101+
* @param certificate certificate to trust
102+
*/
103+
public static void addTrustedCertificate(
104+
Path path, String password, X509Certificate certificate) {
105+
106+
try {
107+
KeyStore keyStore = KeyStore.getInstance("JKS");
108+
109+
try (FileInputStream fis = new FileInputStream(path.toFile())) {
110+
keyStore.load(fis, password.toCharArray());
111+
}
112+
113+
keyStore.setCertificateEntry("trustedCertificate", certificate);
114+
115+
try (FileOutputStream fos = new FileOutputStream(path.toFile())) {
116+
keyStore.store(fos, password.toCharArray());
117+
}
118+
} catch (Exception e) {
119+
throw new IllegalStateException(e);
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)