Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit e51a84d

Browse files
authored
Dropped private Sun security imports. Now using pregenerated certs. (#1032)
1 parent 24dc4e9 commit e51a84d

4 files changed

Lines changed: 66 additions & 67 deletions

File tree

libraries/bot-connector/src/test/java/com/microsoft/bot/connector/JwtTokenExtractorTests.java

Lines changed: 39 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
import com.microsoft.bot.connector.authentication.OpenIdMetadataKey;
1515
import com.microsoft.bot.connector.authentication.TokenValidationParameters;
1616
import java.io.IOException;
17-
import java.math.BigInteger;
17+
import java.io.InputStream;
1818
import java.security.GeneralSecurityException;
1919
import java.security.KeyPair;
20-
import java.security.KeyPairGenerator;
20+
import java.security.KeyStore;
21+
import java.security.KeyStoreException;
2122
import java.security.NoSuchAlgorithmException;
2223
import java.security.PrivateKey;
23-
import java.security.SecureRandom;
24+
import java.security.UnrecoverableKeyException;
2425
import java.security.cert.Certificate;
2526
import java.security.cert.CertificateEncodingException;
27+
import java.security.cert.CertificateException;
2628
import java.security.cert.X509Certificate;
2729
import java.security.interfaces.RSAPrivateKey;
2830
import java.security.interfaces.RSAPublicKey;
@@ -34,54 +36,45 @@
3436
import java.util.concurrent.CompletionException;
3537
import org.junit.Before;
3638
import org.junit.Test;
37-
import sun.security.x509.AlgorithmId;
38-
import sun.security.x509.CertificateAlgorithmId;
39-
import sun.security.x509.CertificateSerialNumber;
40-
import sun.security.x509.CertificateValidity;
41-
import sun.security.x509.CertificateVersion;
42-
import sun.security.x509.CertificateX509Key;
43-
import sun.security.x509.X500Name;
44-
import sun.security.x509.X509CertImpl;
45-
import sun.security.x509.X509CertInfo;
4639

40+
/**
41+
* Test Notes:
42+
*
43+
* The PKCS12 certificates were created using these steps:
44+
* https://kb.globalscape.com/Knowledgebase/11039/Generating-a-PKCS12-Private-Key-and-Public-Certificate
45+
*
46+
* For the expired cert, just specify a negative number of days in step #4.
47+
*
48+
* For both valid and expired certs, these unit tests expect the alias for both to be "bot-connector-pkcs12"
49+
* and the password to be "botframework"
50+
*/
4751
public class JwtTokenExtractorTests {
48-
private X509Certificate validCertificate;
49-
private X509Certificate expiredCertificate;
50-
private KeyPair keyPair;
52+
private CertInfo valid;
53+
private CertInfo expired;
5154

5255
@Before
5356
public void setup() throws GeneralSecurityException, IOException {
5457
ChannelValidation.TOKENVALIDATIONPARAMETERS.validateLifetime = false;
5558
EmulatorValidation.TOKENVALIDATIONPARAMETERS.validateLifetime = false;
5659
GovernmentChannelValidation.TOKENVALIDATIONPARAMETERS.validateLifetime = false;
5760

58-
// create keys
59-
keyPair = createKeyPair();
60-
Date now = new Date();
61-
Date from = new Date(now.getTime() - (10 * 86400000L));
62-
63-
// create expired certificate
64-
Date to = new Date(now.getTime() - (9 * 86400000L));
65-
expiredCertificate = createSelfSignedCertificate(keyPair, from, to);
66-
67-
// create valid certificate
68-
to = new Date(now.getTime() + (9 * 86400000L));
69-
validCertificate = createSelfSignedCertificate(keyPair, from, to);
61+
valid = loadCert("bot-connector.pkcs12");
62+
expired = loadCert("bot-connector-expired.pkcs12");
7063
}
7164

7265
@Test(expected = CompletionException.class)
7366
public void JwtTokenExtractor_WithExpiredCert_ShouldNotAllowCertSigningKey() {
7467
// this should throw a CompletionException (which contains an AuthenticationException)
7568
buildExtractorAndValidateToken(
76-
expiredCertificate, keyPair.getPrivate()
69+
expired.cert, expired.keypair.getPrivate()
7770
).join();
7871
}
7972

8073
@Test
8174
public void JwtTokenExtractor_WithValidCert_ShouldAllowCertSigningKey() {
8275
// this should not throw
8376
buildExtractorAndValidateToken(
84-
validCertificate, keyPair.getPrivate()
77+
valid.cert, valid.keypair.getPrivate()
8578
).join();
8679
}
8780

@@ -92,7 +85,7 @@ public void JwtTokenExtractor_WithExpiredToken_ShouldNotAllow() {
9285
Date issuedAt = new Date(now.getTime() - 86400000L);
9386

9487
buildExtractorAndValidateToken(
95-
expiredCertificate, keyPair.getPrivate(), issuedAt
88+
expired.cert, expired.keypair.getPrivate(), issuedAt
9689
).join();
9790
}
9891

@@ -161,45 +154,24 @@ private static TokenValidationParameters createTokenValidationParameters(X509Cer
161154
}};
162155
}
163156

