1 /* 2 * Copyright 2016 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 /* 17 * Licensed to the Apache Software Foundation (ASF) under one or more 18 * contributor license agreements. See the NOTICE file distributed with 19 * this work for additional information regarding copyright ownership. 20 * The ASF licenses this file to You under the Apache License, Version 2.0 21 * (the "License"); you may not use this file except in compliance with 22 * the License. You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 package io.netty.internal.tcnative; 34 35 public final class SSLContext { 36 SSLContext()37 private SSLContext() { } 38 39 /** 40 * Initialize new SSL context 41 * @param protocol The SSL protocol to use. It can be any combination of 42 * the following: 43 * <PRE> 44 * {@link SSL#SSL_PROTOCOL_SSLV2} 45 * {@link SSL#SSL_PROTOCOL_SSLV3} 46 * {@link SSL#SSL_PROTOCOL_TLSV1} 47 * {@link SSL#SSL_PROTOCOL_TLSV1_1} 48 * {@link SSL#SSL_PROTOCOL_TLSV1_2} 49 * {@link SSL#SSL_PROTOCOL_ALL} ( == all TLS versions, no SSL) 50 * </PRE> 51 * @param mode SSL mode to use 52 * <PRE> 53 * SSL_MODE_CLIENT 54 * SSL_MODE_SERVER 55 * SSL_MODE_COMBINED 56 * </PRE> 57 * @return the SSLContext struct 58 * @throws Exception if an error happened 59 */ make(int protocol, int mode)60 public static native long make(int protocol, int mode) 61 throws Exception; 62 63 /** 64 * Free the resources used by the Context 65 * @param ctx Server or Client context to free. 66 * @return APR Status code. 67 */ free(long ctx)68 public static native int free(long ctx); 69 70 /** 71 * Set Session context id. Usually host:port combination. 72 * @param ctx Context to use. 73 * @param id String that uniquely identifies this context. 74 */ setContextId(long ctx, String id)75 public static native void setContextId(long ctx, String id); 76 77 /** 78 * Set OpenSSL Option. 79 * @param ctx Server or Client context to use. 80 * @param options See SSL.SSL_OP_* for option flags. 81 */ setOptions(long ctx, int options)82 public static native void setOptions(long ctx, int options); 83 84 /** 85 * Get OpenSSL Option. 86 * @param ctx Server or Client context to use. 87 * @return options See SSL.SSL_OP_* for option flags. 88 */ getOptions(long ctx)89 public static native int getOptions(long ctx); 90 91 /** 92 * Clears OpenSSL Options. 93 * @param ctx Server or Client context to use. 94 * @param options See SSL.SSL_OP_* for option flags. 95 */ clearOptions(long ctx, int options)96 public static native void clearOptions(long ctx, int options); 97 98 /** 99 * Cipher Suite available for negotiation in SSL handshake. 100 * <br> 101 * This complex directive uses a colon-separated cipher-spec string consisting 102 * of OpenSSL cipher specifications to configure the Cipher Suite the client 103 * is permitted to negotiate in the SSL handshake phase. Notice that this 104 * directive can be used both in per-server and per-directory context. 105 * In per-server context it applies to the standard SSL handshake when a 106 * connection is established. In per-directory context it forces a SSL 107 * renegotiation with the reconfigured Cipher Suite after the HTTP request 108 * was read but before the HTTP response is sent. 109 * @param ctx Server or Client context to use. 110 * @param ciphers An SSL cipher specification. 111 * @return {@code true} if successful 112 * @throws Exception if an error happened 113 */ setCipherSuite(long ctx, String ciphers)114 public static native boolean setCipherSuite(long ctx, String ciphers) throws Exception; 115 116 /** 117 * Set File of PEM-encoded Server CA Certificates 118 * <br> 119 * This directive sets the optional all-in-one file where you can assemble the 120 * certificates of Certification Authorities (CA) which form the certificate 121 * chain of the server certificate. This starts with the issuing CA certificate 122 * of of the server certificate and can range up to the root CA certificate. 123 * Such a file is simply the concatenation of the various PEM-encoded CA 124 * Certificate files, usually in certificate chain order. 125 * <br> 126 * But be careful: Providing the certificate chain works only if you are using 127 * a single (either RSA or DSA) based server certificate. If you are using a 128 * coupled RSA+DSA certificate pair, this will work only if actually both 129 * certificates use the same certificate chain. Else the browsers will be 130 * confused in this situation. 131 * @param ctx Server or Client context to use. 132 * @param file File of PEM-encoded Server CA Certificates. 133 * @param skipfirst Skip first certificate if chain file is inside 134 * certificate file. 135 * @return {@code true} if successful 136 */ setCertificateChainFile(long ctx, String file, boolean skipfirst)137 public static native boolean setCertificateChainFile(long ctx, String file, boolean skipfirst); 138 /** 139 * Set BIO of PEM-encoded Server CA Certificates 140 * <p> 141 * This directive sets the optional all-in-one file where you can assemble the 142 * certificates of Certification Authorities (CA) which form the certificate 143 * chain of the server certificate. This starts with the issuing CA certificate 144 * of of the server certificate and can range up to the root CA certificate. 145 * Such a file is simply the concatenation of the various PEM-encoded CA 146 * Certificate files, usually in certificate chain order. 147 * <p> 148 * But be careful: Providing the certificate chain works only if you are using 149 * a single (either RSA or DSA) based server certificate. If you are using a 150 * coupled RSA+DSA certificate pair, this will work only if actually both 151 * certificates use the same certificate chain. Otherwsie the browsers will be 152 * confused in this situation. 153 * @param ctx Server or Client context to use. 154 * @param bio BIO of PEM-encoded Server CA Certificates. 155 * @param skipfirst Skip first certificate if chain file is inside 156 * certificate file. 157 * @return {@code true} if successful 158 */ setCertificateChainBio(long ctx, long bio, boolean skipfirst)159 public static native boolean setCertificateChainBio(long ctx, long bio, boolean skipfirst); 160 161 /** 162 * Set Certificate 163 * <p> 164 * Point setCertificateFile at a PEM encoded certificate. If 165 * the certificate is encrypted, then you will be prompted for a 166 * pass phrase. Note that a kill -HUP will prompt again. A test 167 * certificate can be generated with `make certificate' under 168 * built time. Keep in mind that if you've both a RSA and a DSA 169 * certificate you can configure both in parallel (to also allow 170 * the use of DSA ciphers, etc.) 171 * <p> 172 * If the key is not combined with the certificate, use key param 173 * to point at the key file. Keep in mind that if 174 * you've both a RSA and a DSA private key you can configure 175 * both in parallel (to also allow the use of DSA ciphers, etc.) 176 * @param ctx Server or Client context to use. 177 * @param cert Certificate file. 178 * @param key Private Key file to use if not in cert. 179 * @param password Certificate password. If null and certificate 180 * is encrypted, password prompt will be displayed. 181 * @return {@code true} if successful 182 * @throws Exception if an error happened 183 */ setCertificate(long ctx, String cert, String key, String password)184 public static native boolean setCertificate(long ctx, String cert, String key, String password) throws Exception; 185 186 /** 187 * Set Certificate 188 * <p> 189 * Point setCertificate at a PEM encoded certificate stored in a BIO. If 190 * the certificate is encrypted, then you will be prompted for a 191 * pass phrase. Note that a kill -HUP will prompt again. A test 192 * certificate can be generated with `make certificate' under 193 * built time. Keep in mind that if you've both a RSA and a DSA 194 * certificate you can configure both in parallel (to also allow 195 * the use of DSA ciphers, etc.) 196 * <p> 197 * If the key is not combined with the certificate, use key param 198 * to point at the key file. Keep in mind that if 199 * you've both a RSA and a DSA private key you can configure 200 * both in parallel (to also allow the use of DSA ciphers, etc.) 201 * @param ctx Server or Client context to use. 202 * @param certBio Certificate BIO. 203 * @param keyBio Private Key BIO to use if not in cert. 204 * @param password Certificate password. If null and certificate 205 * is encrypted, password prompt will be displayed. 206 * @return {@code true} if successful 207 * @throws Exception if an error happened 208 */ setCertificateBio(long ctx, long certBio, long keyBio, String password)209 public static native boolean setCertificateBio(long ctx, long certBio, long keyBio, String password) throws Exception; 210 211 /** 212 * Set the size of the internal session cache. 213 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_set_cache_size.html">man SSL_CTX_sess_set_cache_size</a> 214 * @param ctx Server or Client context to use. 215 * @param size the size of the cache 216 * @return the previous set value 217 */ setSessionCacheSize(long ctx, long size)218 public static native long setSessionCacheSize(long ctx, long size); 219 220 /** 221 * Get the size of the internal session cache. 222 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_get_cache_size.html">man SSL_CTX_sess_get_cache_size</a> 223 * @param ctx Server or Client context to use. 224 * @return the current value 225 */ getSessionCacheSize(long ctx)226 public static native long getSessionCacheSize(long ctx); 227 228 /** 229 * Set the timeout for the internal session cache in seconds. 230 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_timeout.html">man SSL_CTX_set_timeout</a> 231 * @param ctx Server or Client context to use. 232 * @param timeoutSeconds the timeout of the cache 233 * @return the previous set value 234 */ setSessionCacheTimeout(long ctx, long timeoutSeconds)235 public static native long setSessionCacheTimeout(long ctx, long timeoutSeconds); 236 237 /** 238 * Get the timeout for the internal session cache in seconds. 239 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_get_timeout.html">man SSL_CTX_get_timeout</a> 240 * @param ctx Server or Client context to use 241 * @return the current value 242 */ getSessionCacheTimeout(long ctx)243 public static native long getSessionCacheTimeout(long ctx); 244 245 /** 246 * Set the mode of the internal session cache and return the previous used mode. 247 * @param ctx Server or Client context to use 248 * @param mode the mode of the cache 249 * @return the previous set value 250 */ setSessionCacheMode(long ctx, long mode)251 public static native long setSessionCacheMode(long ctx, long mode); 252 253 /** 254 * Get the mode of the current used internal session cache. 255 * 256 * @param ctx Server or Client context to use 257 * @return the current mode 258 */ getSessionCacheMode(long ctx)259 public static native long getSessionCacheMode(long ctx); 260 261 /** 262 * Session resumption statistics methods. 263 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 264 * @param ctx Server or Client context to use 265 * @return the current number 266 */ sessionAccept(long ctx)267 public static native long sessionAccept(long ctx); 268 269 /** 270 * Session resumption statistics methods. 271 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 272 * @param ctx Server or Client context to use 273 * @return the current number 274 */ sessionAcceptGood(long ctx)275 public static native long sessionAcceptGood(long ctx); 276 277 /** 278 * Session resumption statistics methods. 279 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 280 * @param ctx Server or Client context to use 281 * @return the current number 282 */ sessionAcceptRenegotiate(long ctx)283 public static native long sessionAcceptRenegotiate(long ctx); 284 285 /** 286 * Session resumption statistics methods. 287 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 288 * @param ctx Server or Client context to use 289 * @return the current number 290 */ sessionCacheFull(long ctx)291 public static native long sessionCacheFull(long ctx); 292 293 /** 294 * Session resumption statistics methods. 295 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 296 * @param ctx Server or Client context to use 297 * @return the current number 298 */ sessionCbHits(long ctx)299 public static native long sessionCbHits(long ctx); 300 301 /** 302 * Session resumption statistics methods. 303 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 304 * @param ctx Server or Client context to use 305 * @return the current number 306 */ sessionConnect(long ctx)307 public static native long sessionConnect(long ctx); 308 309 /** 310 * Session resumption statistics methods. 311 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 312 * @param ctx Server or Client context to use 313 * @return the current number 314 */ sessionConnectGood(long ctx)315 public static native long sessionConnectGood(long ctx); 316 317 /** 318 * Session resumption statistics methods. 319 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 320 * @param ctx Server or Client context to use 321 * @return the current number 322 */ sessionConnectRenegotiate(long ctx)323 public static native long sessionConnectRenegotiate(long ctx); 324 325 /** 326 * Session resumption statistics methods. 327 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 328 * @param ctx Server or Client context to use 329 * @return the current number 330 */ sessionHits(long ctx)331 public static native long sessionHits(long ctx); 332 333 /** 334 * Session resumption statistics methods. 335 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 336 * @param ctx Server or Client context to use 337 * @return the current number 338 */ sessionMisses(long ctx)339 public static native long sessionMisses(long ctx); 340 341 /** 342 * Session resumption statistics methods. 343 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 344 * @param ctx Server or Client context to use 345 * @return the current number 346 */ sessionNumber(long ctx)347 public static native long sessionNumber(long ctx); 348 349 /** 350 * Session resumption statistics methods. 351 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_sess_number.html">man SSL_CTX_sess_number</a> 352 * @param ctx Server or Client context to use 353 * @return the current number 354 */ sessionTimeouts(long ctx)355 public static native long sessionTimeouts(long ctx); 356 357 /** 358 * TLS session ticket key resumption statistics. 359 * 360 * @param ctx Server or Client context to use 361 * @return the current number 362 */ sessionTicketKeyNew(long ctx)363 public static native long sessionTicketKeyNew(long ctx); 364 365 /** 366 * TLS session ticket key resumption statistics. 367 * 368 * @param ctx Server or Client context to use 369 * @return the current number 370 */ sessionTicketKeyResume(long ctx)371 public static native long sessionTicketKeyResume(long ctx); 372 373 /** 374 * TLS session ticket key resumption statistics. 375 * 376 * @param ctx Server or Client context to use 377 * @return the current number 378 */ sessionTicketKeyRenew(long ctx)379 public static native long sessionTicketKeyRenew(long ctx); 380 381 /** 382 * TLS session ticket key resumption statistics. 383 * 384 * @param ctx Server or Client context to use 385 * @return the current number 386 */ sessionTicketKeyFail(long ctx)387 public static native long sessionTicketKeyFail(long ctx); 388 389 /** 390 * Set TLS session ticket keys. 391 * 392 * <p> The first key in the list is the primary key. Tickets dervied from the other keys 393 * in the list will be accepted but updated to a new ticket using the primary key. This 394 * is useful for implementing ticket key rotation. 395 * See <a href="https://tools.ietf.org/html/rfc5077">RFC 5077</a> 396 * 397 * @param ctx Server or Client context to use 398 * @param keys the {@link SessionTicketKey}s 399 */ setSessionTicketKeys(long ctx, SessionTicketKey[] keys)400 public static void setSessionTicketKeys(long ctx, SessionTicketKey[] keys) { 401 if (keys == null || keys.length == 0) { 402 throw new IllegalArgumentException("Length of the keys should be longer than 0."); 403 } 404 byte[] binaryKeys = new byte[keys.length * SessionTicketKey.TICKET_KEY_SIZE]; 405 for (int i = 0; i < keys.length; i++) { 406 SessionTicketKey key = keys[i]; 407 int dstCurPos = SessionTicketKey.TICKET_KEY_SIZE * i; 408 System.arraycopy(key.name, 0, binaryKeys, dstCurPos, SessionTicketKey.NAME_SIZE); 409 dstCurPos += SessionTicketKey.NAME_SIZE; 410 System.arraycopy(key.hmacKey, 0, binaryKeys, dstCurPos, SessionTicketKey.HMAC_KEY_SIZE); 411 dstCurPos += SessionTicketKey.HMAC_KEY_SIZE; 412 System.arraycopy(key.aesKey, 0, binaryKeys, dstCurPos, SessionTicketKey.AES_KEY_SIZE); 413 } 414 setSessionTicketKeys0(ctx, binaryKeys); 415 } 416 417 /** 418 * Set TLS session keys. 419 */ setSessionTicketKeys0(long ctx, byte[] keys)420 private static native void setSessionTicketKeys0(long ctx, byte[] keys); 421 422 /** 423 * Set concatenated PEM-encoded CA Certificates for Client Auth 424 * <br> 425 * This directive sets the all-in-one BIO where you can assemble the 426 * Certificates of Certification Authorities (CA) whose clients you deal with. 427 * These are used for Client Authentication. Such a BIO is simply the 428 * concatenation of the various PEM-encoded Certificate files, in order of 429 * preference. This can be used alternatively and/or additionally to 430 * path. 431 * <br> 432 * @param ctx Server context to use. 433 * @param certBio Directory of PEM-encoded CA Certificates for Client Auth. 434 * @return {@code true} if successful, {@code false} otherwise. 435 */ setCACertificateBio(long ctx, long certBio)436 public static native boolean setCACertificateBio(long ctx, long certBio); 437 438 /** 439 * Set Type of Client Certificate verification and Maximum depth of CA Certificates 440 * in Client Certificate verification. 441 * <br> 442 * This directive sets the Certificate verification level for the Client 443 * Authentication. Notice that this directive can be used both in per-server 444 * and per-directory context. In per-server context it applies to the client 445 * authentication process used in the standard SSL handshake when a connection 446 * is established. In per-directory context it forces a SSL renegotiation with 447 * the reconfigured client verification level after the HTTP request was read 448 * but before the HTTP response is sent. 449 * <br> 450 * The following levels are available for level: 451 * <ul> 452 * <li>{@link SSL#SSL_CVERIFY_IGNORED} - The level is ignored. Only depth will change.</li> 453 * <li>{@link SSL#SSL_CVERIFY_NONE} - No client Certificate is required at all</li> 454 * <li>{@link SSL#SSL_CVERIFY_OPTIONAL} - The client may present a valid Certificate</li> 455 * <li>{@link SSL#SSL_CVERIFY_REQUIRED} - The client has to present a valid Certificate</li> 456 * </ul> 457 * The depth actually is the maximum number of intermediate certificate issuers, 458 * i.e. the number of CA certificates which are max allowed to be followed while 459 * verifying the client certificate. A depth of 0 means that self-signed client 460 * certificates are accepted only, the default depth of 1 means the client 461 * certificate can be self-signed or has to be signed by a CA which is directly 462 * known to the server (i.e. the CA's certificate is under 463 * <code>setCACertificatePath</code>), etc. 464 * @param ctx Server or Client context to use. 465 * @param level Type of Client Certificate verification. 466 * @param depth Maximum depth of CA Certificates in Client Certificate 467 * verification. 468 */ setVerify(long ctx, int level, int depth)469 public static native void setVerify(long ctx, int level, int depth); 470 471 /** 472 * Allow to hook {@link CertificateVerifier} into the handshake processing. 473 * This will call {@code SSL_CTX_set_cert_verify_callback} and so replace the default verification 474 * callback used by openssl 475 * @param ctx Server or Client context to use. 476 * @param verifier the verifier to call during handshake. 477 */ setCertVerifyCallback(long ctx, CertificateVerifier verifier)478 public static native void setCertVerifyCallback(long ctx, CertificateVerifier verifier); 479 480 /** 481 * Allow to hook {@link CertificateRequestedCallback} into the certificate choosing process. 482 * This will call {@code SSL_CTX_set_client_cert_cb} and so replace the default verification 483 * callback used by openssl 484 * @param ctx Server or Client context to use. 485 * @param callback the callback to call during certificate selection. 486 */ setCertRequestedCallback(long ctx, CertificateRequestedCallback callback)487 public static native void setCertRequestedCallback(long ctx, CertificateRequestedCallback callback); 488 489 /** 490 * Set next protocol for next protocol negotiation extension 491 * @param ctx Server context to use. 492 * @param nextProtos protocols in priority order 493 * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE} 494 * and {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL} 495 */ setNpnProtos(long ctx, String[] nextProtos, int selectorFailureBehavior)496 public static native void setNpnProtos(long ctx, String[] nextProtos, int selectorFailureBehavior); 497 498 /** 499 * Set application layer protocol for application layer protocol negotiation extension 500 * @param ctx Server context to use. 501 * @param alpnProtos protocols in priority order 502 * @param selectorFailureBehavior see {@link SSL#SSL_SELECTOR_FAILURE_NO_ADVERTISE} 503 * and {@link SSL#SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL} 504 */ setAlpnProtos(long ctx, String[] alpnProtos, int selectorFailureBehavior)505 public static native void setAlpnProtos(long ctx, String[] alpnProtos, int selectorFailureBehavior); 506 507 /** 508 * Set length of the DH to use. 509 * 510 * @param ctx Server context to use. 511 * @param length the length. 512 */ setTmpDHLength(long ctx, int length)513 public static native void setTmpDHLength(long ctx, int length); 514 515 /** 516 * Set the context within which session be reused (server side only). 517 * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_session_id_context.html">man SSL_CTX_set_session_id_context</a> 518 * 519 * @param ctx Server context to use. 520 * @param sidCtx can be any kind of binary data, it is therefore possible to use e.g. the name 521 * of the application and/or the hostname and/or service name 522 * @return {@code true} if success, {@code false} otherwise. 523 */ setSessionIdContext(long ctx, byte[] sidCtx)524 public static native boolean setSessionIdContext(long ctx, byte[] sidCtx); 525 526 /** 527 * Call SSL_CTX_set_mode 528 * 529 * @param ctx context to use 530 * @param mode the mode 531 * @return the set mode. 532 */ setMode(long ctx, int mode)533 public static native int setMode(long ctx, int mode); 534 535 /** 536 * Call SSL_CTX_get_mode 537 * 538 * @param ctx context to use 539 * @return the mode. 540 */ getMode(long ctx)541 public static native int getMode(long ctx); 542 } 543