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);
}
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;
}
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");
}
}
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();
}
}
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));
}
Aggregations