Search in sources :

Example 56 with CertificateException

use of java.security.cert.CertificateException in project robovm by robovm.

the class ServerHandshakeImpl method unwrap.

/**
     * Proceses inbound handshake messages
     * @param bytes
     */
@Override
public void unwrap(byte[] bytes) {
    io_stream.append(bytes);
    while (io_stream.available() > 0) {
        int handshakeType;
        int length;
        io_stream.mark();
        try {
            handshakeType = io_stream.read();
            length = io_stream.readUint24();
            if (io_stream.available() < length) {
                io_stream.reset();
                return;
            }
            switch(handshakeType) {
                case // CLIENT_HELLO
                1:
                    if (clientHello != null && this.status != FINISHED) {
                        // Client hello has been received during handshake
                        unexpectedMessage();
                        return;
                    }
                    // if protocol planed to send Hello Request message
                    // - cancel this demand.
                    needSendHelloRequest = false;
                    clientHello = new ClientHello(io_stream, length);
                    if (nonBlocking) {
                        delegatedTasks.add(new DelegatedTask(new Runnable() {

                            public void run() {
                                processClientHello();
                            }
                        }, this));
                        return;
                    }
                    processClientHello();
                    break;
                case //    CLIENT CERTIFICATE
                11:
                    if (isResuming || certificateRequest == null || serverHelloDone == null || clientCert != null) {
                        unexpectedMessage();
                        return;
                    }
                    clientCert = new CertificateMessage(io_stream, length);
                    if (clientCert.certs.length == 0) {
                        if (parameters.getNeedClientAuth()) {
                            fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "HANDSHAKE FAILURE: no client certificate received");
                        }
                    } else {
                        String authType = clientCert.getAuthType();
                        try {
                            parameters.getTrustManager().checkClientTrusted(clientCert.certs, authType);
                        } catch (CertificateException e) {
                            fatalAlert(AlertProtocol.BAD_CERTIFICATE, "Untrusted Client Certificate ", e);
                        }
                        session.peerCertificates = clientCert.certs;
                    }
                    break;
                case // CERTIFICATE_VERIFY
                15:
                    if (isResuming || clientKeyExchange == null || clientCert == null || //client certificate
                    clientKeyExchange.isEmpty() || // parameters
                    certificateVerify != null || changeCipherSpecReceived) {
                        unexpectedMessage();
                        return;
                    }
                    certificateVerify = new CertificateVerify(io_stream, length);
                    String authType = clientCert.getAuthType();
                    DigitalSignature ds = new DigitalSignature(authType);
                    ds.init(clientCert.certs[0]);
                    byte[] md5_hash = null;
                    byte[] sha_hash = null;
                    if ("RSA".equals(authType)) {
                        md5_hash = io_stream.getDigestMD5withoutLast();
                        sha_hash = io_stream.getDigestSHAwithoutLast();
                    } else if ("DSA".equals(authType)) {
                        sha_hash = io_stream.getDigestSHAwithoutLast();
                    // The Signature should be empty in case of anonymous signature algorithm:
                    // } else if ("DH".equals(authType)) {
                    }
                    ds.setMD5(md5_hash);
                    ds.setSHA(sha_hash);
                    if (!ds.verifySignature(certificateVerify.signedHash)) {
                        fatalAlert(AlertProtocol.DECRYPT_ERROR, "DECRYPT ERROR: CERTIFICATE_VERIFY incorrect signature");
                    }
                    break;
                case // CLIENT_KEY_EXCHANGE
                16:
                    if (isResuming || serverHelloDone == null || clientKeyExchange != null || (clientCert == null && parameters.getNeedClientAuth())) {
                        unexpectedMessage();
                        return;
                    }
                    if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
                        clientKeyExchange = new ClientKeyExchange(io_stream, length, serverHello.server_version[1] == 1, true);
                        Cipher c = null;
                        try {
                            c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                            c.init(Cipher.UNWRAP_MODE, privKey);
                            preMasterSecret = c.unwrap(clientKeyExchange.exchange_keys, "preMasterSecret", Cipher.SECRET_KEY).getEncoded();
                            // check preMasterSecret:
                            if (preMasterSecret.length != 48 || preMasterSecret[0] != clientHello.client_version[0] || preMasterSecret[1] != clientHello.client_version[1]) {
                                // incorrect preMasterSecret
                                // prevent an attack (see TLS 1.0 spec., 7.4.7.1.)
                                preMasterSecret = new byte[48];
                                parameters.getSecureRandom().nextBytes(preMasterSecret);
                            }
                        } catch (Exception e) {
                            fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
                        }
                    } else {
                        // diffie hellman key exchange
                        clientKeyExchange = new ClientKeyExchange(io_stream, length, serverHello.server_version[1] == 1, false);
                        if (clientKeyExchange.isEmpty()) {
                            // TODO check that client cert. DH params
                            // matched server cert. DH params
                            // client cert. contains fixed DH parameters
                            preMasterSecret = ((DHPublicKey) clientCert.certs[0].getPublicKey()).getY().toByteArray();
                        } else {
                            try {
                                KeyFactory kf = KeyFactory.getInstance("DH");
                                KeyAgreement agreement = KeyAgreement.getInstance("DH");
                                PublicKey clientPublic = kf.generatePublic(new DHPublicKeySpec(new BigInteger(1, clientKeyExchange.exchange_keys), serverKeyExchange.par1, serverKeyExchange.par2));
                                agreement.init(privKey);
                                agreement.doPhase(clientPublic, true);
                                preMasterSecret = agreement.generateSecret();
                            } catch (Exception e) {
                                fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
                                return;
                            }
                        }
                    }
                    computerMasterSecret();
                    break;
                case // FINISHED
                20:
                    if (!isResuming && !changeCipherSpecReceived) {
                        unexpectedMessage();
                        return;
                    }
                    clientFinished = new Finished(io_stream, length);
                    verifyFinished(clientFinished.getData());
                    session.context = parameters.getServerSessionContext();
                    parameters.getServerSessionContext().putSession(session);
                    if (!isResuming) {
                        sendChangeCipherSpec();
                    } else {
                        session.lastAccessedTime = System.currentTimeMillis();
                        status = FINISHED;
                    }
                    break;
                default:
                    unexpectedMessage();
                    return;
            }
        } catch (IOException e) {
            // io stream dosn't contain complete handshake message
            io_stream.reset();
            return;
        }
    }
}
Also used : DHPublicKey(javax.crypto.interfaces.DHPublicKey) PublicKey(java.security.PublicKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) DHPublicKey(javax.crypto.interfaces.DHPublicKey) CertificateException(java.security.cert.CertificateException) IOException(java.io.IOException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BigInteger(java.math.BigInteger) Cipher(javax.crypto.Cipher) DHPublicKeySpec(javax.crypto.spec.DHPublicKeySpec) KeyAgreement(javax.crypto.KeyAgreement) KeyFactory(java.security.KeyFactory)

Example 57 with CertificateException

use of java.security.cert.CertificateException in project robovm by robovm.

the class TrustManagerImpl method checkTrusted.

private List<X509Certificate> checkTrusted(X509Certificate[] chain, String authType, String host, boolean clientAuth) throws CertificateException {
    if (chain == null || chain.length == 0 || authType == null || authType.length() == 0) {
        throw new IllegalArgumentException("null or zero-length parameter");
    }
    if (err != null) {
        throw new CertificateException(err);
    }
    // get the cleaned up chain and trust anchor
    // there can only be one!
    Set<TrustAnchor> trustAnchor = new HashSet<TrustAnchor>();
    X509Certificate[] newChain = cleanupCertChainAndFindTrustAnchors(chain, trustAnchor);
    // add the first trust anchor to the chain, which may be an intermediate
    List<X509Certificate> wholeChain = new ArrayList<X509Certificate>();
    wholeChain.addAll(Arrays.asList(newChain));
    // trustAnchor is actually just a single element
    for (TrustAnchor trust : trustAnchor) {
        wholeChain.add(trust.getTrustedCert());
    }
    // add all the cached certificates from the cert index, avoiding loops
    // this gives us a full chain from leaf to root, which we use for cert pinning and pass
    // back out to callers when we return.
    X509Certificate last = wholeChain.get(wholeChain.size() - 1);
    while (true) {
        TrustAnchor cachedTrust = trustedCertificateIndex.findByIssuerAndSignature(last);
        // trusted a non-self-signed cert.
        if (cachedTrust == null) {
            break;
        }
        // at this point we have a cached trust anchor, but don't know if its one we got from
        // the server. Extract the cert, compare it to the last element in the chain, and add it
        // if we haven't seen it before.
        X509Certificate next = cachedTrust.getTrustedCert();
        if (next != last) {
            wholeChain.add(next);
            last = next;
        } else {
            // if next == last then we found a self-signed cert and the chain is done
            break;
        }
    }
    // build the cert path from the array of certs sans trust anchors
    CertPath certPath = factory.generateCertPath(Arrays.asList(newChain));
    if (host != null) {
        boolean chainIsNotPinned = true;
        try {
            chainIsNotPinned = pinManager.chainIsNotPinned(host, wholeChain);
        } catch (PinManagerException e) {
            throw new CertificateException(e);
        }
        if (chainIsNotPinned) {
            throw new CertificateException(new CertPathValidatorException("Certificate path is not properly pinned.", null, certPath, -1));
        }
    }
    if (newChain.length == 0) {
        // chain was entirely trusted, skip the validator
        return wholeChain;
    }
    if (trustAnchor.isEmpty()) {
        throw new CertificateException(new CertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1));
    }
    // There's no point in checking trust anchors here, and it will throw off the MD5 check,
    // so we just hand it the chain without anchors
    ChainStrengthAnalyzer.check(newChain);
    try {
        PKIXParameters params = new PKIXParameters(trustAnchor);
        params.setRevocationEnabled(false);
        params.addCertPathChecker(new ExtendedKeyUsagePKIXCertPathChecker(clientAuth, newChain[0]));
        validator.validate(certPath, params);
        // cleanupCertChainAndFindTrustAnchors.  http://b/3404902
        for (int i = 1; i < newChain.length; i++) {
            trustedCertificateIndex.index(newChain[i]);
        }
    } catch (InvalidAlgorithmParameterException e) {
        throw new CertificateException(e);
    } catch (CertPathValidatorException e) {
        throw new CertificateException(e);
    }
    return wholeChain;
}
Also used : InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) ArrayList(java.util.ArrayList) CertificateException(java.security.cert.CertificateException) TrustAnchor(java.security.cert.TrustAnchor) X509Certificate(java.security.cert.X509Certificate) CertPathValidatorException(java.security.cert.CertPathValidatorException) PKIXParameters(java.security.cert.PKIXParameters) CertPath(java.security.cert.CertPath) HashSet(java.util.HashSet)

