Search in sources :

Example 31 with ECPublicKey

use of java.security.interfaces.ECPublicKey in project jdk8u_jdk by JetBrains.

the class ClientHandshaker method serverHelloDone.

/*
     * The server's "Hello Done" message is the client's sign that
     * it's time to do all the hard work.
     */
private void serverHelloDone(ServerHelloDone mesg) throws IOException {
    if (debug != null && Debug.isOn("handshake")) {
        mesg.print(System.out);
    }
    /*
         * Always make sure the input has been digested before we
         * start emitting data, to ensure the hashes are correctly
         * computed for the Finished and CertificateVerify messages
         * which we send (here).
         */
    input.digestNow();
    /*
         * FIRST ... if requested, send an appropriate Certificate chain
         * to authenticate the client, and remember the associated private
         * key to sign the CertificateVerify message.
         */
    PrivateKey signingKey = null;
    if (certRequest != null) {
        X509ExtendedKeyManager km = sslContext.getX509KeyManager();
        ArrayList<String> keytypesTmp = new ArrayList<>(4);
        for (int i = 0; i < certRequest.types.length; i++) {
            String typeName;
            switch(certRequest.types[i]) {
                case CertificateRequest.cct_rsa_sign:
                    typeName = "RSA";
                    break;
                case CertificateRequest.cct_dss_sign:
                    typeName = "DSA";
                    break;
                case CertificateRequest.cct_ecdsa_sign:
                    // ignore if we do not have EC crypto available
                    typeName = JsseJce.isEcAvailable() ? "EC" : null;
                    break;
                // case CertificateRequest.cct_dss_ephemeral_dh:
                default:
                    typeName = null;
                    break;
            }
            if ((typeName != null) && (!keytypesTmp.contains(typeName))) {
                keytypesTmp.add(typeName);
            }
        }
        String alias = null;
        int keytypesTmpSize = keytypesTmp.size();
        if (keytypesTmpSize != 0) {
            String[] keytypes = keytypesTmp.toArray(new String[keytypesTmpSize]);
            if (conn != null) {
                alias = km.chooseClientAlias(keytypes, certRequest.getAuthorities(), conn);
            } else {
                alias = km.chooseEngineClientAlias(keytypes, certRequest.getAuthorities(), engine);
            }
        }
        CertificateMsg m1 = null;
        if (alias != null) {
            X509Certificate[] certs = km.getCertificateChain(alias);
            if ((certs != null) && (certs.length != 0)) {
                PublicKey publicKey = certs[0].getPublicKey();
                if (publicKey != null) {
                    m1 = new CertificateMsg(certs);
                    signingKey = km.getPrivateKey(alias);
                    session.setLocalPrivateKey(signingKey);
                    session.setLocalCertificates(certs);
                }
            }
        }
        if (m1 == null) {
            //
            if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
                m1 = new CertificateMsg(new X509Certificate[0]);
            } else {
                warningSE(Alerts.alert_no_certificate);
            }
            if (debug != null && Debug.isOn("handshake")) {
                System.out.println("Warning: no suitable certificate found - " + "continuing without client authentication");
            }
        }
        //
        if (m1 != null) {
            if (debug != null && Debug.isOn("handshake")) {
                m1.print(System.out);
            }
            m1.write(output);
        }
    }
    /*
         * SECOND ... send the client key exchange message.  The
         * procedure used is a function of the cipher suite selected;
         * one is always needed.
         */
    HandshakeMessage m2;
    switch(keyExchange) {
        case K_RSA:
        case K_RSA_EXPORT:
            if (serverKey == null) {
                throw new SSLProtocolException("Server did not send certificate message");
            }
            if (!(serverKey instanceof RSAPublicKey)) {
                throw new SSLProtocolException("Server certificate does not include an RSA key");
            }
            /*
             * For RSA key exchange, we randomly generate a new
             * pre-master secret and encrypt it with the server's
             * public key.  Then we save that pre-master secret
             * so that we can calculate the keying data later;
             * it's a performance speedup not to do that until
             * the client's waiting for the server response, but
             * more of a speedup for the D-H case.
             *
             * If the RSA_EXPORT scheme is active, when the public
             * key in the server certificate is less than or equal
             * to 512 bits in length, use the cert's public key,
             * otherwise, the ephemeral one.
             */
            PublicKey key;
            if (keyExchange == K_RSA) {
                key = serverKey;
            } else {
                // K_RSA_EXPORT
                if (JsseJce.getRSAKeyLength(serverKey) <= 512) {
                    // extraneous ephemeralServerKey check done
                    // above in processMessage()
                    key = serverKey;
                } else {
                    if (ephemeralServerKey == null) {
                        throw new SSLProtocolException("Server did not send" + " a RSA_EXPORT Server Key Exchange message");
                    }
                    key = ephemeralServerKey;
                }
            }
            m2 = new RSAClientKeyExchange(protocolVersion, maxProtocolVersion, sslContext.getSecureRandom(), key);
            break;
        case K_DH_RSA:
        case K_DH_DSS:
            /*
             * For DH Key exchange, we only need to make sure the server
             * knows our public key, so we calculate the same pre-master
             * secret.
             *
             * For certs that had DH keys in them, we send an empty
             * handshake message (no key) ... we flag this case by
             * passing a null "dhPublic" value.
             *
             * Otherwise we send ephemeral DH keys, unsigned.
             */
            // if (useDH_RSA || useDH_DSS)
            m2 = new DHClientKeyExchange();
            break;
        case K_DHE_RSA:
        case K_DHE_DSS:
        case K_DH_ANON:
            if (dh == null) {
                throw new SSLProtocolException("Server did not send a DH Server Key Exchange message");
            }
            m2 = new DHClientKeyExchange(dh.getPublicKey());
            break;
        case K_ECDHE_RSA:
        case K_ECDHE_ECDSA:
        case K_ECDH_ANON:
            if (ecdh == null) {
                throw new SSLProtocolException("Server did not send a ECDH Server Key Exchange message");
            }
            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
            break;
        case K_ECDH_RSA:
        case K_ECDH_ECDSA:
            if (serverKey == null) {
                throw new SSLProtocolException("Server did not send certificate message");
            }
            if (serverKey instanceof ECPublicKey == false) {
                throw new SSLProtocolException("Server certificate does not include an EC key");
            }
            ECParameterSpec params = ((ECPublicKey) serverKey).getParams();
            ecdh = new ECDHCrypt(params, sslContext.getSecureRandom());
            m2 = new ECDHClientKeyExchange(ecdh.getPublicKey());
            break;
        case K_KRB5:
        case K_KRB5_EXPORT:
            String sniHostname = null;
            for (SNIServerName serverName : requestedServerNames) {
                if (serverName instanceof SNIHostName) {
                    sniHostname = ((SNIHostName) serverName).getAsciiName();
                    break;
                }
            }
            KerberosClientKeyExchange kerberosMsg = null;
            if (sniHostname != null) {
                // use first requested SNI hostname
                try {
                    kerberosMsg = new KerberosClientKeyExchange(sniHostname, getAccSE(), protocolVersion, sslContext.getSecureRandom());
                } catch (IOException e) {
                    if (serverNamesAccepted) {
                        // so it must be used
                        throw e;
                    }
                    // fallback to using hostname
                    if (debug != null && Debug.isOn("handshake")) {
                        System.out.println("Warning, cannot use Server Name Indication: " + e.getMessage());
                    }
                }
            }
            if (kerberosMsg == null) {
                String hostname = getHostSE();
                if (hostname == null) {
                    throw new IOException("Hostname is required" + " to use Kerberos cipher suites");
                }
                kerberosMsg = new KerberosClientKeyExchange(hostname, getAccSE(), protocolVersion, sslContext.getSecureRandom());
            }
            // Record the principals involved in exchange
            session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
            session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
            m2 = kerberosMsg;
            break;
        default:
            // somethings very wrong
            throw new RuntimeException("Unsupported key exchange: " + keyExchange);
    }
    if (debug != null && Debug.isOn("handshake")) {
        m2.print(System.out);
    }
    m2.write(output);
    /*
         * THIRD, send a "change_cipher_spec" record followed by the
         * "Finished" message.  We flush the messages we've queued up, to
         * get concurrency between client and server.  The concurrency is
         * useful as we calculate the master secret, which is needed both
         * to compute the "Finished" message, and to compute the keys used
         * to protect all records following the change_cipher_spec.
         */
    output.doHashes();
    output.flush();
    /*
         * We deferred calculating the master secret and this connection's
         * keying data; we do it now.  Deferring this calculation is good
         * from a performance point of view, since it lets us do it during
         * some time that network delays and the server's own calculations
         * would otherwise cause to be "dead" in the critical path.
         */
    SecretKey preMasterSecret;
    switch(keyExchange) {
        case K_RSA:
        case K_RSA_EXPORT:
            preMasterSecret = ((RSAClientKeyExchange) m2).preMaster;
            break;
        case K_KRB5:
        case K_KRB5_EXPORT:
            byte[] secretBytes = ((KerberosClientKeyExchange) m2).getUnencryptedPreMasterSecret();
            preMasterSecret = new SecretKeySpec(secretBytes, "TlsPremasterSecret");
            break;
        case K_DHE_RSA:
        case K_DHE_DSS:
        case K_DH_ANON:
            preMasterSecret = dh.getAgreedSecret(serverDH, true);
            break;
        case K_ECDHE_RSA:
        case K_ECDHE_ECDSA:
        case K_ECDH_ANON:
            preMasterSecret = ecdh.getAgreedSecret(ephemeralServerKey);
            break;
        case K_ECDH_RSA:
        case K_ECDH_ECDSA:
            preMasterSecret = ecdh.getAgreedSecret(serverKey);
            break;
        default:
            throw new IOException("Internal error: unknown key exchange " + keyExchange);
    }
    calculateKeys(preMasterSecret, null);
    /*
         * FOURTH, if we sent a Certificate, we need to send a signed
         * CertificateVerify (unless the key in the client's certificate
         * was a Diffie-Hellman key).).
         *
         * This uses a hash of the previous handshake messages ... either
         * a nonfinal one (if the particular implementation supports it)
         * or else using the third element in the arrays of hashes being
         * computed.
         */
    if (signingKey != null) {
        CertificateVerify m3;
        try {
            SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
            if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
                preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(getPeerSupportedSignAlgs(), signingKey.getAlgorithm(), signingKey);
                if (preferableSignatureAlgorithm == null) {
                    throw new SSLHandshakeException("No supported signature algorithm");
                }
                String hashAlg = SignatureAndHashAlgorithm.getHashAlgorithmName(preferableSignatureAlgorithm);
                if (hashAlg == null || hashAlg.length() == 0) {
                    throw new SSLHandshakeException("No supported hash algorithm");
                }
            }
            m3 = new CertificateVerify(protocolVersion, handshakeHash, signingKey, session.getMasterSecret(), sslContext.getSecureRandom(), preferableSignatureAlgorithm);
        } catch (GeneralSecurityException e) {
            fatalSE(Alerts.alert_handshake_failure, "Error signing certificate verify", e);
            // NOTREACHED, make compiler happy
            m3 = null;
        }
        if (debug != null && Debug.isOn("handshake")) {
            m3.print(System.out);
        }
        m3.write(output);
        output.doHashes();
    }
    /*
         * OK, that's that!
         */
    sendChangeCipherAndFinish(false);
}
Also used : RSAPublicKey(java.security.interfaces.RSAPublicKey) SecretKeySpec(javax.crypto.spec.SecretKeySpec) RSAPublicKey(java.security.interfaces.RSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) X509Certificate(java.security.cert.X509Certificate) SecretKey(javax.crypto.SecretKey) HandshakeMessage(sun.security.ssl.HandshakeMessage) ECPublicKey(java.security.interfaces.ECPublicKey) ECParameterSpec(java.security.spec.ECParameterSpec)

