1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tomcat.jni;
/**
* Support TLS extensions and extra methods.
*
* The methods are separated to make it easier for java code to
* support existing native library - it can check if this class can
* be loaded in order to use the exensions.
*
* @author Costin Manolache
*/
public final class SSLExt {
/**
* Set advertised NPN protocol.
* This is only available for recent or patched openssl.
*
* Example: "\x06spdy/2"
*
* Works with TLS1, doesn't with SSL2/SSL3
*
* Servers sends list in ServerHelo, client selects it and
* sends it back after ChangeChipher
*
* Not supported in 1.0.0, seems to be in 1.0.1 and after
*/
public static native int setNPN(long tcctx, byte[] proto, int len);
/**
* Get other side's advertised protocols.
* Only works after handshake.
*/
public static native int getNPN(long tcsock, byte[] proto);
/**
* Enabling dump/debugging on the socket. Both raw and decrypted
* packets will be logged.
*/
public static native int debug(long tcsock);
/**
* Server: Extract the session data associated with the socket.
* Must be saved, keyed by session ID.
*/
public static native byte[] getSessionData(long tcsock);
/**
* Server: Set the session data for a socket.
*/
public static native int setSessionData(long tcsock, byte[] data, int len);
/**
* Client: get the ticket received from server, if tickets are supported.
*/
public static native int getTicket(long tcsock, byte[] resBuf);
/**
* Client: set the previously received ticket.
*/
public static native int setTicket(long tcsock, byte[] data, int len);
/**
* Set the key used by server to generate tickets.
* Key must be 48 bytes.
*/
public static native int setTicketKeys(long ctx, byte[] data, int len);
/**
* For client side calls. Data should be a \0 terminated string
*/
public static native int setSNI(long tcsock, byte[] data, int len);
/**
* Return the last openssl error
*/
public static native String sslErrReasonErrorString();
public static native long sslCtxSetMode(long ctx, long mode);
/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
* when just a single record has been written): */
public static final int SSL_MODE_ENABLE_PARTIAL_WRITE = 0x1;
/* Make it possible to retry SSL_write() with changed buffer location
* (buffer contents must stay the same!); this is not the default to avoid
* the misconception that non-blocking SSL_write() behaves like
* non-blocking write(): */
public static final int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = 0x2;
/* Don't attempt to automatically build certificate chain */
static final int SSL_MODE_NO_AUTO_CHAIN = 0x8;
/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
public static final int SSL_MODE_RELEASE_BUFFERS = 0x10;
// 1.1
//static final int SSL_MODE_HANDSHAKE_CUTTHROUGH = ..;
/**
* SSL_set_mode
*/
public static native long sslSetMode(long tcsock, long mode);
public static int setNPN(long sslContext, byte[] spdyNPN) {
try {
return SSLExt.setNPN(sslContext, spdyNPN, spdyNPN.length);
} catch (Throwable t) {
t.printStackTrace();
return -1;
}
}
/**
* Higher level method, checking if the specified protocol has been
* negotiated.
*/
public static boolean checkNPN(long tcsocket, byte[] expected) {
byte[] npn = new byte[expected.length + 1];
int npnLen = 0;
try {
npnLen = SSLExt.getNPN(tcsocket, npn);
if (npnLen != expected.length) {
return false;
}
} catch (Throwable t) {
// ignore
return false;
}
for (int i = 0; i < expected.length; i++) {
if (expected[i] != npn[i]) {
return false;
}
}
return true;
}
}
|