Example 58 with CertificateException

use of java.security.cert.CertificateException in project robovm by robovm.

the class OpenSSLX509CertPath method fromPkiPathEncoding.

private static CertPath fromPkiPathEncoding(InputStream inStream) throws CertificateException {
    OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(inStream);
    final boolean markable = inStream.markSupported();
    if (markable) {
        inStream.mark(PUSHBACK_SIZE);
    }
    final long[] certRefs;
    try {
        certRefs = NativeCrypto.ASN1_seq_unpack_X509_bio(bis.getBioContext());
    } catch (Exception e) {
        if (markable) {
            try {
                inStream.reset();
            } catch (IOException ignored) {
            }
        }
        throw new CertificateException(e);
    } finally {
        NativeCrypto.BIO_free(bis.getBioContext());
    }
    if (certRefs == null) {
        return new OpenSSLX509CertPath(Collections.<X509Certificate>emptyList());
    }
    final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(certRefs.length);
    for (int i = certRefs.length - 1; i >= 0; i--) {
        if (certRefs[i] == 0) {
            continue;
        }
        certs.add(new OpenSSLX509Certificate(certRefs[i]));
    }
    return new OpenSSLX509CertPath(certs);
}
Also used : ArrayList(java.util.ArrayList) CertificateException(java.security.cert.CertificateException) IOException(java.io.IOException) ParsingException(org.conscrypt.OpenSSLX509CertificateFactory.ParsingException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) CertificateEncodingException(java.security.cert.CertificateEncodingException)

