Search in sources :

Example 11 with SSLProtocolException

use of javax.net.ssl.SSLProtocolException in project robovm by robovm.

the class OpenSSLSocketImpl method startHandshake.

/**
     * Starts a TLS/SSL handshake on this connection using some native methods
     * from the OpenSSL library. It can negotiate new encryption keys, change
     * cipher suites, or initiate a new session. The certificate chain is
     * verified if the correspondent property in java.Security is set. All
     * listeners are notified at the end of the TLS/SSL handshake.
     */
@Override
public synchronized void startHandshake() throws IOException {
    synchronized (handshakeLock) {
        checkOpen();
        if (!handshakeStarted) {
            handshakeStarted = true;
        } else {
            return;
        }
    }
    // note that this modifies the global seed, not something specific to the connection
    final int seedLengthInBytes = NativeCrypto.RAND_SEED_LENGTH_IN_BYTES;
    final SecureRandom secureRandom = sslParameters.getSecureRandomMember();
    if (secureRandom == null) {
        NativeCrypto.RAND_load_file("/dev/urandom", seedLengthInBytes);
    } else {
        NativeCrypto.RAND_seed(secureRandom.generateSeed(seedLengthInBytes));
    }
    final boolean client = sslParameters.getUseClientMode();
    final long sslCtxNativePointer = (client) ? sslParameters.getClientSessionContext().sslCtxNativePointer : sslParameters.getServerSessionContext().sslCtxNativePointer;
    this.sslNativePointer = 0;
    boolean exception = true;
    try {
        sslNativePointer = NativeCrypto.SSL_new(sslCtxNativePointer);
        guard.open("close");
        if (npnProtocols != null) {
            NativeCrypto.SSL_CTX_enable_npn(sslCtxNativePointer);
        }
        if (client && alpnProtocols != null) {
            NativeCrypto.SSL_CTX_set_alpn_protos(sslCtxNativePointer, alpnProtocols);
        }
        // clients will receive a call back to request certificates.
        if (!client) {
            Set<String> keyTypes = new HashSet<String>();
            for (String enabledCipherSuite : enabledCipherSuites) {
                if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
                    continue;
                }
                String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
                if (keyType != null) {
                    keyTypes.add(keyType);
                }
            }
            for (String keyType : keyTypes) {
                try {
                    setCertificate(sslParameters.getKeyManager().chooseServerAlias(keyType, null, this));
                } catch (CertificateEncodingException e) {
                    throw new IOException(e);
                }
            }
        }
        NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols);
        NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites);
        if (useSessionTickets) {
            NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET);
        }
        if (hostname != null) {
            NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, hostname);
        }
        boolean enableSessionCreation = sslParameters.getEnableSessionCreation();
        if (!enableSessionCreation) {
            NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, enableSessionCreation);
        }
        AbstractSessionContext sessionContext;
        OpenSSLSessionImpl sessionToReuse;
        if (client) {
            // look for client session to reuse
            ClientSessionContext clientSessionContext = sslParameters.getClientSessionContext();
            sessionContext = clientSessionContext;
            sessionToReuse = getCachedClientSession(clientSessionContext);
            if (sessionToReuse != null) {
                NativeCrypto.SSL_set_session(sslNativePointer, sessionToReuse.sslSessionNativePointer);
            }
        } else {
            sessionContext = sslParameters.getServerSessionContext();
            sessionToReuse = null;
        }
        // setup peer certificate verification
        if (client) {
        // TODO support for anonymous cipher would require us to
        // conditionally use SSL_VERIFY_NONE
        } else {
            // needing client auth takes priority...
            boolean certRequested;
            if (sslParameters.getNeedClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer, NativeCrypto.SSL_VERIFY_PEER | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
                certRequested = true;
            // ... over just wanting it...
            } else if (sslParameters.getWantClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer, NativeCrypto.SSL_VERIFY_PEER);
                certRequested = true;
            // ... and it defaults properly so don't call SSL_set_verify in the common case.
            } else {
                certRequested = false;
            }
            if (certRequested) {
                X509TrustManager trustManager = sslParameters.getTrustManager();
                X509Certificate[] issuers = trustManager.getAcceptedIssuers();
                if (issuers != null && issuers.length != 0) {
                    byte[][] issuersBytes;
                    try {
                        issuersBytes = encodeIssuerX509Principals(issuers);
                    } catch (CertificateEncodingException e) {
                        throw new IOException("Problem encoding principals", e);
                    }
                    NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes);
                }
            }
        }
        // Temporarily use a different timeout for the handshake process
        int savedReadTimeoutMilliseconds = getSoTimeout();
        int savedWriteTimeoutMilliseconds = getSoWriteTimeout();
        if (handshakeTimeoutMilliseconds >= 0) {
            setSoTimeout(handshakeTimeoutMilliseconds);
            setSoWriteTimeout(handshakeTimeoutMilliseconds);
        }
        // TLS Channel ID
        if (channelIdEnabled) {
            if (client) {
                // Client-side TLS Channel ID
                if (channelIdPrivateKey == null) {
                    throw new SSLHandshakeException("Invalid TLS channel ID key specified");
                }
                NativeCrypto.SSL_set1_tls_channel_id(sslNativePointer, channelIdPrivateKey.getPkeyContext());
            } else {
                // Server-side TLS Channel ID
                NativeCrypto.SSL_enable_tls_channel_id(sslNativePointer);
            }
        }
        long sslSessionNativePointer;
        try {
            sslSessionNativePointer = NativeCrypto.SSL_do_handshake(sslNativePointer, socket.getFileDescriptor$(), this, getSoTimeout(), client, npnProtocols, client ? null : alpnProtocols);
        } catch (CertificateException e) {
            SSLHandshakeException wrapper = new SSLHandshakeException(e.getMessage());
            wrapper.initCause(e);
            throw wrapper;
        }
        byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
        if (sessionToReuse != null && Arrays.equals(sessionToReuse.getId(), sessionId)) {
            this.sslSession = sessionToReuse;
            sslSession.lastAccessedTime = System.currentTimeMillis();
            NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
        } else {
            if (!enableSessionCreation) {
                // Should have been prevented by NativeCrypto.SSL_set_session_creation_enabled
                throw new IllegalStateException("SSL Session may not be created");
            }
            X509Certificate[] localCertificates = createCertChain(NativeCrypto.SSL_get_certificate(sslNativePointer));
            X509Certificate[] peerCertificates = createCertChain(NativeCrypto.SSL_get_peer_cert_chain(sslNativePointer));
            this.sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates, peerCertificates, getPeerHostName(), getPeerPort(), sessionContext);
            // if not, putSession later in handshakeCompleted() callback
            if (handshakeCompleted) {
                sessionContext.putSession(sslSession);
            }
        }
        // Restore the original timeout now that the handshake is complete
        if (handshakeTimeoutMilliseconds >= 0) {
            setSoTimeout(savedReadTimeoutMilliseconds);
            setSoWriteTimeout(savedWriteTimeoutMilliseconds);
        }
        // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
        if (handshakeCompleted) {
            notifyHandshakeCompletedListeners();
        }
        exception = false;
    } catch (SSLProtocolException e) {
        throw new SSLHandshakeException(e);
    } finally {
        // on exceptional exit, treat the socket as closed
        if (exception) {
            close();
        }
    }
}
Also used : SecureRandom(java.security.SecureRandom) CertificateEncodingException(java.security.cert.CertificateEncodingException) CertificateException(java.security.cert.CertificateException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) SSLProtocolException(javax.net.ssl.SSLProtocolException) X509TrustManager(javax.net.ssl.X509TrustManager) HashSet(java.util.HashSet)

