@Override public final synchronized boolean isOutboundDone() { // Check if there is anything left in the outbound buffer. // We need to ensure we only call SSL.pendingWrittenBytesInBIO(...) if the engine was not destroyed yet. return outboundClosed && (networkBIO == 0 || SSL.bioLengthNonApplication(networkBIO) == 0); }
@Override protected void deallocate() { SSL.freePrivateKey(privateKeyAddress); privateKeyAddress = 0; }
@Override public long getCreationTime() { synchronized (ReferenceCountedOpenSslEngine.this) { if (creationTime == 0 && !isDestroyed()) { creationTime = SSL.getTime(ssl) * 1000L; } } return creationTime; }
private static boolean doesSupportProtocol(int protocol, int opt) { if (opt == 0) { // If the opt is 0 the protocol is not supported. This is for example the case with BoringSSL and SSLv2. return false; } long sslCtx = -1; try { sslCtx = SSLContext.make(protocol, SSL.SSL_MODE_COMBINED); return true; } catch (Exception ignore) { return false; } finally { if (sslCtx != -1) { SSLContext.free(sslCtx); } } }
@Override protected void deallocate() { SSL.freeX509Chain(chain); chain = 0; SSL.freePrivateKey(privateKey); privateKey = 0; if (leak != null) { boolean closed = leak.close(this); assert closed; } }
private static boolean initializeTcNative(String engine) throws Exception { return Library.initialize("provided", engine); }
private int sslPending0() { // OpenSSL has a limitation where if you call SSL_pending before the handshake is complete OpenSSL will throw a // "called a function you should not call" error. Using the TLS_method instead of SSLv23_method may solve this // issue but this API is only available in 1.1.0+ [1]. // [1] https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_new.html return handshakeState != HandshakeState.FINISHED ? 0 : SSL.sslPending(ssl); }
@Override public void invalidate() { synchronized (ReferenceCountedOpenSslEngine.this) { if (!isDestroyed()) { SSL.setTimeout(ssl, 0); } } }
static void freeBio(long bio) { if (bio != 0) { SSL.freeBIO(bio); } }
private void releaseChain() { SSL.freeX509Chain(certificateChain); certificateChain = 0; }
@Override public String getProtocol() { String protocol = this.protocol; if (protocol == null) { synchronized (ReferenceCountedOpenSslEngine.this) { if (!isDestroyed()) { protocol = SSL.getVersion(ssl); } else { protocol = StringUtil.EMPTY_STRING; } } } return protocol; }
/** * See <a href="https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_verify.html">SSL_set_verify</a> and * {@link SSL#setVerify(long, int, int)}. */ @UnstableApi public final synchronized void setVerify(int verifyMode, int depth) { SSL.setVerify(ssl, verifyMode, depth); }
/** * Returns the version of the used available OpenSSL library or {@code -1} if {@link #isAvailable()} * returns {@code false}. */ public static int version() { return isAvailable() ? SSL.version() : -1; }
/** * Get HMAC key. * @return the HMAC key of the session ticket key */ public byte[] hmacKey() { return key.getHmacKey().clone(); }
/** * Log the error, shutdown the engine and throw an exception. */ private SSLException shutdownWithError(String operations, int sslError) { return shutdownWithError(operations, sslError, SSL.getLastErrorNumber()); }
/** * Returns the version string of the used available OpenSSL library or {@code null} if {@link #isAvailable()} * returns {@code false}. */ public static String versionString() { return isAvailable() ? SSL.versionString() : null; }
/** * Get name. * @return the name of the session ticket key */ public byte[] name() { return key.getName().clone(); }
/** * It is assumed this method is called in a synchronized block (or the constructor)! */ private void calculateMaxWrapOverhead() { maxWrapOverhead = SSL.getMaxWrapOverhead(ssl); // maxWrapBufferSize must be set after maxWrapOverhead because there is a dependency on this value. // If jdkCompatibility mode is off we allow enough space to encrypt 16 buffers at a time. This could be // configurable in the future if necessary. maxWrapBufferSize = jdkCompatibilityMode ? maxEncryptedPacketLength0() : maxEncryptedPacketLength0() << 4; }
/** * Construct a OpenSslSessionTicketKey. * * @param name the name of the session ticket key * @param hmacKey the HMAC key of the session ticket key * @param aesKey the AES key of the session ticket key */ public OpenSslSessionTicketKey(byte[] name, byte[] hmacKey, byte[] aesKey) { key = new SessionTicketKey(name.clone(), hmacKey.clone(), aesKey.clone()); }
@Override public final synchronized SSLEngineResult.HandshakeStatus getHandshakeStatus() { // Check if we are in the initial handshake phase or shutdown phase return needPendingStatus() ? pendingStatus(SSL.bioLengthNonApplication(networkBIO)) : NOT_HANDSHAKING; }