Example 59 with CertificateException

use of java.security.cert.CertificateException in project robovm by robovm.

the class OpenSSLX509CertPath method fromPkcs7Encoding.

private static CertPath fromPkcs7Encoding(InputStream inStream) throws CertificateException {
    try {
        if (inStream == null || inStream.available() == 0) {
            return new OpenSSLX509CertPath(Collections.<X509Certificate>emptyList());
        }
    } catch (IOException e) {
        throw new CertificateException("Problem reading input stream", e);
    }
    final boolean markable = inStream.markSupported();
    if (markable) {
        inStream.mark(PUSHBACK_SIZE);
    }
    /* Attempt to see if this is a PKCS#7 bag. */
    final PushbackInputStream pbis = new PushbackInputStream(inStream, PUSHBACK_SIZE);
    try {
        final byte[] buffer = new byte[PKCS7_MARKER.length];
        final int len = pbis.read(buffer);
        if (len < 0) {
            /* No need to reset here. The stream was empty or EOF. */
            throw new ParsingException("inStream is empty");
        }
        pbis.unread(buffer, 0, len);
        if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
            return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7PemInputStream(pbis));
        }
        return new OpenSSLX509CertPath(OpenSSLX509Certificate.fromPkcs7DerInputStream(pbis));
    } catch (Exception e) {
        if (markable) {
            try {
                inStream.reset();
            } catch (IOException ignored) {
            }
        }
        throw new CertificateException(e);
    }
}
Also used : PushbackInputStream(java.io.PushbackInputStream) ParsingException(org.conscrypt.OpenSSLX509CertificateFactory.ParsingException) CertificateException(java.security.cert.CertificateException) IOException(java.io.IOException) ParsingException(org.conscrypt.OpenSSLX509CertificateFactory.ParsingException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) CertificateEncodingException(java.security.cert.CertificateEncodingException)