Example 32 with ECPublicKey

use of java.security.interfaces.ECPublicKey in project jdk8u_jdk by JetBrains.

the class P11ECDHKeyAgreement method engineDoPhase.

// see JCE spec
protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException {
    if (privateKey == null) {
        throw new IllegalStateException("Not initialized");
    }
    if (publicValue != null) {
        throw new IllegalStateException("Phase already executed");
    }
    if (lastPhase == false) {
        throw new IllegalStateException("Only two party agreement supported, lastPhase must be true");
    }
    if (key instanceof ECPublicKey == false) {
        throw new InvalidKeyException("Key must be a PublicKey with algorithm EC");
    }
    ECPublicKey ecKey = (ECPublicKey) key;
    int keyLenBits = ecKey.getParams().getCurve().getField().getFieldSize();
    secretLen = (keyLenBits + 7) >> 3;
    publicValue = P11ECKeyFactory.getEncodedPublicValue(ecKey);
    return null;
}
Also used : ECPublicKey(java.security.interfaces.ECPublicKey)

Example 33 with ECPublicKey

use of java.security.interfaces.ECPublicKey in project jdk8u_jdk by JetBrains.

the class TestECDH method test.

private static final void test(Provider p, String pub1s, String priv1s, String pub2s, String priv2s, String secrets) throws Exception {
    KeyFactory kf = KeyFactory.getInstance("EC", p);
    PublicKey pub1 = kf.generatePublic(new X509EncodedKeySpec(parse(pub1s)));
    System.out.println("Testing using parameters " + ((ECPublicKey) pub1).getParams() + "...");
    PrivateKey priv1 = kf.generatePrivate(new PKCS8EncodedKeySpec(parse(priv1s)));
    PublicKey pub2 = kf.generatePublic(new X509EncodedKeySpec(parse(pub2s)));
    PrivateKey priv2 = kf.generatePrivate(new PKCS8EncodedKeySpec(parse(priv2s)));
    byte[] secret = parse(secrets);
    KeyAgreement ka1 = KeyAgreement.getInstance("ECDH", p);
    ka1.init(priv1);
    ka1.doPhase(pub2, true);
    byte[] s1 = ka1.generateSecret();
    if (Arrays.equals(secret, s1) == false) {
        System.out.println("expected: " + toString(secret));
        System.out.println("actual:   " + toString(s1));
        throw new Exception("Secret 1 does not match");
    }
    KeyAgreement ka2 = KeyAgreement.getInstance("ECDH", p);
    ka2.init(priv2);
    ka2.doPhase(pub1, true);
    byte[] s2 = ka2.generateSecret();
    if (Arrays.equals(secret, s2) == false) {
        System.out.println("expected: " + toString(secret));
        System.out.println("actual:   " + toString(s2));
        throw new Exception("Secret 2 does not match");
    }
}
Also used : ECPublicKey(java.security.interfaces.ECPublicKey)