Example 12 with SSLProtocolException

use of javax.net.ssl.SSLProtocolException in project robovm by robovm.

the class SSLProtocolExceptionTest method test_Constructor02.

/**
     * Test for <code>SSLProtocolException(String)</code> constructor Assertion:
     * constructs SSLProtocolException with detail message msg. Parameter
     * <code>msg</code> is null.
     */
public void test_Constructor02() {
    String msg = null;
    SSLProtocolException sslE = new SSLProtocolException(msg);
    assertNull("getMessage() must return null.", sslE.getMessage());
    assertNull("getCause() must return null", sslE.getCause());
}
Also used : SSLProtocolException(javax.net.ssl.SSLProtocolException)

Example 13 with SSLProtocolException

use of javax.net.ssl.SSLProtocolException in project robovm by robovm.

the class SSLProtocolExceptionTest method test_Constructor01.

/**
     * Test for <code>SSLProtocolException(String)</code> constructor Assertion:
     * constructs SSLProtocolException with detail message msg. Parameter
     * <code>msg</code> is not null.
     */
public void test_Constructor01() {
    SSLProtocolException sslE;
    for (int i = 0; i < msgs.length; i++) {
        sslE = new SSLProtocolException(msgs[i]);
        assertEquals("getMessage() must return: ".concat(msgs[i]), sslE.getMessage(), msgs[i]);
        assertNull("getCause() must return null", sslE.getCause());
    }
}
Also used : SSLProtocolException(javax.net.ssl.SSLProtocolException)