Example 60 with CertificateException

use of java.security.cert.CertificateException in project robovm by robovm.

the class OpenSSLX509CertificateFactory method engineGenerateCertPath.

@Override
public CertPath engineGenerateCertPath(List<? extends Certificate> certificates) throws CertificateException {
    final List<X509Certificate> filtered = new ArrayList<X509Certificate>(certificates.size());
    for (int i = 0; i < certificates.size(); i++) {
        final Certificate c = certificates.get(i);
        if (!(c instanceof X509Certificate)) {
            throw new CertificateException("Certificate not X.509 type at index " + i);
        }
        filtered.add((X509Certificate) c);
    }
    return new OpenSSLX509CertPath(filtered);
}
Also used : ArrayList(java.util.ArrayList) CertificateException(java.security.cert.CertificateException) X509Certificate(java.security.cert.X509Certificate) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Aggregations

CertificateException (java.security.cert.CertificateException)456 IOException (java.io.IOException)221 X509Certificate (java.security.cert.X509Certificate)215 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)141 KeyStoreException (java.security.KeyStoreException)123 CertificateFactory (java.security.cert.CertificateFactory)103 ByteArrayInputStream (java.io.ByteArrayInputStream)97 Certificate (java.security.cert.Certificate)75 KeyStore (java.security.KeyStore)58 InputStream (java.io.InputStream)55 UnrecoverableKeyException (java.security.UnrecoverableKeyException)53 ArrayList (java.util.ArrayList)49 InvalidKeyException (java.security.InvalidKeyException)44 X509TrustManager (javax.net.ssl.X509TrustManager)41 SSLContext (javax.net.ssl.SSLContext)36 FileInputStream (java.io.FileInputStream)34 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)34 RemoteException (android.os.RemoteException)33 FileNotFoundException (java.io.FileNotFoundException)30 KeyManagementException (java.security.KeyManagementException)30