164-
private KeyPair createKeyPair() throws NoSuchAlgorithmException {
165-
// note that this isn't allowing for a "kid" value
166-
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
167-
generator.initialize(2048);
168-
return generator.generateKeyPair();
157+
private static class CertInfo {
158+
public X509Certificate cert;
159+
public KeyPair keypair;
169160
}
170161

171-
private static X509Certificate createSelfSignedCertificate(
172-
KeyPair pair, Date from, Date to
173-
) throws GeneralSecurityException, IOException {
174-
String dn = "CN=Bot, OU=BotFramework, O=Microsoft, C=US";
175-
String algorithm = "SHA256withRSA";
176-
177-
PrivateKey privateKey = pair.getPrivate();
178-
X509CertInfo info = new X509CertInfo();
179-
180-
CertificateValidity interval = new CertificateValidity(from, to);
181-
BigInteger sn = new BigInteger(64, new SecureRandom());
182-
X500Name owner = new X500Name(dn);
183-
184-
info.set(X509CertInfo.VALIDITY, interval);
185-
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
186-
info.set(X509CertInfo.SUBJECT, owner);
187-
info.set(X509CertInfo.ISSUER, owner);
188-
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
189-
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
190-
AlgorithmId algo = new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid);
191-
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
192-
193-
// Sign the cert to identify the algorithm that's used.
194-
X509CertImpl cert = new X509CertImpl(info);
195-
cert.sign(privateKey, algorithm);
196-
197-
// Update the algorithm, and resign.
198-
algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
199-
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
200-
cert = new X509CertImpl(info);
201-
cert.sign(privateKey, algorithm);
202-
return cert;
162+
private static CertInfo loadCert(String pkcs12File)
163+
throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException,
164+
UnrecoverableKeyException {
165+
InputStream fis = ClassLoader.getSystemResourceAsStream(pkcs12File);
166+
KeyStore p12 = KeyStore.getInstance("pkcs12");
167+
p12.load(fis, "botframework".toCharArray());
168+
169+
return new CertInfo() {{
170+
cert = (X509Certificate) p12.getCertificate("bot-connector-pkcs12");
171+
keypair = new KeyPair(cert.getPublicKey(),
172+
(PrivateKey) p12.getKey("bot-connector-pkcs12", "botframework".toCharArray())
173+
);
174+
}};
203175
}
204176

205177
private static String encodeCertificate(Certificate certificate) {
Binary file not shown.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpAIBAAKCAQEAy8VcIYWh4sF2XcZF7u+lSq7YdE8skZhmtDF5w8GoEoPscGyT
3+
wSeWjK7u+y2g5iAZsXQwzhN1VvOHznAlLrswLaORie7ch9veFeTMT60gLL2w8e6h
4+
RUWxNJiQXjeExwk8Fhvcq7Kpl+qM4iEHvDX6iXCjEkNJ4Ghx48j9siUKMf1T8IcZ
5+
sE3zzaaGOU5ar8NVsf9Kz1kPCOYv8zqykB45nUDsbE/q9cEkumL8ebjd1JApDJf0
6+
sf/PkftMvwP69QY1CJ/achUsRqDvFGLw+ZyUyXaSdPt92H92vbNzo8hn6GuxnPHy
7+
f/Aoxjy/o5zNocsiiJvgFBFjRBZXWhk3OJWKZwIDAQABAoIBADNiKx9Q4Uea3Uw8
8+
STo9OAMjH/YEWQrF0XAy4a+ZT9aLab3Xw1J7txz2p9Cy6tXc1l3HHN96TKaGdoJ6
9+
CQZFsZpwmqybjQS9Tr1amqKk124wz0PSltwu/MZ0ikMX4OWH0J0KnZS2Usm6HZiQ
10+
F7FAM1MhEh3y1dg+vilgb4jSikWcVp7RbcMgwG0N9oQhbPqN+Bv/E5KBpYk1Rdwt
11+
yjSBOdDenx+TF5RrdKYxC3ouKN0BJMgtIIkv+iGce1WMtSAHkNXrgxJ9AhDquREU
12+
Op363fad01Ulvs4Z+IDlEhrpA6oUt5hr8lStFhrhVuDPqctAWz27+YNw5ioHbimA
13+
U48EOzECgYEA7T5dQzKXIzrDha4Spr8KbCMvXsesehWG3RLZxhU7lnjSMAhBuKGU
14+
hZMfjmSSBR/rr7ppMjN4LLmpjqTkhojg/p+MnK9XRSvmGaSxlS1K8hANjShhx6s7
15+
xWbEsKQEPbuq1m0vCAzxgGkxLpRmM9ajJhFYEoSdVbc/hhVI72mxhiUCgYEA2+GI
16+
ig0Wpbq5D1ISwljWHhpdi4d0MeO+wtogMo46AAX4kpgCEKDmPwX2igJKJjQJyWNB
17+
PqHXPPQJyferun27baiNA5vEDzoCRvyLqKjyLrzSS+wDszR4mYhK8naILPonmIca
18+
9BsUDcQw7x3rzVUlOKFpbRfT0qPVa5qn3T32apsCgYEAmYJvCloj3ZHajhdSzj5z
19+
WgFyV1vQSLbBKy9VZoy6n+TR7G6LSBKVbdEC7Do7GcHL2Us/YlJXgmkoQ7qCfGL5
20+
YwiODZyPVZzQKOueVK6X/gVRH3NvwakU5ehXgQzACcnzAwhnFEh7w+FNB5zSfNx3
21+
eNxkJqdUvu/x1KrVJMU5L1kCgYEAkIokYGOUNKOXDTwterY9IpLAVX1YY4dLmfkb
22+
W0BlXiiOq4bjLJ0oXduEolo49f4VRN5LQGnQ/I+Lc8msiK4oLEC1Wd7mNgAzCQjw
23+
oZFVimWzdBcUo5Plhz+xzMsgXzieGMUPcdHvD9GdPUKVBGhpTF3G2ODl7LyoCdEj
24+
cetOdesCgYAIuxFR/89S44Je5maTMkcExZpVTm1D1Zc8EmlHQ+WPjrakZSWFx2TS
25+
o8wUd/mCwCTLRG3S2t3eUZiEi+G9gI8bE/w7ABxNCFAlHbo0SETy7T+9XeznoFbZ
26+
0FyvVLvXQVZhKPVTF0pYkfuHo3ofbotKbTEM62EurroU1dviRJ7Seg==
27+
-----END RSA PRIVATE KEY-----
2.64 KB
Binary file not shown.

0 commit comments

Comments
 (0)