Example 14 with SSLProtocolException

use of javax.net.ssl.SSLProtocolException in project XobotOS by xamarin.

the class SSLRecordProtocol method unwrap.

/**
     * Retrieves the fragment field of TLSCiphertext, and than
     * depending on the established Connection State
     * decrypts and decompresses it. The following structure is expected
     * on the input at the moment of the call:
     *
     *  struct {
     *      ContentType type;
     *      ProtocolVersion version;
     *      uint16 length;
     *      select (CipherSpec.cipher_type) {
     *          case stream: GenericStreamCipher;
     *          case block: GenericBlockCipher;
     *      } fragment;
     *  } TLSCiphertext;
     *
     * (as specified by RFC 2246, TLS v1 Protocol specification)
     *
     * In addition this method can recognize SSLv2 hello message which
     * are often used to establish the SSL/TLS session.
     *
     * @throws IOException if some io errors have been occurred
     * @throws EndOfSourceException if underlying input stream
     *                              has ran out of data.
     * @throws EndOfBufferException if there was not enough data
     *                              to build complete ssl packet.
     * @return the type of unwrapped message.
     */
protected int unwrap() throws IOException {
    if (logger != null) {
        logger.println("SSLRecordProtocol.unwrap: BEGIN [");
    }
    int type = in.readUint8();
    if ((type < ContentType.CHANGE_CIPHER_SPEC) || (type > ContentType.APPLICATION_DATA)) {
        if (logger != null) {
            logger.println("Non v3.1 message type:" + type);
        }
        if (type >= 0x80) {
            // it is probably SSL v2 client_hello message
            // (see SSL v2 spec at:
            // http://wp.netscape.com/eng/security/SSL_2.html)
            int length = (type & 0x7f) << 8 | in.read();
            byte[] fragment = in.read(length);
            handshakeProtocol.unwrapSSLv2(fragment);
            if (logger != null) {
                logger.println("SSLRecordProtocol:unwrap ] END, SSLv2 type");
            }
            return ContentType.HANDSHAKE;
        }
        throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE, new SSLProtocolException("Unexpected message type has been received: " + type));
    }
    if (logger != null) {
        logger.println("Got the message of type: " + type);
    }
    if (version != null) {
        if ((in.read() != version[0]) || (in.read() != version[1])) {
            throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE, new SSLProtocolException("Unexpected message type has been received: " + type));
        }
    } else {
        // just skip the version number
        in.skip(2);
    }
    int length = in.readUint16();
    if (logger != null) {
        logger.println("TLSCiphertext.fragment[" + length + "]: ...");
    }
    if (length > MAX_CIPHERED_DATA_LENGTH) {
        throw new AlertException(AlertProtocol.RECORD_OVERFLOW, new SSLProtocolException("Received message is too big."));
    }
    byte[] fragment = in.read(length);
    if (logger != null) {
        logger.print(fragment);
    }
    if (activeReadState != null) {
        fragment = activeReadState.decrypt((byte) type, fragment);
        if (logger != null) {
            logger.println("TLSPlaintext.fragment:");
            logger.print(fragment);
        }
    }
    if (fragment.length > MAX_DATA_LENGTH) {
        throw new AlertException(AlertProtocol.DECOMPRESSION_FAILURE, new SSLProtocolException("Decompressed plain data is too big."));
    }
    switch(type) {
        case ContentType.CHANGE_CIPHER_SPEC:
            // notify handshake protocol:
            handshakeProtocol.receiveChangeCipherSpec();
            setSession(handshakeProtocol.getSession());
            // change cipher spec message has been received, so:
            if (logger != null) {
                logger.println("activeReadState = pendingConnectionState");
            }
            activeReadState = pendingConnectionState;
            break;
        case ContentType.ALERT:
            alert(fragment[0], fragment[1]);
            break;
        case ContentType.HANDSHAKE:
            handshakeProtocol.unwrap(fragment);
            break;
        case ContentType.APPLICATION_DATA:
            if (logger != null) {
                logger.println("TLSCiphertext.unwrap: APP DATA[" + length + "]:");
                logger.println(new String(fragment));
            }
            appData.append(fragment);
            break;
        default:
            throw new AlertException(AlertProtocol.UNEXPECTED_MESSAGE, new SSLProtocolException("Unexpected message type has been received: " + type));
    }
    if (logger != null) {
        logger.println("SSLRecordProtocol:unwrap ] END, type: " + type);
    }
    return type;
}
Also used : SSLProtocolException(javax.net.ssl.SSLProtocolException)

