1 module hunt.net.secure.conscrypt.OpenSSLKey;
2 
3 // // dfmt off
4 // version(WITH_HUNT_SECURITY):
5 // // dfmt on
6 
7 // import hunt.net.secure.conscrypt.NativeCrypto;
8 // import hunt.net.secure.conscrypt.NativeRef;
9 // import hunt.net.secure.conscrypt.OpenSSLKeyHolder;
10 
11 // import hunt.security.Key;
12 
13 // import hunt.Exceptions;
14 // import hunt.text.Common;
15 
16 // /**
17 //  * Represents a BoringSSL {@code EVP_PKEY}.
18 //  */
19 // final class OpenSSLKey {
20 //     private NativeRef.EVP_PKEY ctx;
21 
22 //     private bool wrapped;
23 
24 //     this(long ctx) {
25 //         this(ctx, false);
26 //     }
27 
28 //     this(long ctx, bool wrapped) {
29 //         this.ctx = new NativeRef.EVP_PKEY(ctx);
30 //         this.wrapped = wrapped;
31 //     }
32 
33 //     /**
34 //      * Returns the EVP_PKEY context for use in JNI calls.
35 //      */
36 //     NativeRef.EVP_PKEY getNativeRef() {
37 //         return ctx;
38 //     }
39 
40 //     bool isWrapped() {
41 //         return wrapped;
42 //     }
43 
44 //     // static OpenSSLKey fromPrivateKey(PrivateKey key) {
45 //     //     if (key instanceof OpenSSLKeyHolder) {
46 //     //         return ((OpenSSLKeyHolder) key).getOpenSSLKey();
47 //     //     }
48 
49 //     //     string keyFormat = key.getFormat();
50 //     //     if (keyFormat is null) {
51 //     //         return wrapPrivateKey(key);
52 //     //     } else if (!"PKCS#8".equals(key.getFormat())) {
53 //     //         throw new InvalidKeyException("Unknown key format " ~ keyFormat);
54 //     //     }
55 
56 //     //     byte[] encoded = key.getEncoded();
57 //     //     if (encoded is null) {
58 //     //         throw new InvalidKeyException("Key encoding is null");
59 //     //     }
60 
61 //     //     try {
62 //     //         return new OpenSSLKey(NativeCrypto.EVP_parse_private_key(key.getEncoded()));
63 //     //     } catch (ParsingException e) {
64 //     //         throw new InvalidKeyException(e);
65 //     //     }
66 //     // }
67 
68 //     // /**
69 //     //  * Parse a private key in PEM encoding from the provided input stream.
70 //     //  *
71 //     //  * @throws InvalidKeyException if parsing fails
72 //     //  */
73 //     // static OpenSSLKey fromPrivateKeyPemInputStream(InputStream is)
74 //     //         {
75 //     //     OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
76 //     //     try {
77 //     //         long keyCtx = NativeCrypto.PEM_read_bio_PrivateKey(bis.getBioContext());
78 //     //         if (keyCtx == 0L) {
79 //     //             return null;
80 //     //         }
81 
82 //     //         return new OpenSSLKey(keyCtx);
83 //     //     } catch (Exception e) {
84 //     //         throw new InvalidKeyException(e);
85 //     //     } finally {
86 //     //         bis.release();
87 //     //     }
88 //     // }
89 
90 //     /**
91 //      * Gets an {@code OpenSSLKey} instance backed by the provided private key. The resulting key is
92 //      * usable only by this provider's TLS/SSL stack.
93 //      *
94 //      * @param privateKey private key.
95 //      * @param publicKey corresponding key or {@code null} if not available. Some opaque
96 //      *        private keys cannot be used by the TLS/SSL stack without the key.
97 //      */
98 //     // static OpenSSLKey fromPrivateKeyForTLSStackOnly(
99 //     //         PrivateKey privateKey, PublicKey publicKey) {
100 //     //     OpenSSLKey result = getOpenSSLKey(privateKey);
101 //     //     if (result !is null) {
102 //     //         return result;
103 //     //     }
104 
105 //     //     result = fromKeyMaterial(privateKey);
106 //     //     if (result !is null) {
107 //     //         return result;
108 //     //     }
109 
110 //     //     return wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
111 //     // }
112 
113 //     // /**
114 //     //  * Gets an {@code OpenSSLKey} instance backed by the provided EC private key. The resulting key
115 //     //  * is usable only by this provider's TLS/SSL stack.
116 //     //  *
117 //     //  * @param key private key.
118 //     //  * @param ecParams EC parameters {@code null} if not available. Some opaque private keys cannot
119 //     //  *        be used by the TLS/SSL stack without the parameters because the private key itself
120 //     //  *        might not expose the parameters.
121 //     //  */
122 //     // static OpenSSLKey fromECPrivateKeyForTLSStackOnly(
123 //     //         PrivateKey key, ECParameterSpec ecParams) {
124 //     //     OpenSSLKey result = getOpenSSLKey(key);
125 //     //     if (result !is null) {
126 //     //         return result;
127 //     //     }
128 
129 //     //     result = fromKeyMaterial(key);
130 //     //     if (result !is null) {
131 //     //         return result;
132 //     //     }
133 
134 //     //     return OpenSSLECPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(key, ecParams);
135 //     // }
136 
137 //     /**
138 //      * Gets the {@code OpenSSLKey} instance of the provided key.
139 //      *
140 //      * @return instance or {@code null} if the {@code key} is not backed by OpenSSL's
141 //      *         {@code EVP_PKEY}.
142 //      */
143 //     // private static OpenSSLKey getOpenSSLKey(PrivateKey key) {
144 //     //     OpenSSLKeyHolder keyHolder = cast(OpenSSLKeyHolder) key;
145 //     //     if (keyHolder !is null) {
146 //     //         return keyHolder.getOpenSSLKey();
147 //     //     }
148 
149 //     //     if ("RSA" == key.getAlgorithm()) {
150 //     //         implementationMissing(false);
151 //     //         // return Platform.wrapRsaKey(key);
152 //     //     }
153 
154 //     //     return null;
155 //     // }
156 
157 //     /**
158 //      * Gets an {@code OpenSSLKey} instance initialized with the key material of the provided key.
159 //      *
160 //      * @return instance or {@code null} if the {@code key} does not export its key material in a
161 //      *         suitable format.
162 //      */
163 //     // private static OpenSSLKey fromKeyMaterial(PrivateKey key) {
164 //     //     if (!"PKCS#8".equals(key.getFormat())) {
165 //     //         return null;
166 //     //     }
167 //     //     byte[] encoded = key.getEncoded();
168 //     //     if (encoded is null) {
169 //     //         return null;
170 //     //     }
171 //     //     try {
172 //     //         version(Have_boringssl) return new OpenSSLKey(NativeCrypto.EVP_parse_private_key(encoded));
173 //     //         version(Have_hunt_openssl) {
174 //     //             implementationMissing(false);
175 //     //             return null;
176 //     //         }
177 //     //     } catch (ParsingException e) {
178 //     //         throw new InvalidKeyException(e.msg);
179 //     //     }
180 //     // }
181 
182 //     /**
183 //      * Wraps the provided private key for use in the TLS/SSL stack only. Sign/decrypt operations
184 //      * using the key will be delegated to the {@code Signature}/{@code Cipher} implementation of the
185 //      * provider which accepts the key.
186 //      */
187 //     // private static OpenSSLKey wrapJCAPrivateKeyForTLSStackOnly(PrivateKey privateKey,
188 //     //         PublicKey publicKey) {
189 //     //     string keyAlgorithm = privateKey.getAlgorithm();
190 //     //     implementationMissing(false);
191 //     //     return null;
192 //     //     // if ("RSA".equals(keyAlgorithm)) {
193 //     //     //     return OpenSSLRSAPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
194 //     //     // } else if ("EC".equals(keyAlgorithm)) {
195 //     //     //     return OpenSSLECPrivateKey.wrapJCAPrivateKeyForTLSStackOnly(privateKey, publicKey);
196 //     //     // } else {
197 //     //     //     throw new InvalidKeyException("Unsupported key algorithm: " ~ keyAlgorithm);
198 //     //     // }
199 //     // }
200 
201 //     // private static OpenSSLKey wrapPrivateKey(PrivateKey key) {
202 //     //     if (key instanceof RSAPrivateKey) {
203 //     //         return OpenSSLRSAPrivateKey.wrapPlatformKey((RSAPrivateKey) key);
204 //     //     } else if (key instanceof ECPrivateKey) {
205 //     //         return OpenSSLECPrivateKey.wrapPlatformKey((ECPrivateKey) key);
206 //     //     } else {
207 //     //         throw new InvalidKeyException("Unknown key type: " ~ key.toString());
208 //     //     }
209 //     // }
210 
211 //     // static OpenSSLKey fromPublicKey(PublicKey key) {
212 //     //     if (key instanceof OpenSSLKeyHolder) {
213 //     //         return ((OpenSSLKeyHolder) key).getOpenSSLKey();
214 //     //     }
215 
216 //     //     if (!"X.509".equals(key.getFormat())) {
217 //     //         throw new InvalidKeyException("Unknown key format " ~ key.getFormat());
218 //     //     }
219 
220 //     //     byte[] encoded = key.getEncoded();
221 //     //     if (encoded is null) {
222 //     //         throw new InvalidKeyException("Key encoding is null");
223 //     //     }
224 
225 //     //     try {
226 //     //         return new OpenSSLKey(NativeCrypto.EVP_parse_public_key(key.getEncoded()));
227 //     //     } catch (Exception e) {
228 //     //         throw new InvalidKeyException(e);
229 //     //     }
230 //     // }
231 
232 //     // /**
233 //     //  * Parse a key in PEM encoding from the provided input stream.
234 //     //  *
235 //     //  * @throws InvalidKeyException if parsing fails
236 //     //  */
237 //     // static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
238 //     //         {
239 //     //     OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
240 //     //     try {
241 //     //         long keyCtx = NativeCrypto.PEM_read_bio_PUBKEY(bis.getBioContext());
242 //     //         if (keyCtx == 0L) {
243 //     //             return null;
244 //     //         }
245 
246 //     //         return new OpenSSLKey(keyCtx);
247 //     //     } catch (Exception e) {
248 //     //         throw new InvalidKeyException(e);
249 //     //     } finally {
250 //     //         bis.release();
251 //     //     }
252 //     // }
253 
254 //     // PublicKey getPublicKey() throws NoSuchAlgorithmException {
255 //     //     switch (NativeCrypto.EVP_PKEY_type(ctx)) {
256 //     //         case NativeConstants.EVP_PKEY_RSA:
257 //     //             return new OpenSSLRSAPublicKey(this);
258 //     //         case NativeConstants.EVP_PKEY_EC:
259 //     //             return new OpenSSLECPublicKey(this);
260 //     //         default:
261 //     //             throw new NoSuchAlgorithmException("unknown PKEY type");
262 //     //     }
263 //     // }
264 
265 //     // static PublicKey getPublicKey(X509EncodedKeySpec keySpec, int type)
266 //     //         throws InvalidKeySpecException {
267 //     //     X509EncodedKeySpec x509KeySpec = keySpec;
268 
269 //     //     OpenSSLKey key;
270 //     //     try {
271 //     //         key = new OpenSSLKey(NativeCrypto.EVP_parse_public_key(x509KeySpec.getEncoded()));
272 //     //     } catch (Exception e) {
273 //     //         throw new InvalidKeySpecException(e);
274 //     //     }
275 
276 //     //     if (NativeCrypto.EVP_PKEY_type(key.getNativeRef()) != type) {
277 //     //         throw new InvalidKeySpecException("Unexpected key type");
278 //     //     }
279 
280 //     //     try {
281 //     //         return key.getPublicKey();
282 //     //     } catch (NoSuchAlgorithmException e) {
283 //     //         throw new InvalidKeySpecException(e);
284 //     //     }
285 //     // }
286 
287 //     // PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
288 //     //     switch (NativeCrypto.EVP_PKEY_type(ctx)) {
289 //     //         case NativeConstants.EVP_PKEY_RSA:
290 //     //             return new OpenSSLRSAPrivateKey(this);
291 //     //         case NativeConstants.EVP_PKEY_EC:
292 //     //             return new OpenSSLECPrivateKey(this);
293 //     //         default:
294 //     //             throw new NoSuchAlgorithmException("unknown PKEY type");
295 //     //     }
296 //     // }
297 
298 //     // static PrivateKey getPrivateKey(PKCS8EncodedKeySpec keySpec, int type)
299 //     //         throws InvalidKeySpecException {
300 //     //     PKCS8EncodedKeySpec pkcs8KeySpec = keySpec;
301 
302 //     //     OpenSSLKey key;
303 //     //     try {
304 //     //         key = new OpenSSLKey(NativeCrypto.EVP_parse_private_key(pkcs8KeySpec.getEncoded()));
305 //     //     } catch (Exception e) {
306 //     //         throw new InvalidKeySpecException(e);
307 //     //     }
308 
309 //     //     if (NativeCrypto.EVP_PKEY_type(key.getNativeRef()) != type) {
310 //     //         throw new InvalidKeySpecException("Unexpected key type");
311 //     //     }
312 
313 //     //     try {
314 //     //         return key.getPrivateKey();
315 //     //     } catch (NoSuchAlgorithmException e) {
316 //     //         throw new InvalidKeySpecException(e);
317 //     //     }
318 //     // }
319 
320 //     // override
321 //     // bool equals(Object o) {
322 //     //     if (o == this) {
323 //     //         return true;
324 //     //     }
325 
326 //     //     if (!(o instanceof OpenSSLKey)) {
327 //     //         return false;
328 //     //     }
329 
330 //     //     OpenSSLKey other = (OpenSSLKey) o;
331 //     //     if (ctx.equals(other.getNativeRef())) {
332 //     //         return true;
333 //     //     }
334 
335 //     //     return NativeCrypto.EVP_PKEY_cmp(ctx, other.getNativeRef()) == 1;
336 //     // }
337 
338 //     // override
339 //     // int hashCode() {
340 //     //     return ctx.hashCode();
341 //     // }
342 // }