Example 34 with ECPublicKey

use of java.security.interfaces.ECPublicKey in project jdk8u_jdk by JetBrains.

the class TestECGenSpec method main.

public void main(Provider p) throws Exception {
    if (p.getService("Signature", "SHA1withECDSA") == null) {
        System.out.println("Provider does not support ECDSA, skipping...");
        return;
    }
    if (isNSS(p) && getNSSVersion() >= 3.11 && getNSSVersion() < 3.12) {
        System.out.println("NSS 3.11 has a DER issue that recent " + "version do not.");
        return;
    }
    String[] names = { "secp256r1", "NIST P-192", "sect163k1", "1.3.132.0.26", "X9.62 c2tnb239v1" };
    int curves = 1;
    if (getNSSECC() == ECCState.Extended) {
        curves = names.length;
    }
    int[] lengths = { 256, 192, 163, 233, 239 };
    for (int i = 0; i < curves; i++) {
        String name = names[i];
        int len = lengths[i];
        System.out.println("Testing " + name + "...");
        ECGenParameterSpec spec = new ECGenParameterSpec(name);
        AlgorithmParameters algParams = AlgorithmParameters.getInstance("EC", p);
        algParams.init(spec);
        ECParameterSpec ecSpec = algParams.getParameterSpec(ECParameterSpec.class);
        System.out.println(ecSpec);
        // no public API to get the curve name, so rely on toString();
        if (ecSpec.toString().contains(name) == false) {
            throw new Exception("wrong curve");
        }
        algParams = AlgorithmParameters.getInstance("EC", p);
        algParams.init(ecSpec);
        ECGenParameterSpec genSpec = algParams.getParameterSpec(ECGenParameterSpec.class);
        System.out.println(genSpec.getName());
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
        kpg.initialize(spec);
        KeyPair kp = kpg.generateKeyPair();
        System.out.println(kp.getPrivate());
        ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
        if (publicKey.getParams().getCurve().getField().getFieldSize() != len) {
            throw new Exception("wrong curve");
        }
        System.out.println();
    }
}
Also used : ECPublicKey(java.security.interfaces.ECPublicKey)

