1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.ssl;
17
18 import io.netty.internal.tcnative.SSL;
19 import io.netty5.buffer.api.BufferAllocator;
20
21 import javax.net.ssl.SSLException;
22 import javax.net.ssl.X509KeyManager;
23 import java.security.PrivateKey;
24 import java.security.cert.X509Certificate;
25
26 import static io.netty5.buffer.api.DefaultBufferAllocators.offHeapAllocator;
27 import static io.netty5.handler.ssl.ReferenceCountedOpenSslContext.toBIO;
28
29
30
31
32 class OpenSslKeyMaterialProvider {
33
34 private final X509KeyManager keyManager;
35 private final String password;
36
37 OpenSslKeyMaterialProvider(X509KeyManager keyManager, String password) {
38 this.keyManager = keyManager;
39 this.password = password;
40 }
41
42 static void validateKeyMaterialSupported(X509Certificate[] keyCertChain, PrivateKey key, String keyPassword)
43 throws SSLException {
44 validateSupported(keyCertChain);
45 validateSupported(key, keyPassword);
46 }
47
48 private static void validateSupported(PrivateKey key, String password) throws SSLException {
49 if (key == null) {
50 return;
51 }
52
53 long pkeyBio = 0;
54 long pkey = 0;
55
56 try {
57 pkeyBio = toBIO(key);
58 pkey = SSL.parsePrivateKey(pkeyBio, password);
59 } catch (Exception e) {
60 throw new SSLException("PrivateKey type not supported " + key.getFormat(), e);
61 } finally {
62 SSL.freeBIO(pkeyBio);
63 if (pkey != 0) {
64 SSL.freePrivateKey(pkey);
65 }
66 }
67 }
68
69 private static void validateSupported(X509Certificate[] certificates) throws SSLException {
70 if (certificates == null || certificates.length == 0) {
71 return;
72 }
73
74 long chainBio = 0;
75 long chain = 0;
76 BufferAllocator allocator = offHeapAllocator();
77 try (PemEncoded encoded = PemX509Certificate.toPEM(allocator, certificates)) {
78 chainBio = toBIO(allocator, encoded);
79 chain = SSL.parseX509Chain(chainBio);
80 } catch (Exception e) {
81 throw new SSLException("Certificate type not supported", e);
82 } finally {
83 SSL.freeBIO(chainBio);
84 if (chain != 0) {
85 SSL.freeX509Chain(chain);
86 }
87 }
88 }
89
90
91
92
93 X509KeyManager keyManager() {
94 return keyManager;
95 }
96
97
98
99
100
101 OpenSslKeyMaterial chooseKeyMaterial(BufferAllocator allocator, String alias) throws Exception {
102 X509Certificate[] certificates = keyManager.getCertificateChain(alias);
103 if (certificates == null || certificates.length == 0) {
104 return null;
105 }
106
107 PrivateKey key = keyManager.getPrivateKey(alias);
108 long chainBio = 0;
109 long pkeyBio = 0;
110 long chain = 0;
111 long pkey = 0;
112 try (PemEncoded encoded = PemX509Certificate.toPEM(allocator, certificates)) {
113 chainBio = toBIO(allocator, encoded);
114 chain = SSL.parseX509Chain(chainBio);
115
116 OpenSslKeyMaterial keyMaterial;
117 if (key instanceof OpenSslPrivateKey) {
118 keyMaterial = ((OpenSslPrivateKey) key).newKeyMaterial(chain, certificates);
119 } else {
120 pkeyBio = toBIO(key);
121 pkey = key == null ? 0 : SSL.parsePrivateKey(pkeyBio, password);
122 keyMaterial = new DefaultOpenSslKeyMaterial(chain, pkey, certificates);
123 }
124
125
126
127 chain = 0;
128 pkey = 0;
129 return keyMaterial;
130 } finally {
131 SSL.freeBIO(chainBio);
132 SSL.freeBIO(pkeyBio);
133 if (chain != 0) {
134 SSL.freeX509Chain(chain);
135 }
136 if (pkey != 0) {
137 SSL.freePrivateKey(pkey);
138 }
139 }
140 }
141
142
143
144
145 void destroy() {
146
147 }
148 }