1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.ssl;
17
18 import io.netty.buffer.ByteBufAllocator;
19 import io.netty.buffer.UnpooledByteBufAllocator;
20 import io.netty.internal.tcnative.SSL;
21
22 import javax.net.ssl.SSLException;
23 import javax.net.ssl.X509KeyManager;
24 import java.security.PrivateKey;
25 import java.security.cert.X509Certificate;
26
27 import static io.netty.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(UnpooledByteBufAllocator.DEFAULT, 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 PemEncoded encoded = null;
77 try {
78 encoded = PemX509Certificate.toPEM(UnpooledByteBufAllocator.DEFAULT, true, certificates);
79 chainBio = toBIO(UnpooledByteBufAllocator.DEFAULT, encoded.retain());
80 chain = SSL.parseX509Chain(chainBio);
81 } catch (Exception e) {
82 throw new SSLException("Certificate type not supported", e);
83 } finally {
84 SSL.freeBIO(chainBio);
85 if (chain != 0) {
86 SSL.freeX509Chain(chain);
87 }
88 if (encoded != null) {
89 encoded.release();
90 }
91 }
92 }
93
94
95
96
97 X509KeyManager keyManager() {
98 return keyManager;
99 }
100
101
102
103
104
105 OpenSslKeyMaterial chooseKeyMaterial(ByteBufAllocator allocator, String alias) throws Exception {
106 X509Certificate[] certificates = keyManager.getCertificateChain(alias);
107 if (certificates == null || certificates.length == 0) {
108 return null;
109 }
110
111 PrivateKey key = keyManager.getPrivateKey(alias);
112 PemEncoded encoded = PemX509Certificate.toPEM(allocator, true, certificates);
113 long chainBio = 0;
114 long pkeyBio = 0;
115 long chain = 0;
116 long pkey = 0;
117 try {
118 chainBio = toBIO(allocator, encoded.retain());
119 chain = SSL.parseX509Chain(chainBio);
120
121 OpenSslKeyMaterial keyMaterial;
122 if (key instanceof OpenSslPrivateKey) {
123 keyMaterial = ((OpenSslPrivateKey) key).newKeyMaterial(chain, certificates);
124 } else {
125 pkeyBio = toBIO(allocator, key);
126 pkey = key == null ? 0 : SSL.parsePrivateKey(pkeyBio, password);
127 keyMaterial = new DefaultOpenSslKeyMaterial(chain, pkey, certificates);
128 }
129
130
131
132 chain = 0;
133 pkey = 0;
134 return keyMaterial;
135 } finally {
136 SSL.freeBIO(chainBio);
137 SSL.freeBIO(pkeyBio);
138 if (chain != 0) {
139 SSL.freeX509Chain(chain);
140 }
141 if (pkey != 0) {
142 SSL.freePrivateKey(pkey);
143 }
144 encoded.release();
145 }
146 }
147
148
149
150
151 void destroy() {
152
153 }
154 }