Example 15 with SSLProtocolException

use of javax.net.ssl.SSLProtocolException in project XobotOS by xamarin.

the class ConnectionStateSSLv3 method decrypt.

/**
     * Retrieves the fragment of the Plaintext structure of
     * the specified type from the provided data.
     * @throws AlertException if alert was occured.
     */
@Override
protected byte[] decrypt(byte type, byte[] fragment, int offset, int len) {
    // plain data of the Generic[Stream|Block]Cipher structure
    byte[] data = decCipher.update(fragment, offset, len);
    // the 'content' part of the structure
    byte[] content;
    if (block_size != 0) {
        // check padding
        int padding_length = data[data.length - 1];
        for (int i = 0; i < padding_length; i++) {
            if (data[data.length - 2 - i] != padding_length) {
                throw new AlertException(AlertProtocol.DECRYPTION_FAILED, new SSLProtocolException("Received message has bad padding"));
            }
        }
        content = new byte[data.length - hash_size - padding_length - 1];
    } else {
        content = new byte[data.length - hash_size];
    }
    byte[] mac_value;
    mac_material_part[0] = type;
    mac_material_part[1] = (byte) ((0x00FF00 & content.length) >> 8);
    mac_material_part[2] = (byte) (0x0000FF & content.length);
    messageDigest.update(mac_read_secret);
    messageDigest.update(pad_1);
    messageDigest.update(read_seq_num);
    messageDigest.update(mac_material_part);
    messageDigest.update(data, 0, content.length);
    mac_value = messageDigest.digest();
    messageDigest.update(mac_read_secret);
    messageDigest.update(pad_2);
    messageDigest.update(mac_value);
    mac_value = messageDigest.digest();
    if (logger != null) {
        logger.println("Decrypted:");
        logger.print(data);
        //logger.println("MAC Material:");
        //logger.print(read_seq_num);
        //logger.print(mac_material_header);
        //logger.print(data, 0, content.length);
        logger.println("Expected mac value:");
        logger.print(mac_value);
    }
    // checking the mac value
    for (int i = 0; i < hash_size; i++) {
        if (mac_value[i] != data[i + content.length]) {
            throw new AlertException(AlertProtocol.BAD_RECORD_MAC, new SSLProtocolException("Bad record MAC"));
        }
    }
    System.arraycopy(data, 0, content, 0, content.length);
    incSequenceNumber(read_seq_num);
    return content;
}
Also used : SSLProtocolException(javax.net.ssl.SSLProtocolException)

Aggregations

SSLProtocolException (javax.net.ssl.SSLProtocolException)16 SSLHandshakeException (javax.net.ssl.SSLHandshakeException)5 CertificateException (java.security.cert.CertificateException)3 Test (org.junit.Test)3 IOException (java.io.IOException)2 SecureRandom (java.security.SecureRandom)2 CertificateEncodingException (java.security.cert.CertificateEncodingException)2 X509Certificate (java.security.cert.X509Certificate)2 HashSet (java.util.HashSet)2 X509TrustManager (javax.net.ssl.X509TrustManager)2 MockResponse (okhttp3.mockwebserver.MockResponse)2 SSLProtocolExceptionParser (org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser)2 HttpsURLConnection (javax.net.ssl.HttpsURLConnection)1 SingleInetAddressDns (okhttp3.internal.SingleInetAddressDns)1 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)1