Example 35 with ECPublicKey

use of java.security.interfaces.ECPublicKey in project android_frameworks_base by ResurrectionRemix.

the class AndroidKeyPairGeneratorTest method assertKeyPairCorrect.

private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize, AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end) throws Exception {
    final PublicKey pubKey = pair.getPublic();
    assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
    assertEquals(keyType, pubKey.getAlgorithm());
    if ("EC".equalsIgnoreCase(keyType)) {
        assertEquals("Curve should be what was specified during initialization", keySize, ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
    } else if ("RSA".equalsIgnoreCase(keyType)) {
        RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
        assertEquals("Modulus size should be what is specified during initialization", (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
        if (spec != null) {
            RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
            assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
            assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
        }
    }
    final PrivateKey privKey = pair.getPrivate();
    assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
    assertEquals(keyType, privKey.getAlgorithm());
    if ("EC".equalsIgnoreCase(keyType)) {
        assertTrue("EC private key must be instanceof ECKey: " + privKey.getClass().getName(), privKey instanceof ECKey);
        assertEquals("Private and public key must have the same EC parameters", ((ECKey) pubKey).getParams(), ((ECKey) privKey).getParams());
    } else if ("RSA".equalsIgnoreCase(keyType)) {
        assertTrue("RSA private key must be instance of RSAKey: " + privKey.getClass().getName(), privKey instanceof RSAKey);
        assertEquals("Private and public key must have the same RSA modulus", ((RSAKey) pubKey).getModulus(), ((RSAKey) privKey).getModulus());
    }
    final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
    assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
    final CertificateFactory cf = CertificateFactory.getInstance("X.509");
    final Certificate userCert = cf.generateCertificate(new ByteArrayInputStream(userCertBytes));
    assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
    final X509Certificate x509userCert = (X509Certificate) userCert;
    assertEquals("Public key used to sign certificate should have the same algorithm as in KeyPair", pubKey.getAlgorithm(), x509userCert.getPublicKey().getAlgorithm());
    assertEquals("PublicKey used to sign certificate should match one returned in KeyPair", pubKey, AndroidKeyStoreProvider.getAndroidKeyStorePublicKey(Credentials.USER_PRIVATE_KEY + alias, KeyStore.UID_SELF, x509userCert.getPublicKey().getAlgorithm(), x509userCert.getPublicKey().getEncoded()));
    assertEquals("The Subject DN should be the one passed into the params", dn, x509userCert.getSubjectDN());
    assertEquals("The Issuer DN should be the same as the Subject DN", dn, x509userCert.getIssuerDN());
    assertEquals("The Serial should be the one passed into the params", serial, x509userCert.getSerialNumber());
    assertDateEquals("The notBefore date should be the one passed into the params", start, x509userCert.getNotBefore());
    assertDateEquals("The notAfter date should be the one passed into the params", end, x509userCert.getNotAfter());
    // Assert that the cert's signature verifies using the public key from generated KeyPair
    x509userCert.verify(pubKey);
    // Assert that the cert's signature verifies using the public key from the cert itself.
    x509userCert.verify(x509userCert.getPublicKey());
    final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias);
    assertNull("A list of CA certificates should not exist for the generated entry", caCerts);
    ExportResult exportResult = mAndroidKeyStore.exportKey(Credentials.USER_PRIVATE_KEY + alias, KeymasterDefs.KM_KEY_FORMAT_X509, null, null);
    assertEquals(KeyStore.NO_ERROR, exportResult.resultCode);
    final byte[] pubKeyBytes = exportResult.exportData;
    assertNotNull("The keystore should return the public key for the generated key", pubKeyBytes);
    assertTrue("Public key X.509 format should be as expected", Arrays.equals(pubKey.getEncoded(), pubKeyBytes));
}
Also used : RSAKey(java.security.interfaces.RSAKey) PrivateKey(java.security.PrivateKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) PublicKey(java.security.PublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) RSAKeyGenParameterSpec(java.security.spec.RSAKeyGenParameterSpec) ECKey(java.security.interfaces.ECKey) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) ECPublicKey(java.security.interfaces.ECPublicKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) ByteArrayInputStream(java.io.ByteArrayInputStream) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate) ExportResult(android.security.keymaster.ExportResult)

Aggregations

ECPublicKey (java.security.interfaces.ECPublicKey)35 RSAPublicKey (java.security.interfaces.RSAPublicKey)14 PublicKey (java.security.PublicKey)13 KeyFactory (java.security.KeyFactory)11 KeyPairGenerator (java.security.KeyPairGenerator)8 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)8 ECPrivateKey (java.security.interfaces.ECPrivateKey)8 X509EncodedKeySpec (java.security.spec.X509EncodedKeySpec)8 PrivateKey (java.security.PrivateKey)7 X509Certificate (java.security.cert.X509Certificate)7 ECParameterSpec (java.security.spec.ECParameterSpec)7 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)7 NonNull (android.annotation.NonNull)5 ExportResult (android.security.keymaster.ExportResult)5 ByteArrayInputStream (java.io.ByteArrayInputStream)5 KeyPair (java.security.KeyPair)5 NoSuchProviderException (java.security.NoSuchProviderException)5 ProviderException (java.security.ProviderException)5 Certificate (java.security.cert.Certificate)5 CertificateFactory (java.security.cert.CertificateFactory)5