]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/runtime/PkiUtils.java
Improve ACR attribute typing.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / runtime / PkiUtils.java
1 package org.argeo.cms.internal.runtime;
2
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;
8 import java.io.Reader;
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;
27
28 /**
29 * Utilities around private keys and certificate, mostly wrapping BouncyCastle
30 * implementations.
31 */
32 class PkiUtils {
33 public static KeyStore getKeyStore(Path keyStoreFile, char[] keyStorePassword, String keyStoreType) {
34 try {
35 KeyStore store = KeyStore.getInstance(keyStoreType);
36 if (Files.exists(keyStoreFile)) {
37 try (InputStream fis = Files.newInputStream(keyStoreFile)) {
38 store.load(fis, keyStorePassword);
39 }
40 } else {
41 store.load(null);
42 }
43 return store;
44 } catch (GeneralSecurityException | IOException e) {
45 throw new RuntimeException("Cannot load keystore " + keyStoreFile, e);
46 }
47 }
48
49 public static void saveKeyStore(Path keyStoreFile, char[] keyStorePassword, KeyStore keyStore) {
50 try {
51 try (OutputStream fis = Files.newOutputStream(keyStoreFile)) {
52 keyStore.store(fis, keyStorePassword);
53 }
54 } catch (GeneralSecurityException | IOException e) {
55 throw new RuntimeException("Cannot save keystore " + keyStoreFile, e);
56 }
57 }
58
59 public static void loadPrivateCertificatePem(KeyStore keyStore, String alias, Reader key, char[] keyPassword,
60 BufferedInputStream cert) {
61 Objects.requireNonNull(keyStore);
62 Objects.requireNonNull(key);
63 try {
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);
69 }
70 }
71
72 public static void loadTrustedCertificatePem(KeyStore keyStore, char[] keyStorePassword, BufferedInputStream cert) {
73 try {
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);
79 }
80 }
81
82 public static PrivateKey loadPemPrivateKey(Reader reader, char[] keyPassword) {
83 try {
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))
91 break lines;
92 key.append(line);
93 }
94 }
95
96 byte[] encoded = Base64.getDecoder().decode(key.toString());
97
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);
103 }
104
105 }
106
107 public static X509Certificate loadPemCertificate(BufferedInputStream in) {
108 try {
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);
120 }
121 }
122 }