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 boolean allowSignatureFallback)
44 throws SSLException {
45 validateSupported(keyCertChain);
46 validateSupported(key, keyPassword, allowSignatureFallback);
47 }
48
49 private static void validateSupported(PrivateKey key, String password,
50 boolean allowSignatureFallback) throws SSLException {
51 if (key == null) {
52 return;
53 }
54
55
56
57 if (key.getEncoded() == null && allowSignatureFallback) {
58 return;
59 }
60
61 long pkeyBio = 0;
62 long pkey = 0;
63
64 try {
65 pkeyBio = toBIO(UnpooledByteBufAllocator.DEFAULT, key);
66 pkey = SSL.parsePrivateKey(pkeyBio, password);
67 } catch (Exception e) {
68 throw new SSLException("PrivateKey type not supported " + key.getFormat(), e);
69 } finally {
70 SSL.freeBIO(pkeyBio);
71 if (pkey != 0) {
72 SSL.freePrivateKey(pkey);
73 }
74 }
75 }
76
77 private static void validateSupported(X509Certificate[] certificates) throws SSLException {
78 if (certificates == null || certificates.length == 0) {
79 return;
80 }
81
82 long chainBio = 0;
83 long chain = 0;
84 PemEncoded encoded = null;
85 try {
86 encoded = PemX509Certificate.toPEM(UnpooledByteBufAllocator.DEFAULT, true, certificates);
87 chainBio = toBIO(UnpooledByteBufAllocator.DEFAULT, encoded.retain());
88 chain = SSL.parseX509Chain(chainBio);
89 } catch (Exception e) {
90 throw new SSLException("Certificate type not supported", e);
91 } finally {
92 SSL.freeBIO(chainBio);
93 if (chain != 0) {
94 SSL.freeX509Chain(chain);
95 }
96 if (encoded != null) {
97 encoded.release();
98 }
99 }
100 }
101
102
103
104
105 X509KeyManager keyManager() {
106 return keyManager;
107 }
108
109
110
111
112
113 OpenSslKeyMaterial chooseKeyMaterial(ByteBufAllocator allocator, String alias) throws Exception {
114 X509Certificate[] certificates = keyManager.getCertificateChain(alias);
115 if (certificates == null || certificates.length == 0) {
116 return null;
117 }
118
119 PrivateKey key = keyManager.getPrivateKey(alias);
120 PemEncoded encoded = PemX509Certificate.toPEM(allocator, true, certificates);
121 long chainBio = 0;
122 long pkeyBio = 0;
123 long chain = 0;
124 long pkey = 0;
125 try {
126 chainBio = toBIO(allocator, encoded.retain());
127 chain = SSL.parseX509Chain(chainBio);
128
129 OpenSslKeyMaterial keyMaterial;
130 if (key instanceof OpenSslPrivateKey) {
131 keyMaterial = ((OpenSslPrivateKey) key).newKeyMaterial(chain, certificates);
132 } else {
133 pkeyBio = toBIO(allocator, key);
134 pkey = key == null ? 0 : SSL.parsePrivateKey(pkeyBio, password);
135 keyMaterial = new DefaultOpenSslKeyMaterial(chain, pkey, certificates);
136 }
137
138
139
140 chain = 0;
141 pkey = 0;
142 return keyMaterial;
143 } finally {
144 SSL.freeBIO(chainBio);
145 SSL.freeBIO(pkeyBio);
146 if (chain != 0) {
147 SSL.freeX509Chain(chain);
148 }
149 if (pkey != 0) {
150 SSL.freePrivateKey(pkey);
151 }
152 encoded.release();
153 }
154 }
155
156
157
158
159 void destroy() {
160
161 }
162 }