1 package org
.argeo
.cms
.internal
.runtime
;
3 import java
.io
.BufferedInputStream
;
4 import java
.io
.BufferedReader
;
5 import java
.io
.IOException
;
6 import java
.io
.InputStream
;
7 import java
.io
.OutputStream
;
9 import java
.nio
.file
.Files
;
10 import java
.nio
.file
.Path
;
11 import java
.security
.GeneralSecurityException
;
12 import java
.security
.KeyFactory
;
13 import java
.security
.KeyStore
;
14 import java
.security
.KeyStore
.TrustedCertificateEntry
;
15 import java
.security
.KeyStoreException
;
16 import java
.security
.NoSuchAlgorithmException
;
17 import java
.security
.PrivateKey
;
18 import java
.security
.cert
.CertificateException
;
19 import java
.security
.cert
.CertificateFactory
;
20 import java
.security
.cert
.X509Certificate
;
21 import java
.security
.interfaces
.RSAPrivateKey
;
22 import java
.security
.spec
.InvalidKeySpecException
;
23 import java
.security
.spec
.PKCS8EncodedKeySpec
;
24 import java
.util
.Base64
;
25 import java
.util
.Collection
;
26 import java
.util
.Objects
;
29 * Utilities around private keys and certificate, mostly wrapping BouncyCastle
33 public static KeyStore
getKeyStore(Path keyStoreFile
, char[] keyStorePassword
, String keyStoreType
) {
35 KeyStore store
= KeyStore
.getInstance(keyStoreType
);
36 if (Files
.exists(keyStoreFile
)) {
37 try (InputStream fis
= Files
.newInputStream(keyStoreFile
)) {
38 store
.load(fis
, keyStorePassword
);
44 } catch (GeneralSecurityException
| IOException e
) {
45 throw new RuntimeException("Cannot load keystore " + keyStoreFile
, e
);
49 public static void saveKeyStore(Path keyStoreFile
, char[] keyStorePassword
, KeyStore keyStore
) {
51 try (OutputStream fis
= Files
.newOutputStream(keyStoreFile
)) {
52 keyStore
.store(fis
, keyStorePassword
);
54 } catch (GeneralSecurityException
| IOException e
) {
55 throw new RuntimeException("Cannot save keystore " + keyStoreFile
, e
);
59 public static void loadPrivateCertificatePem(KeyStore keyStore
, String alias
, Reader key
, char[] keyPassword
,
60 BufferedInputStream cert
) {
61 Objects
.requireNonNull(keyStore
);
62 Objects
.requireNonNull(key
);
64 X509Certificate certificate
= loadPemCertificate(cert
);
65 PrivateKey privateKey
= loadPemPrivateKey(key
, keyPassword
);
66 keyStore
.setKeyEntry(alias
, privateKey
, keyPassword
, new java
.security
.cert
.Certificate
[] { certificate
});
67 } catch (KeyStoreException e
) {
68 throw new RuntimeException("Cannot store PEM certificate", e
);
72 public static void loadTrustedCertificatePem(KeyStore keyStore
, char[] keyStorePassword
, BufferedInputStream cert
) {
74 X509Certificate certificate
= loadPemCertificate(cert
);
75 TrustedCertificateEntry trustedCertificateEntry
= new TrustedCertificateEntry(certificate
);
76 keyStore
.setEntry(certificate
.getSubjectX500Principal().getName(), trustedCertificateEntry
, null);
77 } catch (KeyStoreException e
) {
78 throw new RuntimeException("Cannot store PEM certificate", e
);
82 public static PrivateKey
loadPemPrivateKey(Reader reader
, char[] keyPassword
) {
84 StringBuilder key
= new StringBuilder();
85 try (BufferedReader in
= new BufferedReader(reader
)) {
86 String line
= in
.readLine();
87 if (!"-----BEGIN PRIVATE KEY-----".equals(line
))
88 throw new IllegalArgumentException("Not a PEM private key");
89 lines
: while ((line
= in
.readLine()) != null) {
90 if ("-----END PRIVATE KEY-----".equals(line
))
96 byte[] encoded
= Base64
.getDecoder().decode(key
.toString());
98 KeyFactory keyFactory
= KeyFactory
.getInstance("RSA");
99 PKCS8EncodedKeySpec keySpec
= new PKCS8EncodedKeySpec(encoded
);
100 return (RSAPrivateKey
) keyFactory
.generatePrivate(keySpec
);
101 } catch (NoSuchAlgorithmException
| InvalidKeySpecException
| IOException e
) {
102 throw new RuntimeException("Cannot load PEM key", e
);
107 public static X509Certificate
loadPemCertificate(BufferedInputStream in
) {
109 CertificateFactory certificateFactory
= CertificateFactory
.getInstance("X509");
110 @SuppressWarnings("unchecked")
111 Collection
<X509Certificate
> certificates
= (Collection
<X509Certificate
>) certificateFactory
112 .generateCertificates(in
);
113 if (certificates
.isEmpty())
114 throw new IllegalArgumentException("No certificate found");
115 if (certificates
.size() != 1)
116 throw new IllegalArgumentException(certificates
.size() + " certificates found");
117 return certificates
.iterator().next();
118 } catch (CertificateException e
) {
119 throw new IllegalStateException("cannot load certifciate", e
);