xref: /aosp_15_r20/external/aws-crt-java/src/main/java/software/amazon/awssdk/crt/io/TlsContextOptions.java (revision 3c7ae9de214676c52d19f01067dc1a404272dc11)
1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 package software.amazon.awssdk.crt.io;
6 
7 import java.util.ArrayList;
8 import java.util.IllegalFormatException;
9 import java.util.List;
10 import java.util.function.Consumer;
11 
12 import software.amazon.awssdk.crt.CrtResource;
13 import software.amazon.awssdk.crt.CrtRuntimeException;
14 import software.amazon.awssdk.crt.utils.PemUtils;
15 import software.amazon.awssdk.crt.utils.StringUtils;
16 
17 /**
18  * This class wraps the aws_tls_connection_options from aws-c-io to provide
19  * access to TLS configuration contexts in the AWS Common Runtime.
20  */
21 public final class TlsContextOptions extends CrtResource {
22 
23     public enum TlsVersions {
24         /**
25          * SSL v3. This should almost never be used.
26          */
27         SSLv3(0),
28         TLSv1(1),
29         /**
30          * TLS 1.1
31          */
32         TLSv1_1(2),
33         /**
34          * TLS 1.2
35          */
36         TLSv1_2(3),
37         /**
38          * TLS 1.3
39          */
40         TLSv1_3(4),
41         /**
42          * Use whatever the system default is. This is usually the best option, as it will be automatically updated
43          * as the underlying OS or platform changes.
44          */
45         TLS_VER_SYS_DEFAULTS(128);
46 
47         private int version;
TlsVersions(int val)48         TlsVersions(int val) {
49             version = val;
50         }
51 
getValue()52         int getValue() { return version; }
53     }
54 
55     /**
56      * Sets the minimum acceptable TLS version that the {@link TlsContext} will
57      * allow. Not compatible with setCipherPreference() API.
58      *
59      * Select from TlsVersions, a good default is TlsVersions.TLS_VER_SYS_DEFAULTS
60      * as this will update if the OS TLS is updated
61      */
62     public TlsVersions minTlsVersion = TlsVersions.TLS_VER_SYS_DEFAULTS;
63     /**
64      * Sets the TLS Cipher Preferences that can be negotiated and used during the
65      * TLS Connection. Not compatible with setMinimumTlsVersion() API.
66      *
67      */
68     public TlsCipherPreference tlsCipherPreference = TlsCipherPreference.TLS_CIPHER_SYSTEM_DEFAULT;
69     /**
70      * Sets the ALPN protocol list that will be provided when a TLS connection
71      * starts e.g. "x-amzn-mqtt-ca"
72      */
73     public List<String> alpnList = new ArrayList<>();
74     /**
75      * Set whether or not the peer should be verified. Default is true for clients,
76      * and false for servers. If you are in a development or debugging environment,
77      * you can disable this to avoid or diagnose trust store issues. This should
78      * always be true on clients in the wild. If you set this to true on a server,
79      * it will validate every client connection.
80      */
81     public boolean verifyPeer = false;
82 
83     private String certificate;
84     private String privateKey;
85     private String certificatePath;
86     private String privateKeyPath;
87     private String caRoot;
88     private String caFile;
89     private String caDir;
90     private String pkcs12Path;
91     private String pkcs12Password;
92     private TlsContextPkcs11Options pkcs11Options;
93     private TlsContextCustomKeyOperationOptions customKeyOperations;
94     private String windowsCertStorePath;
95 
96     /**
97      * Creates a new set of options that can be used to create a {@link TlsContext}
98      */
TlsContextOptions()99     private TlsContextOptions() {
100 
101     }
102 
103     @Override
getNativeHandle()104     public long getNativeHandle() {
105         if (super.getNativeHandle() == 0) {
106             if (tlsCipherPreference != TlsCipherPreference.TLS_CIPHER_SYSTEM_DEFAULT
107                     && minTlsVersion != TlsVersions.TLS_VER_SYS_DEFAULTS) {
108                 throw new IllegalStateException("tlsCipherPreference and minTlsVersion are mutually exclusive");
109             }
110             acquireNativeHandle(tlsContextOptionsNew(
111                 minTlsVersion.getValue(),
112                 tlsCipherPreference.getValue(),
113                 alpnList.size() > 0 ? StringUtils.join(";", alpnList) : null,
114                 certificate,
115                 privateKey,
116                 certificatePath,
117                 privateKeyPath,
118                 caRoot,
119                 caFile,
120                 caDir,
121                 verifyPeer,
122                 pkcs12Path,
123                 pkcs12Password,
124                 pkcs11Options,
125                 customKeyOperations,
126                 windowsCertStorePath
127             ));
128         }
129         return super.getNativeHandle();
130     }
131 
132     /**
133      * Determines whether a resource releases its dependencies at the same time the native handle is released or if it waits.
134      * Resources that wait are responsible for calling releaseReferences() manually.
135      */
136     @Override
canReleaseReferencesImmediately()137     protected boolean canReleaseReferencesImmediately() { return true; }
138 
139     /**
140      * Frees the native resources associated with this instance
141      */
142     @Override
releaseNativeHandle()143     protected void releaseNativeHandle() {
144         // It is perfectly acceptable for this to have never created a native resource
145         if (!isNull()) {
146             tlsContextOptionsDestroy(getNativeHandle());
147         }
148     }
149 
150     /**
151      * Sets the TLS cipher preferences to use in contexts using this configuration
152      * @param cipherPref cipher preferences to use
153      */
setCipherPreference(TlsCipherPreference cipherPref)154     public void setCipherPreference(TlsCipherPreference cipherPref) {
155         if(!isCipherPreferenceSupported(cipherPref)) {
156             throw new IllegalArgumentException("TlsCipherPreference is not supported on this platform: " + cipherPref.name());
157         }
158 
159         if (this.minTlsVersion != TlsVersions.TLS_VER_SYS_DEFAULTS && cipherPref != TlsCipherPreference.TLS_CIPHER_SYSTEM_DEFAULT) {
160             throw new IllegalArgumentException("Currently only setMinimumTlsVersion() or setCipherPreference() may be used, not both.");
161         }
162 
163         this.tlsCipherPreference = cipherPref;
164     }
165 
166     /**
167      * Sets the path to the certificate that identifies this mutual TLS (mTLS) host. Must be in PEM format.
168      * @param certificatePath Path to PEM format certificate
169      * @param privateKeyPath Path to PEM format private key
170      */
initMtlsFromPath(String certificatePath, String privateKeyPath)171     public void initMtlsFromPath(String certificatePath, String privateKeyPath) {
172         this.certificatePath = certificatePath;
173         this.privateKeyPath = privateKeyPath;
174     }
175 
176     /**
177      * Sets the certificate/key pair that identifies this mutual TLS (mTLS) host. Must be in
178      * PEM format.
179      *
180      * @param certificate PEM armored certificate
181      * @param privateKey  PEM armored private key
182      * @throws IllegalArgumentException If the certificate or privateKey are not in PEM format or if they contain chains
183      */
initMtls(String certificate, String privateKey)184     public void initMtls(String certificate, String privateKey) throws IllegalArgumentException {
185         this.certificate = PemUtils.cleanUpPem(certificate);
186         PemUtils.sanityCheck(certificate, 1, "CERTIFICATE");
187 
188         this.privateKey = PemUtils.cleanUpPem(privateKey);
189         PemUtils.sanityCheck(privateKey, 1, "PRIVATE KEY");
190     }
191 
192     /**
193      * Apple platforms only - Initializes mutual TLS (mTLS) with PKCS12 file and password
194      * @param pkcs12Path Path to PKCS12 file
195      * @param pkcs12Password PKCS12 password
196      */
initMtlsPkcs12(String pkcs12Path, String pkcs12Password)197     public void initMtlsPkcs12(String pkcs12Path, String pkcs12Password) {
198         if (this.certificate != null || this.privateKey != null || this.certificatePath != null
199                 || this.privateKeyPath != null) {
200             throw new IllegalArgumentException(
201                     "PKCS#12 and mTLS via certificate/private key pair are mutually exclusive");
202         }
203         this.pkcs12Path = pkcs12Path;
204         this.pkcs12Password = pkcs12Password;
205     }
206 
207     /**
208      * Returns whether or not ALPN is supported on the current platform
209      * @return true if ALPN is supported, false otherwise
210      */
isAlpnSupported()211     public static boolean isAlpnSupported() {
212         return tlsContextOptionsIsAlpnAvailable();
213     }
214 
215     /**
216      * Returns whether or not the current platform can be configured to a specific TlsCipherPreference.
217      * @param cipherPref The TlsCipherPreference to check
218      * @return True if the current platform does support this TlsCipherPreference, false otherwise
219      */
isCipherPreferenceSupported(TlsCipherPreference cipherPref)220     public static boolean isCipherPreferenceSupported(TlsCipherPreference cipherPref) {
221         return tlsContextOptionsIsCipherPreferenceSupported(cipherPref.getValue());
222     }
223 
224     /**
225      * Helper function to provide a TlsContext-local trust store
226      * @param caPath Path to the local trust store. Can be null.
227      * @param caFile Path to the root certificate. Must be in PEM format.
228      */
overrideDefaultTrustStoreFromPath(String caPath, String caFile)229     public void overrideDefaultTrustStoreFromPath(String caPath, String caFile) {
230         if (this.caRoot != null) {
231             throw new IllegalArgumentException("Certificate authority is already specified via PEM buffer");
232         }
233         this.caDir = caPath;
234         this.caFile = caFile;
235     }
236 
237     /**
238      * Helper function to provide a TlsContext-local trust store
239      *
240      * @param caRoot Buffer containing the root certificate chain. Must be in PEM format.
241      * @throws IllegalArgumentException if the CA Root PEM file is malformed
242      */
overrideDefaultTrustStore(String caRoot)243     public void overrideDefaultTrustStore(String caRoot) throws IllegalArgumentException {
244         if (this.caFile != null || this.caDir != null) {
245             throw new IllegalArgumentException("Certificate authority is already specified via path(s)");
246         }
247         this.caRoot = PemUtils.cleanUpPem(caRoot);
248         // 1024 certs in the chain is the default supported by s2n:
249         PemUtils.sanityCheck(this.caRoot, 1024, "CERTIFICATE");
250     }
251 
252     /**
253      * Helper which creates a default set of TLS options for the current platform
254      * @return A default configured set of options for a TLS client connection
255      */
createDefaultClient()256     public static TlsContextOptions createDefaultClient() {
257         TlsContextOptions options = new TlsContextOptions();
258         options.verifyPeer = true;
259         return options;
260     }
261 
262     /**
263      * Helper which creates a default set of TLS options for the current platform
264      *
265      * @return A default configured set of options for a TLS server connection
266      */
createDefaultServer()267     public static TlsContextOptions createDefaultServer() {
268         TlsContextOptions options = new TlsContextOptions();
269         options.verifyPeer = false;
270         return options;
271     }
272 
273     /**
274      * Helper which creates mutual TLS (mTLS) options using a certificate and private key
275      * @param certificatePath Path to a PEM format certificate
276      * @param privateKeyPath Path to a PEM format private key
277      * @return A set of options for setting up an mTLS connection
278      */
createWithMtlsFromPath(String certificatePath, String privateKeyPath)279     public static TlsContextOptions createWithMtlsFromPath(String certificatePath, String privateKeyPath) {
280         TlsContextOptions options = new TlsContextOptions();
281         options.initMtlsFromPath(certificatePath, privateKeyPath);
282         options.verifyPeer = true;
283         return options;
284     }
285 
286     /**
287      * Helper which creates mutual TLS (mTLS) options using a certificate and private key
288      *
289      * @param certificate String containing a PEM format certificate
290      * @param privateKey  String containing a PEM format private key
291      * @return A set of options for setting up an mTLS connection
292      * @throws IllegalArgumentException If either PEM fails to parse
293      */
createWithMtls(String certificate, String privateKey)294     public static TlsContextOptions createWithMtls(String certificate, String privateKey)
295             throws IllegalArgumentException {
296         TlsContextOptions options = new TlsContextOptions();
297         options.initMtls(certificate, privateKey);
298         options.verifyPeer = true;
299         return options;
300     }
301 
302     /**
303      * Apple platforms only - Helper which creates mutual TLS (mTLS) options using PKCS12
304      * @param pkcs12Path The path to a PKCS12 file @see #setPkcs12Path(String)
305      * @param pkcs12Password The PKCS12 password @see #setPkcs12Password(String)
306      * @return A set of options for creating a PKCS12 mTLS connection
307      */
createWithMtlsPkcs12(String pkcs12Path, String pkcs12Password)308     public static TlsContextOptions createWithMtlsPkcs12(String pkcs12Path, String pkcs12Password) {
309         TlsContextOptions options = new TlsContextOptions();
310         options.initMtlsPkcs12(pkcs12Path, pkcs12Password);
311         options.verifyPeer = true;
312         return options;
313     }
314 
315     /**
316      * Unix platforms only - Helper which creates mutual TLS (mTLS) options using a PKCS#11 library for private key operations.
317      * @param pkcs11Options PKCS#11 options
318      * @return A set of options for creating a PKCS#11 mTLS connection
319      */
createWithMtlsPkcs11(TlsContextPkcs11Options pkcs11Options)320     public static TlsContextOptions createWithMtlsPkcs11(TlsContextPkcs11Options pkcs11Options) {
321         TlsContextOptions options = new TlsContextOptions();
322         options.withMtlsPkcs11(pkcs11Options);
323         options.verifyPeer = true;
324         return options;
325     }
326 
327     /**
328      * Unix platforms only - Helper which creates mutual TLS (mTLS) options using the applied custom key operations. This
329      * allows you to perform custom private key operations such as signing and decrypting. This is necessary if you
330      * require an external library to handle private key operations.
331      *
332      * @param custom The options for the custom private key operations
333      * @return A set of options for creating a custom key operation mTLS connection
334      */
createWithMtlsCustomKeyOperations(TlsContextCustomKeyOperationOptions custom)335     public static TlsContextOptions createWithMtlsCustomKeyOperations(TlsContextCustomKeyOperationOptions custom) {
336         TlsContextOptions options = new TlsContextOptions();
337         options.withMtlsCustomKeyOperations(custom);
338         options.verifyPeer = true;
339         return options;
340     }
341 
342      /**
343      * Windows platforms only - Helper which creates mutual TLS (mTLS) options using a
344      * certificate in a Windows certificate store.
345      *
346      * @param certificatePath Path to certificate in a Windows certificate store.
347      *                        The path must use backslashes and end with the
348      *                        certificate's thumbprint. Example:
349      *                        {@code CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6}
350      * @return A set of options for setting up an mTLS connection
351      */
createWithMtlsWindowsCertStorePath(String certificatePath)352     public static TlsContextOptions createWithMtlsWindowsCertStorePath(String certificatePath) {
353         TlsContextOptions options = new TlsContextOptions();
354         options.withMtlsWindowsCertStorePath(certificatePath);
355         options.verifyPeer = true;
356         return options;
357     }
358 
359     /**
360      * Helper which creates mutual TLS (mTLS) options using a certificate and private key
361      * stored in a Java keystore.
362      * Will throw an exception if there is no certificate and key at the given certificate alias, or there is some other
363      * error accessing or using the passed-in Java keystore.
364      *
365      * Note: function assumes the passed keystore has already been loaded from a file by calling "keystore.load()" or similar.
366      *
367      * @param keyStore The Java keystore to use. Assumed to be loaded with the desired certificate and key
368      * @param certificateAlias The alias of the certificate and key to use.
369      * @param certificatePassword The password of the certificate and key to use.
370      * @throws CrtRuntimeException if the certificate alias does not exist or the certificate/key cannot be found in the certificate alias
371      * @return A set of options for setting up an mTLS connection
372      */
createWithMtlsJavaKeystore( java.security.KeyStore keyStore, String certificateAlias, String certificatePassword)373     public static TlsContextOptions createWithMtlsJavaKeystore(
374         java.security.KeyStore keyStore, String certificateAlias, String certificatePassword) {
375 
376         TlsContextOptions options = new TlsContextOptions();
377         String certificate;
378         try {
379             java.security.cert.Certificate certificateData = keyStore.getCertificate(certificateAlias);
380             if (certificateData == null) {
381                 throw new CrtRuntimeException("Certificate at given certificate alias does not exist or does not contain a certificate");
382             }
383             String certificateString = new String(StringUtils.base64Encode(certificateData.getEncoded()));
384             certificate = "-----BEGIN CERTIFICATE-----\n" + certificateString + "-----END CERTIFICATE-----\n";
385         } catch (java.security.KeyStoreException | java.security.cert.CertificateEncodingException ex) {
386             throw new RuntimeException("Failed to get certificate from Java keystore", ex);
387         }
388         String privateKey;
389         try {
390             java.security.Key keyData = keyStore.getKey(certificateAlias, certificatePassword.toCharArray());
391             if (keyData == null) {
392                 throw new CrtRuntimeException("Private key at given certificate alias does not exist or does not identify a key-related entity");
393             }
394             String keyString = new String(StringUtils.base64Encode(keyData.getEncoded()));
395             privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" + keyString + "-----END RSA PRIVATE KEY-----\n";
396         } catch (java.security.KeyStoreException | java.security.NoSuchAlgorithmException | java.security.UnrecoverableKeyException ex) {
397             throw new RuntimeException("Failed to get private key from Java keystore", ex);
398         }
399         options.initMtls(certificate, privateKey);
400         options.verifyPeer = true;
401         return options;
402     }
403 
404     /*******************************************************************************
405      * .with() methods
406      ******************************************************************************/
407 
408     /**
409      * Sets the ciphers that the TlsContext will be able to use
410      * @param cipherPref The preference set of ciphers to use
411      * @return this
412      */
withCipherPreference(TlsCipherPreference cipherPref)413     public TlsContextOptions withCipherPreference(TlsCipherPreference cipherPref) {
414         setCipherPreference(cipherPref);
415         return this;
416     }
417 
418     /**
419      * Sets the minimum TLS version that the TlsContext will allow. Defaults to
420      * OS defaults.
421      * @param version Minimum acceptable TLS version
422      * @return this
423      */
withMinimumTlsVersion(TlsVersions version)424     public TlsContextOptions withMinimumTlsVersion(TlsVersions version) {
425         minTlsVersion = version;
426         return this;
427     }
428 
429     /**
430      * Sets the ALPN protocols list for any connections using this TlsContext
431      * @param alpnList Semi-colon delimited list of supported ALPN protocols
432      * @return this
433      */
withAlpnList(String alpnList)434     public TlsContextOptions withAlpnList(String alpnList) {
435         String[] parts = alpnList.split(";");
436         for (String part : parts) {
437             this.alpnList.add(part);
438         }
439         return this;
440     }
441 
442     /**
443      * Enables mutual TLS (mTLS) on this TlsContext
444      * @param certificate mTLS certificate, in PEM format
445      * @param privateKey mTLS private key, in PEM format
446      * @return this
447      */
withMtls(String certificate, String privateKey)448     public TlsContextOptions withMtls(String certificate, String privateKey) {
449         this.initMtls(certificate, privateKey);
450         return this;
451     }
452 
453     /**
454      * Enables mutual TLS (mTLS) on this TlsContext
455      * @param certificatePath path to mTLS certificate, in PEM format
456      * @param privateKeyPath path to mTLS private key, in PEM format
457      * @return this
458      */
withMtlsFromPath(String certificatePath, String privateKeyPath)459     public TlsContextOptions withMtlsFromPath(String certificatePath, String privateKeyPath) {
460         this.initMtlsFromPath(certificatePath, privateKeyPath);
461         return this;
462     }
463 
464     /**
465      * Specifies the certificate authority to use. By default, the OS CA repository will be used.
466      * @param caRoot Certificate Authority, in PEM format
467      * @return this
468      */
withCertificateAuthority(String caRoot)469     public TlsContextOptions withCertificateAuthority(String caRoot) {
470         this.overrideDefaultTrustStore(caRoot);
471         return this;
472     }
473 
474     /**
475      * Specifies the certificate authority to use.
476      * @param caDirPath Path to certificate directory, e.g. /etc/ssl/certs
477      * @param caFilePath Path to ceritificate authority, in PEM format
478      * @return this
479      */
withCertificateAuthorityFromPath(String caDirPath, String caFilePath)480     public TlsContextOptions withCertificateAuthorityFromPath(String caDirPath, String caFilePath) {
481         this.overrideDefaultTrustStoreFromPath(caDirPath, caFilePath);
482         return this;
483     }
484 
485     /**
486      * Apple platforms only, specifies mutual TLS (mTLS) using PKCS#12
487      * @param pkcs12Path Path to PKCS#12 certificate, in PEM format
488      * @param pkcs12Password PKCS#12 password
489      * @return this
490      */
withMtlsPkcs12(String pkcs12Path, String pkcs12Password)491     public TlsContextOptions withMtlsPkcs12(String pkcs12Path, String pkcs12Password) {
492         this.initMtlsPkcs12(pkcs12Path, pkcs12Password);
493         return this;
494     }
495 
496     /**
497      * Unix platforms only, specifies mutual TLS (mTLS) using a PKCS#11 library for private key operations.
498      * @param pkcs11Options PKCS#11 options
499      * @return this
500      */
withMtlsPkcs11(TlsContextPkcs11Options pkcs11Options)501     public TlsContextOptions withMtlsPkcs11(TlsContextPkcs11Options pkcs11Options) {
502         swapReferenceTo(this.pkcs11Options, pkcs11Options);
503         this.pkcs11Options = pkcs11Options;
504         return this;
505     }
506 
507     /**
508      * Unix platforms only, specifies TLS options for custom private key operations. This
509      * allows you to perform custom private key operations such as signing and decrypting.
510      *
511      * @param customKeyOperations The custom private key operations
512      * @return this
513      */
withMtlsCustomKeyOperations(TlsContextCustomKeyOperationOptions customKeyOperations)514     public TlsContextOptions withMtlsCustomKeyOperations(TlsContextCustomKeyOperationOptions customKeyOperations) {
515         this.customKeyOperations = customKeyOperations;
516         return this;
517     }
518 
519      /**
520      * Windows platforms only, specifies mutual TLS (mTLS) using a certificate in a Windows
521      * certificate store.
522      *
523      * @param certificatePath Path to certificate in a Windows certificate store.
524      *                        The path must use backslashes and end with the
525      *                        certificate's thumbprint. Example:
526      *                        {@code CurrentUser\MY\A11F8A9B5DF5B98BA3508FBCA575D09570E0D2C6}
527      * @return this
528      */
withMtlsWindowsCertStorePath(String certificatePath)529     public TlsContextOptions withMtlsWindowsCertStorePath(String certificatePath) {
530         this.windowsCertStorePath = certificatePath;
531         return this;
532     }
533 
534     /**
535      * Sets whether or not TLS will validate the certificate from the peer. On clients,
536      * this is enabled by default. On servers, this is disabled by default.
537      * @param verify true to verify peers, false to ignore certs
538      * @return this
539      */
withVerifyPeer(boolean verify)540     public TlsContextOptions withVerifyPeer(boolean verify) {
541         this.verifyPeer = verify;
542         return this;
543     }
544 
545     /**
546      * Enables TLS peer verification of certificates
547      * @see TlsContextOptions#withVerifyPeer(boolean)
548      * @return this
549      */
withVerifyPeer()550     public TlsContextOptions withVerifyPeer() {
551         return this.withVerifyPeer(true);
552     }
553 
554     /*******************************************************************************
555      * native methods
556      ******************************************************************************/
tlsContextOptionsNew( int minTlsVersion, int cipherPref, String alpn, String certificate, String privateKey, String certificatePath, String privateKeyPath, String caRoot, String caFile, String caDir, boolean verifyPeer, String pkcs12Path, String pkcs12Password, TlsContextPkcs11Options pkcs11Options, TlsContextCustomKeyOperationOptions customKeyOperation, String windowsCertStorePath )557     private static native long tlsContextOptionsNew(
558                 int minTlsVersion,
559                 int cipherPref,
560                 String alpn,
561                 String certificate,
562                 String privateKey,
563                 String certificatePath,
564                 String privateKeyPath,
565                 String caRoot,
566                 String caFile,
567                 String caDir,
568                 boolean verifyPeer,
569                 String pkcs12Path,
570                 String pkcs12Password,
571                 TlsContextPkcs11Options pkcs11Options,
572                 TlsContextCustomKeyOperationOptions customKeyOperation,
573                 String windowsCertStorePath
574             );
575 
tlsContextOptionsDestroy(long elg)576     private static native void tlsContextOptionsDestroy(long elg);
577 
tlsContextOptionsIsAlpnAvailable()578     private static native boolean tlsContextOptionsIsAlpnAvailable();
579 
tlsContextOptionsIsCipherPreferenceSupported(int cipherPref)580     private static native boolean tlsContextOptionsIsCipherPreferenceSupported(int cipherPref);
581 
582 };
583