1515 */
1616package io .fusionauth .http .security ;
1717
18- import javax .net .ssl .KeyManager ;
1918import javax .net .ssl .KeyManagerFactory ;
2019import javax .net .ssl .SSLContext ;
20+ import javax .net .ssl .TrustManagerFactory ;
2121import java .io .ByteArrayInputStream ;
2222import java .io .IOException ;
2323import java .security .GeneralSecurityException ;
2828import java .security .cert .Certificate ;
2929import java .security .cert .CertificateException ;
3030import java .security .cert .CertificateFactory ;
31- import java .security .cert .X509Certificate ;
3231import java .security .interfaces .RSAPrivateKey ;
3332import java .security .spec .InvalidKeySpecException ;
3433import java .security .spec .PKCS8EncodedKeySpec ;
@@ -57,46 +56,31 @@ private SecurityTools() {
5756 }
5857
5958 /**
60- * This creates an in-memory keystore containing the certificate and private key and initializes the SSLContext with the key material it
61- * contains.
59+ * This creates an in-memory trust store containing the certificate and initializes the SSLContext with it.
6260 *
63- * @param certificateString A PEM formatted Certificate.
64- * @param keyString A PKCS8 PEM formatted Private Key.
65- * @return A SSLContext configured with the Certificate and Private Key.
61+ * @param certificate A Certificate object.
62+ * @return A SSLContext configured with the Certificate.
6663 */
67- public static SSLContext getServerContext (String certificateString , String keyString ) throws GeneralSecurityException , IOException {
68- byte [] certBytes = parseDERFromPEM (certificateString , CERT_START , CERT_END );
69- byte [] keyBytes = parseDERFromPEM (keyString , P8_KEY_START , P8_KEY_END );
70-
71- X509Certificate cert = generateCertificateFromDER (certBytes );
72- PrivateKey key = generatePrivateKeyFromPKCS8DER (keyBytes );
64+ public static SSLContext clientContext (Certificate certificate ) throws GeneralSecurityException , IOException {
7365 KeyStore keystore = KeyStore .getInstance ("JKS" );
7466 keystore .load (null );
75- keystore .setCertificateEntry ("cert-alias" , cert );
76- keystore .setKeyEntry ("key-alias" , key , "changeit" .toCharArray (), new Certificate []{cert });
67+ keystore .setCertificateEntry ("cert-alias" , certificate );
7768
78- KeyManagerFactory kmf = KeyManagerFactory .getInstance ("SunX509" );
79- kmf .init (keystore , "changeit" .toCharArray ());
80-
81- KeyManager [] km = kmf .getKeyManagers ();
69+ TrustManagerFactory tmf = TrustManagerFactory .getInstance ("SunX509" );
70+ tmf .init (keystore );
8271
8372 SSLContext context = SSLContext .getInstance ("TLS" );
84- context .init (km , null , null );
73+ context .init (null , tmf . getTrustManagers () , null );
8574 return context ;
8675 }
8776
88- private static X509Certificate generateCertificateFromDER ( byte [] certBytes ) throws CertificateException {
77+ public static Certificate parseCertificate ( String certificate ) throws CertificateException {
8978 CertificateFactory factory = CertificateFactory .getInstance ("X.509" );
90- return (X509Certificate ) factory .generateCertificate (new ByteArrayInputStream (certBytes ));
79+ byte [] certBytes = parseDERFromPEM (certificate , CERT_START , CERT_END );
80+ return factory .generateCertificate (new ByteArrayInputStream (certBytes ));
9181 }
9282
93- private static RSAPrivateKey generatePrivateKeyFromPKCS8DER (byte [] keyBytes ) throws InvalidKeySpecException , NoSuchAlgorithmException {
94- PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec (keyBytes );
95- KeyFactory factory = KeyFactory .getInstance ("RSA" );
96- return (RSAPrivateKey ) factory .generatePrivate (spec );
97- }
98-
99- private static byte [] parseDERFromPEM (String pem , String beginDelimiter , String endDelimiter ) {
83+ public static byte [] parseDERFromPEM (String pem , String beginDelimiter , String endDelimiter ) {
10084 int startIndex = pem .indexOf (beginDelimiter );
10185 if (startIndex < 0 ) {
10286 throw new IllegalArgumentException ("Invalid PEM format" );
@@ -111,4 +95,33 @@ private static byte[] parseDERFromPEM(String pem, String beginDelimiter, String
11195 String base64 = pem .substring (startIndex + beginDelimiter .length (), endIndex ).replaceAll ("\\ s" , "" );
11296 return Base64 .getDecoder ().decode (base64 );
11397 }
98+
99+ public static RSAPrivateKey parsePrivateKey (String privateKey ) throws InvalidKeySpecException , NoSuchAlgorithmException {
100+ byte [] keyBytes = parseDERFromPEM (privateKey , P8_KEY_START , P8_KEY_END );
101+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec (keyBytes );
102+ KeyFactory factory = KeyFactory .getInstance ("RSA" );
103+ return (RSAPrivateKey ) factory .generatePrivate (spec );
104+ }
105+
106+ /**
107+ * This creates an in-memory keystore containing the certificate and private key and initializes the SSLContext with the key material it
108+ * contains.
109+ *
110+ * @param certificate A Certificate object.
111+ * @param privateKey A PrivateKey object.
112+ * @return A SSLContext configured with the Certificate and Private Key.
113+ */
114+ public static SSLContext serverContext (Certificate certificate , PrivateKey privateKey ) throws GeneralSecurityException , IOException {
115+ KeyStore keystore = KeyStore .getInstance ("JKS" );
116+ keystore .load (null );
117+ keystore .setCertificateEntry ("cert-alias" , certificate );
118+ keystore .setKeyEntry ("key-alias" , privateKey , "changeit" .toCharArray (), new Certificate []{certificate });
119+
120+ KeyManagerFactory kmf = KeyManagerFactory .getInstance ("SunX509" );
121+ kmf .init (keystore , "changeit" .toCharArray ());
122+
123+ SSLContext context = SSLContext .getInstance ("TLS" );
124+ context .init (kmf .getKeyManagers (), null , null );
125+ return context ;
126+ }
114127}
0 commit comments