summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/jarjar-rules.txt1
-rw-r--r--crypto/src/main/java/org/conscrypt/AbstractSessionContext.java298
-rw-r--r--crypto/src/main/java/org/conscrypt/AlertException.java66
-rw-r--r--crypto/src/main/java/org/conscrypt/AlertProtocol.java281
-rw-r--r--crypto/src/main/java/org/conscrypt/Appendable.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/ByteArray.java44
-rw-r--r--crypto/src/main/java/org/conscrypt/CertPinManager.java229
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateMessage.java166
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateRequest.java159
-rw-r--r--crypto/src/main/java/org/conscrypt/CertificateVerify.java90
-rw-r--r--crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java58
-rw-r--r--crypto/src/main/java/org/conscrypt/CipherSuite.java1184
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java604
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientHello.java207
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientKeyExchange.java148
-rw-r--r--crypto/src/main/java/org/conscrypt/ClientSessionContext.java145
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionState.java177
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java361
-rw-r--r--crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java351
-rw-r--r--crypto/src/main/java/org/conscrypt/ContentType.java49
-rw-r--r--crypto/src/main/java/org/conscrypt/DHParameters.java108
-rw-r--r--crypto/src/main/java/org/conscrypt/DataStream.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java130
-rw-r--r--crypto/src/main/java/org/conscrypt/DelegatedTask.java43
-rw-r--r--crypto/src/main/java/org/conscrypt/DigitalSignature.java259
-rw-r--r--crypto/src/main/java/org/conscrypt/EndOfBufferException.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/EndOfSourceException.java33
-rw-r--r--crypto/src/main/java/org/conscrypt/FileClientSessionCache.java365
-rw-r--r--crypto/src/main/java/org/conscrypt/Finished.java78
-rw-r--r--crypto/src/main/java/org/conscrypt/Handshake.java89
-rw-r--r--crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java435
-rw-r--r--crypto/src/main/java/org/conscrypt/HandshakeProtocol.java527
-rw-r--r--crypto/src/main/java/org/conscrypt/HelloRequest.java73
-rw-r--r--crypto/src/main/java/org/conscrypt/JSSEProvider.java123
-rw-r--r--crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java116
-rw-r--r--crypto/src/main/java/org/conscrypt/KeyManagerImpl.java220
-rw-r--r--crypto/src/main/java/org/conscrypt/Logger.java108
-rw-r--r--crypto/src/main/java/org/conscrypt/Message.java70
-rw-r--r--crypto/src/main/java/org/conscrypt/NativeCrypto.java1097
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java72
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipher.java850
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java357
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java52
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java201
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java90
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java155
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java234
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java193
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java42
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java158
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java171
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java188
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java110
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java83
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java188
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java173
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLEngine.java139
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLKey.java213
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java21
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLMac.java167
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java154
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLProvider.java241
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java232
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java74
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java329
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java271
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java189
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLRandom.java41
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java137
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java76
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java245
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java449
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSignature.java343
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java195
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java100
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java1137
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java203
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java391
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java135
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java246
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java497
-rw-r--r--crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java340
-rw-r--r--crypto/src/main/java/org/conscrypt/PRF.java198
-rw-r--r--crypto/src/main/java/org/conscrypt/PinEntryException.java29
-rw-r--r--crypto/src/main/java/org/conscrypt/PinFailureLogger.java70
-rw-r--r--crypto/src/main/java/org/conscrypt/PinListEntry.java155
-rw-r--r--crypto/src/main/java/org/conscrypt/PinManagerException.java32
-rw-r--r--crypto/src/main/java/org/conscrypt/Platform.java55
-rw-r--r--crypto/src/main/java/org/conscrypt/ProtocolVersion.java145
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLBufferedInput.java75
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java53
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLContextImpl.java141
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineAppData.java93
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java91
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLEngineImpl.java753
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLInputStream.java113
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLParametersImpl.java418
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java477
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java52
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java128
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java266
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSessionImpl.java236
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java162
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketImpl.java847
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java164
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java45
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java232
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLStreamedInput.java57
-rw-r--r--crypto/src/main/java/org/conscrypt/SSLv3Constants.java84
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java653
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHello.java136
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerHelloDone.java76
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerKeyExchange.java245
-rw-r--r--crypto/src/main/java/org/conscrypt/ServerSessionContext.java88
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java82
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustManagerImpl.java536
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java148
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java113
-rw-r--r--crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java587
-rw-r--r--crypto/src/main/java/org/conscrypt/X509PublicKey.java86
-rw-r--r--crypto/src/main/java/org/conscrypt/util/EmptyArray.java35
-rw-r--r--crypto/src/main/native/org_conscrypt_NativeCrypto.cpp8244
-rw-r--r--crypto/src/main/native/sub.mk18
-rw-r--r--crypto/src/test/java/org/conscrypt/CertPinManagerTest.java175
-rw-r--r--crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java128
-rw-r--r--crypto/src/test/java/org/conscrypt/CipherSuiteTest.java167
-rw-r--r--crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java120
-rw-r--r--crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java56
-rw-r--r--crypto/src/test/java/org/conscrypt/MacTest.java69
-rw-r--r--crypto/src/test/java/org/conscrypt/NativeCryptoTest.java2629
-rw-r--r--crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java36
-rw-r--r--crypto/src/test/java/org/conscrypt/SignatureTest.java125
-rw-r--r--crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java235
-rw-r--r--crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java662
135 files changed, 0 insertions, 39144 deletions
diff --git a/crypto/jarjar-rules.txt b/crypto/jarjar-rules.txt
deleted file mode 100644
index 0eb6ac2..0000000
--- a/crypto/jarjar-rules.txt
+++ /dev/null
@@ -1 +0,0 @@
-rule org.conscrypt.** com.android.@0
diff --git a/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java b/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java
deleted file mode 100644
index 4aed70c..0000000
--- a/crypto/src/main/java/org/conscrypt/AbstractSessionContext.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionContext;
-
-/**
- * Supports SSL session caches.
- */
-abstract class AbstractSessionContext implements SSLSessionContext {
-
- volatile int maximumSize;
- volatile int timeout;
-
- final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
-
- /** Identifies OpenSSL sessions. */
- static final int OPEN_SSL = 1;
-
- private final Map<ByteArray, SSLSession> sessions
- = new LinkedHashMap<ByteArray, SSLSession>() {
- @Override
- protected boolean removeEldestEntry(
- Map.Entry<ByteArray, SSLSession> eldest) {
- boolean remove = maximumSize > 0 && size() > maximumSize;
- if (remove) {
- remove(eldest.getKey());
- sessionRemoved(eldest.getValue());
- }
- return false;
- }
- };
-
- /**
- * Constructs a new session context.
- *
- * @param maximumSize of cache
- * @param timeout for cache entries
- */
- AbstractSessionContext(int maximumSize, int timeout) {
- this.maximumSize = maximumSize;
- this.timeout = timeout;
- }
-
- /**
- * Returns the collection of sessions ordered from oldest to newest
- */
- private Iterator<SSLSession> sessionIterator() {
- synchronized (sessions) {
- SSLSession[] array = sessions.values().toArray(
- new SSLSession[sessions.size()]);
- return Arrays.asList(array).iterator();
- }
- }
-
- public final Enumeration<byte[]> getIds() {
- final Iterator<SSLSession> i = sessionIterator();
- return new Enumeration<byte[]>() {
- private SSLSession next;
- public boolean hasMoreElements() {
- if (next != null) {
- return true;
- }
- while (i.hasNext()) {
- SSLSession session = i.next();
- if (session.isValid()) {
- next = session;
- return true;
- }
- }
- next = null;
- return false;
- }
- public byte[] nextElement() {
- if (hasMoreElements()) {
- byte[] id = next.getId();
- next = null;
- return id;
- }
- throw new NoSuchElementException();
- }
- };
- }
-
- public final int getSessionCacheSize() {
- return maximumSize;
- }
-
- public final int getSessionTimeout() {
- return timeout;
- }
-
- /**
- * Makes sure cache size is < maximumSize.
- */
- protected void trimToSize() {
- synchronized (sessions) {
- int size = sessions.size();
- if (size > maximumSize) {
- int removals = size - maximumSize;
- Iterator<SSLSession> i = sessions.values().iterator();
- do {
- SSLSession session = i.next();
- i.remove();
- sessionRemoved(session);
- } while (--removals > 0);
- }
- }
- }
-
- public void setSessionTimeout(int seconds)
- throws IllegalArgumentException {
- if (seconds < 0) {
- throw new IllegalArgumentException("seconds < 0");
- }
- timeout = seconds;
-
- synchronized (sessions) {
- Iterator<SSLSession> i = sessions.values().iterator();
- while (i.hasNext()) {
- SSLSession session = i.next();
- // SSLSession's know their context and consult the
- // timeout as part of their validity condition.
- if (!session.isValid()) {
- i.remove();
- sessionRemoved(session);
- }
- }
- }
- }
-
- /**
- * Called when a session is removed. Used by ClientSessionContext
- * to update its host-and-port based cache.
- */
- protected abstract void sessionRemoved(SSLSession session);
-
- public final void setSessionCacheSize(int size)
- throws IllegalArgumentException {
- if (size < 0) {
- throw new IllegalArgumentException("size < 0");
- }
-
- int oldMaximum = maximumSize;
- maximumSize = size;
-
- // Trim cache to size if necessary.
- if (size < oldMaximum) {
- trimToSize();
- }
- }
-
- /**
- * Converts the given session to bytes.
- *
- * @return session data as bytes or null if the session can't be converted
- */
- byte[] toBytes(SSLSession session) {
- // TODO: Support SSLSessionImpl, too.
- if (!(session instanceof OpenSSLSessionImpl)) {
- return null;
- }
-
- OpenSSLSessionImpl sslSession = (OpenSSLSessionImpl) session;
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream daos = new DataOutputStream(baos);
-
- daos.writeInt(OPEN_SSL); // session type ID
-
- // Session data.
- byte[] data = sslSession.getEncoded();
- daos.writeInt(data.length);
- daos.write(data);
-
- // Certificates.
- Certificate[] certs = session.getPeerCertificates();
- daos.writeInt(certs.length);
-
- for (Certificate cert : certs) {
- data = cert.getEncoded();
- daos.writeInt(data.length);
- daos.write(data);
- }
- // TODO: local certificates?
-
- return baos.toByteArray();
- } catch (IOException e) {
- log(e);
- return null;
- } catch (CertificateEncodingException e) {
- log(e);
- return null;
- }
- }
-
- /**
- * Creates a session from the given bytes.
- *
- * @return a session or null if the session can't be converted
- */
- SSLSession toSession(byte[] data, String host, int port) {
- ByteArrayInputStream bais = new ByteArrayInputStream(data);
- DataInputStream dais = new DataInputStream(bais);
- try {
- int type = dais.readInt();
- if (type != OPEN_SSL) {
- log(new AssertionError("Unexpected type ID: " + type));
- return null;
- }
-
- int length = dais.readInt();
- byte[] sessionData = new byte[length];
- dais.readFully(sessionData);
-
- int count = dais.readInt();
- X509Certificate[] certs = new X509Certificate[count];
- for (int i = 0; i < count; i++) {
- length = dais.readInt();
- byte[] certData = new byte[length];
- dais.readFully(certData);
- certs[i] = OpenSSLX509Certificate.fromX509Der(certData);
- }
-
- return new OpenSSLSessionImpl(sessionData, host, port, certs, this);
- } catch (IOException e) {
- log(e);
- return null;
- }
- }
-
- public SSLSession getSession(byte[] sessionId) {
- if (sessionId == null) {
- throw new NullPointerException("sessionId == null");
- }
- ByteArray key = new ByteArray(sessionId);
- SSLSession session;
- synchronized (sessions) {
- session = sessions.get(key);
- }
- if (session != null && session.isValid()) {
- return session;
- }
- return null;
- }
-
- void putSession(SSLSession session) {
- byte[] id = session.getId();
- if (id.length == 0) {
- return;
- }
- ByteArray key = new ByteArray(id);
- synchronized (sessions) {
- sessions.put(key, session);
- }
- }
-
- static void log(Throwable t) {
- System.logW("Error converting session.", t);
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- NativeCrypto.SSL_CTX_free(sslCtxNativePointer);
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/AlertException.java b/crypto/src/main/java/org/conscrypt/AlertException.java
deleted file mode 100644
index a483021..0000000
--- a/crypto/src/main/java/org/conscrypt/AlertException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLException;
-
-/**
- * This exception is used to signal that a fatal alert has occurred while working through the
- * protocol.
- */
-public class AlertException extends RuntimeException {
-
- private static final long serialVersionUID = -4448327177165687581L;
- // SSLException to be thrown to application side
- private final SSLException reason;
- // alert description code
- private final byte description;
-
- /**
- * Constructs the instance.
- *
- * @param description The alert description code from {@link AlertProtocol}
- * @param reason The SSLException to be thrown to application side after alert processing
- * (sending the record with alert, shutdown work, etc).
- * @see AlertProtocol
- */
- protected AlertException(byte description, SSLException reason) {
- super(reason);
- this.reason = reason;
- this.description = description;
- }
-
- /**
- * Returns the reason of alert. This reason should be rethrown after alert processing.
- *
- * @return the reason of alert.
- */
- protected SSLException getReason() {
- return reason;
- }
-
- /**
- * Returns alert's description code.
- *
- * @return alert description code from {@link AlertProtocol}
- * @see AlertProtocol for more information about possible reason codes.
- */
- protected byte getDescriptionCode() {
- return description;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/AlertProtocol.java b/crypto/src/main/java/org/conscrypt/AlertProtocol.java
deleted file mode 100644
index 0330e79..0000000
--- a/crypto/src/main/java/org/conscrypt/AlertProtocol.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This class encapsulates the functionality of Alert Protocol.
- * Constant values are taken according to the TLS v1 specification
- * (http://www.ietf.org/rfc/rfc2246.txt), p 7.2.
- */
-public class AlertProtocol {
-
- // ------------------------ AlertLevel codes --------------------------
- /**
- * Defines the severity of alert as warning
- */
- protected static final byte WARNING = 1;
- /**
- * Defines the severity of alert as fatal
- */
- protected static final byte FATAL = 2;
-
- // --------------------- AlertDescription codes -----------------------
- /**
- * Defines the description code of the close_notify alert
- */
- protected static final byte CLOSE_NOTIFY = 0;
- /**
- * Defines the description code of the unexpected_message alert
- */
- protected static final byte UNEXPECTED_MESSAGE = 10;
- /**
- * Defines the description code of the bad_record_mac alert
- */
- protected static final byte BAD_RECORD_MAC = 20;
- /**
- * Defines the description code of the decryption_failed alert
- */
- protected static final byte DECRYPTION_FAILED = 21;
- /**
- * Defines the description code of the record_overflow alert
- */
- protected static final byte RECORD_OVERFLOW = 22;
- /**
- * Defines the description code of the decompression_failure alert
- */
- protected static final byte DECOMPRESSION_FAILURE = 30;
- /**
- * Defines the description code of the handshake_failure alert
- */
- protected static final byte HANDSHAKE_FAILURE = 40;
- /**
- * Defines the description code of the bad_certificate alert
- */
- protected static final byte BAD_CERTIFICATE = 42;
- /**
- * Defines the description code of the unsupported_certificate alert
- */
- protected static final byte UNSUPPORTED_CERTIFICATE = 43;
- /**
- * Defines the description code of the certificate_revoked alert
- */
- protected static final byte CERTIFICATE_REVOKED = 44;
- /**
- * Defines the description code of the certificate_expired alert
- */
- protected static final byte CERTIFICATE_EXPIRED = 45;
- /**
- * Defines the description code of the certificate_unknown alert
- */
- protected static final byte CERTIFICATE_UNKNOWN = 46;
- /**
- * Defines the description code of the illegal_parameter alert
- */
- protected static final byte ILLEGAL_PARAMETER = 47;
- /**
- * Defines the description code of the unknown_ca alert
- */
- protected static final byte UNKNOWN_CA = 48;
- /**
- * Defines the description code of the access_denied alert
- */
- protected static final byte ACCESS_DENIED = 49;
- /**
- * Defines the description code of the decode_error alert
- */
- protected static final byte DECODE_ERROR = 50;
- /**
- * Defines the description code of the decrypt_error alert
- */
- protected static final byte DECRYPT_ERROR = 51;
- /**
- * Defines the description code of the export_restriction alert
- */
- protected static final byte EXPORT_RESTRICTION = 60;
- /**
- * Defines the description code of the protocol_version alert
- */
- protected static final byte PROTOCOL_VERSION = 70;
- /**
- * Defines the description code of the insufficient_security alert
- */
- protected static final byte INSUFFICIENT_SECURITY = 71;
- /**
- * Defines the description code of the internal_error alert
- */
- protected static final byte INTERNAL_ERROR = 80;
- /**
- * Defines the description code of the user_canceled alert
- */
- protected static final byte USER_CANCELED = 90;
- /**
- * Defines the description code of the no_renegotiation alert
- */
- protected static final byte NO_RENEGOTIATION = 100;
- // holds level and description codes
- private final byte[] alert = new byte[2];
- // record protocol to be used to wrap the alerts
- private SSLRecordProtocol recordProtocol;
-
- private Logger.Stream logger = Logger.getStream("alert");
-
- /**
- * Creates the instance of AlertProtocol.
- * Note that class is not ready to work without providing of
- * record protocol
- * @see #setRecordProtocol
- */
- protected AlertProtocol() {}
-
- /**
- * Sets up the record protocol to be used by this allert protocol.
- */
- protected void setRecordProtocol(SSLRecordProtocol recordProtocol) {
- this.recordProtocol = recordProtocol;
- }
-
- /**
- * Reports an alert to be sent/received by transport.
- * This method is usually called during processing
- * of the income TSL record: if it contains alert message from another
- * peer, or if warning alert occured during the processing of the
- * message and this warning should be sent to another peer.
- * @param level alert level code
- * @param description alert description code
- */
- protected void alert(byte level, byte description) {
- if (logger != null) {
- logger.println("Alert.alert: "+level+" "+description);
- }
- this.alert[0] = level;
- this.alert[1] = description;
- }
-
- /**
- * Returns the description code of alert or -100 if there
- * is no alert.
- */
- protected byte getDescriptionCode() {
- return (alert[0] != 0) ? alert[1] : -100;
- }
-
- /**
- * Resets the protocol to be in "no alert" state.
- * This method shoud be called after processing of the reported alert.
- */
- protected void setProcessed() {
- // free the info about alert
- if (logger != null) {
- logger.println("Alert.setProcessed");
- }
- this.alert[0] = 0;
- }
-
- /**
- * Checks if any alert has occured.
- */
- protected boolean hasAlert() {
- return (alert[0] != 0);
- }
-
- /**
- * Checks if occured alert is fatal alert.
- */
- protected boolean isFatalAlert() {
- return (alert[0] == 2);
- }
-
- /**
- * Returns the string representation of occured alert.
- * If no alert has occured null is returned.
- */
- protected String getAlertDescription() {
- switch (alert[1]) {
- case CLOSE_NOTIFY:
- return "close_notify";
- case UNEXPECTED_MESSAGE:
- return "unexpected_message";
- case BAD_RECORD_MAC:
- return "bad_record_mac";
- case DECRYPTION_FAILED:
- return "decryption_failed";
- case RECORD_OVERFLOW:
- return "record_overflow";
- case DECOMPRESSION_FAILURE:
- return "decompression_failure";
- case HANDSHAKE_FAILURE:
- return "handshake_failure";
- case BAD_CERTIFICATE:
- return "bad_certificate";
- case UNSUPPORTED_CERTIFICATE:
- return "unsupported_certificate";
- case CERTIFICATE_REVOKED:
- return "certificate_revoked";
- case CERTIFICATE_EXPIRED:
- return "certificate_expired";
- case CERTIFICATE_UNKNOWN:
- return "certificate_unknown";
- case ILLEGAL_PARAMETER:
- return "illegal_parameter";
- case UNKNOWN_CA:
- return "unknown_ca";
- case ACCESS_DENIED:
- return "access_denied";
- case DECODE_ERROR:
- return "decode_error";
- case DECRYPT_ERROR:
- return "decrypt_error";
- case EXPORT_RESTRICTION:
- return "export_restriction";
- case PROTOCOL_VERSION:
- return "protocol_version";
- case INSUFFICIENT_SECURITY:
- return "insufficient_security";
- case INTERNAL_ERROR:
- return "internal_error";
- case USER_CANCELED:
- return "user_canceled";
- case NO_RENEGOTIATION:
- return "no_renegotiation";
- }
- return null;
- }
-
- /**
- * Returns the record with reported alert message.
- * The returned array of bytes is ready to be sent to another peer.
- * Note, that this method does not automatically set the state of alert
- * protocol in "no alert" state, so after wrapping the method setProcessed
- * should be called.
- */
- protected byte[] wrap() {
- byte[] res = recordProtocol.wrap(ContentType.ALERT, alert, 0, 2);
- return res;
- }
-
- /**
- * Shutdown the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- alert[0] = 0;
- alert[1] = 0;
- recordProtocol = null;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/Appendable.java b/crypto/src/main/java/org/conscrypt/Appendable.java
deleted file mode 100644
index d22c5a8..0000000
--- a/crypto/src/main/java/org/conscrypt/Appendable.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This interface represents the ability of the input stream related classes to provide additional
- * data to be read.
- */
-public interface Appendable {
-
- /**
- * Provides the additional data to be read.
- *
- * @param src the source data to be appended.
- */
- public void append(byte[] src);
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ByteArray.java b/crypto/src/main/java/org/conscrypt/ByteArray.java
deleted file mode 100644
index be682de..0000000
--- a/crypto/src/main/java/org/conscrypt/ByteArray.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.Arrays;
-
-/**
- * Byte array wrapper for hashtable use. Implements equals() and hashCode().
- */
-final class ByteArray {
- private final byte[] bytes;
- private final int hashCode;
-
- ByteArray(byte[] bytes) {
- this.bytes = bytes;
- this.hashCode = Arrays.hashCode(bytes);
- }
-
- @Override public int hashCode() {
- return hashCode;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof ByteArray)) {
- return false;
- }
- ByteArray lhs = (ByteArray) o;
- return Arrays.equals(bytes, lhs.bytes);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertPinManager.java b/crypto/src/main/java/org/conscrypt/CertPinManager.java
deleted file mode 100644
index 22578fc..0000000
--- a/crypto/src/main/java/org/conscrypt/CertPinManager.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import libcore.io.IoUtils;
-import libcore.util.BasicLruCache;
-
-/**
- * This class provides a simple interface for cert pinning.
- */
-public class CertPinManager {
-
- private long lastModified;
-
- private final Map<String, PinListEntry> entries = new HashMap<String, PinListEntry>();
- private final BasicLruCache<String, String> hostnameCache = new BasicLruCache<String, String>(10);
-
- private boolean initialized = false;
- private static final boolean DEBUG = false;
-
- private final File pinFile;
- private final TrustedCertificateStore certStore;
-
- public CertPinManager(TrustedCertificateStore store) throws PinManagerException {
- pinFile = new File("/data/misc/keychain/pins");
- certStore = store;
- rebuild();
- }
-
- /** Test only */
- public CertPinManager(String path, TrustedCertificateStore store) throws PinManagerException {
- if (path == null) {
- throw new NullPointerException("path == null");
- }
- pinFile = new File(path);
- certStore = store;
- rebuild();
- }
-
- /**
- * This is the public interface for cert pinning.
- *
- * Given a hostname and a certificate chain this verifies that the chain includes
- * certs from the pinned list provided.
- *
- * If the chain doesn't include those certs and is in enforcing mode, then this method
- * returns true and the certificate check should fail.
- */
- public boolean chainIsNotPinned(String hostname, List<X509Certificate> chain)
- throws PinManagerException {
- // lookup the entry
- PinListEntry entry = lookup(hostname);
-
- // return its result or false if there's no pin
- if (entry != null) {
- return entry.chainIsNotPinned(chain);
- }
- return false;
- }
-
- private synchronized void rebuild() throws PinManagerException {
- // reread the pin file
- String pinFileContents = readPinFile();
-
- if (pinFileContents != null) {
- // rebuild the pinned certs
- for (String entry : getPinFileEntries(pinFileContents)) {
- try {
- PinListEntry pin = new PinListEntry(entry, certStore);
- entries.put(pin.getCommonName(), pin);
- } catch (PinEntryException e) {
- log("Pinlist contains a malformed pin: " + entry, e);
- }
- }
-
- // clear the cache
- hostnameCache.evictAll();
-
- // set the last modified time
- lastModified = pinFile.lastModified();
-
- // we've been fully initialized and are ready to go
- initialized = true;
- }
- }
-
- private String readPinFile() throws PinManagerException {
- try {
- return IoUtils.readFileAsString(pinFile.getPath());
- } catch (FileNotFoundException e) {
- // there's no pin list, all certs are unpinned
- return null;
- } catch (IOException e) {
- // this is unexpected, fail
- throw new PinManagerException("Unexpected error reading pin list; failing.", e);
- }
- }
-
- private static String[] getPinFileEntries(String pinFileContents) {
- return pinFileContents.split("\n");
- }
-
- private synchronized PinListEntry lookup(String hostname) throws PinManagerException {
-
- // if we don't have any data, don't bother
- if (!initialized) {
- return null;
- }
-
- // check to see if our cache is valid
- if (cacheIsNotValid()) {
- rebuild();
- }
-
- // if so, check the hostname cache
- String cn = hostnameCache.get(hostname);
- if (cn != null) {
- // if we hit, return the corresponding entry
- return entries.get(cn);
- }
-
- // otherwise, get the matching cn
- cn = getMatchingCN(hostname);
- if (cn != null) {
- hostnameCache.put(hostname, cn);
- // we have a matching CN, return that entry
- return entries.get(cn);
- }
-
- // if we got here, we don't have a matching CN for this hostname
- return null;
- }
-
- private boolean cacheIsNotValid() {
- return pinFile.lastModified() != lastModified;
- }
-
- private String getMatchingCN(String hostname) {
- String bestMatch = "";
- for (String cn : entries.keySet()) {
- // skip shorter CNs since they can't be better matches
- if (cn.length() < bestMatch.length()) {
- continue;
- }
- // now verify that the CN matches at all
- if (isHostnameMatchedBy(hostname, cn)) {
- bestMatch = cn;
- }
- }
- return bestMatch;
- }
-
- /**
- * Returns true if {@code hostName} matches the name or pattern {@code cn}.
- *
- * @param hostName lowercase host name.
- * @param cn certificate host name. May include wildcards like
- * {@code *.android.com}.
- */
- private static boolean isHostnameMatchedBy(String hostName, String cn) {
- if (hostName == null || hostName.isEmpty() || cn == null || cn.isEmpty()) {
- return false;
- }
-
- cn = cn.toLowerCase(Locale.US);
-
- if (!cn.contains("*")) {
- return hostName.equals(cn);
- }
-
- if (cn.startsWith("*.") && hostName.regionMatches(0, cn, 2, cn.length() - 2)) {
- return true; // "*.foo.com" matches "foo.com"
- }
-
- int asterisk = cn.indexOf('*');
- int dot = cn.indexOf('.');
- if (asterisk > dot) {
- return false; // malformed; wildcard must be in the first part of
- // the cn
- }
-
- if (!hostName.regionMatches(0, cn, 0, asterisk)) {
- return false; // prefix before '*' doesn't match
- }
-
- int suffixLength = cn.length() - (asterisk + 1);
- int suffixStart = hostName.length() - suffixLength;
- if (hostName.indexOf('.', asterisk) < suffixStart) {
- return false; // wildcard '*' can't match a '.'
- }
-
- if (!hostName.regionMatches(suffixStart, cn, asterisk + 1, suffixLength)) {
- return false; // suffix after '*' doesn't match
- }
-
- return true;
- }
-
- private static void log(String s, Exception e) {
- if (DEBUG) {
- System.out.println("PINFILE: " + s);
- if (e != null) {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateMessage.java b/crypto/src/main/java/org/conscrypt/CertificateMessage.java
deleted file mode 100644
index 0c0e092..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateMessage.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-
-/**
- * Represents server/client certificate message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS
- * 1.0 spec., 7.4.2. Server certificate; 7.4.6. Client certificate</a>
- *
- */
-public class CertificateMessage extends Message {
-
- /**
- * Certificates
- */
- X509Certificate[] certs;
-
- /**
- * Certificates in encoded form
- */
- byte[][] encoded_certs;
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateMessage(HandshakeIODataStream in, int length) throws IOException {
- int l = in.readUint24(); // total_length
- if (l == 0) { // message contais no certificates
- if (length != 3) { // no more bytes after total_length
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateMessage");
- }
- certs = new X509Certificate[0];
- encoded_certs = new byte[0][0];
- this.length = 3;
- return;
- }
- CertificateFactory cf;
- try {
- cf = CertificateFactory.getInstance("X509");
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- return;
- }
- ArrayList<X509Certificate> certsList = new ArrayList<X509Certificate>();
- int size = 0;
- int enc_size = 0;
- while (l > 0) {
- size = in.readUint24();
- l -= 3;
- try {
- certsList.add((X509Certificate) cf.generateCertificate(in));
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR", e);
- }
- l -= size;
- enc_size += size;
- }
- certs = certsList.toArray(new X509Certificate[certsList.size()]);
- this.length = 3 + 3 * certs.length + enc_size;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect CertificateMessage");
- }
- }
-
- /**
- * Creates outbound message
- *
- * @param certs
- */
- public CertificateMessage(X509Certificate[] certs) {
- if (certs == null) {
- this.certs = new X509Certificate[0];
- encoded_certs = new byte[0][0];
- length = 3;
- return;
- }
- this.certs = certs;
- if (encoded_certs == null) {
- encoded_certs = new byte[certs.length][];
- for (int i = 0; i < certs.length; i++) {
- try {
- encoded_certs[i] = certs[i].getEncoded();
- } catch (CertificateEncodingException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
- e);
- }
- }
- }
- length = 3 + 3 * encoded_certs.length;
- for (int i = 0; i < encoded_certs.length; i++) {
- length += encoded_certs[i].length;
- }
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
-
- int total_length = 0;
- if (encoded_certs == null) {
- encoded_certs = new byte[certs.length][];
- for (int i = 0; i < certs.length; i++) {
- try {
- encoded_certs[i] = certs[i].getEncoded();
- } catch (CertificateEncodingException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR",
- e);
- }
- }
- }
- total_length = 3 * encoded_certs.length;
- for (int i = 0; i < encoded_certs.length; i++) {
- total_length += encoded_certs[i].length;
- }
- out.writeUint24(total_length);
- for (int i = 0; i < encoded_certs.length; i++) {
- out.writeUint24(encoded_certs[i].length);
- out.write(encoded_certs[i]);
- }
-
- }
-
- public String getAuthType() {
- return certs[0].getPublicKey().getAlgorithm();
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateRequest.java b/crypto/src/main/java/org/conscrypt/CertificateRequest.java
deleted file mode 100644
index 6d08cc2..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateRequest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import javax.security.auth.x500.X500Principal;
-import libcore.io.Streams;
-
-/**
- *
- * Represents certificate request message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.4.
- * Certificate request</a>
- */
-public class CertificateRequest extends Message {
-
- /**
- * Requested certificate types
- */
- final byte[] certificate_types;
-
- /**
- * Certificate authorities
- */
- final X500Principal[] certificate_authorities;
-
- /**
- * Requested certificate types as Strings
- * ("RSA", "DSA", "DH_RSA" or "DH_DSA")
- */
- private String[] types;
-
- /**
- * Encoded form of certificate authorities
- */
- private byte[][] encoded_principals;
-
- /**
- * Creates outbound message
- *
- * @param certificate_types
- * @param accepted - array of certificate authority certificates
- */
- public CertificateRequest(byte[] certificate_types,
- X509Certificate[] accepted) {
-
- if (accepted == null) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "CertificateRequest: array of certificate authority certificates is null");
- }
- this.certificate_types = certificate_types;
-
- int totalPrincipalsLength = 0;
- certificate_authorities = new X500Principal[accepted.length];
- encoded_principals = new byte[accepted.length][];
- for (int i = 0; i < accepted.length; i++) {
- certificate_authorities[i] = accepted[i].getIssuerX500Principal();
- encoded_principals[i] = certificate_authorities[i].getEncoded();
- totalPrincipalsLength += encoded_principals[i].length + 2;
- }
-
- length = 3 + certificate_types.length + totalPrincipalsLength;
- }
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateRequest(HandshakeIODataStream in, int length) throws IOException {
- int size = in.readUint8();
- certificate_types = new byte[size];
- Streams.readFully(in, certificate_types);
- size = in.readUint16();
- int totalPrincipalsLength = 0;
- int principalLength = 0;
- ArrayList<X500Principal> principals = new ArrayList<X500Principal>();
- while (totalPrincipalsLength < size) {
- principalLength = in.readUint16(); // encoded X500Principal size
- principals.add(new X500Principal(in));
- totalPrincipalsLength += 2;
- totalPrincipalsLength += principalLength;
- }
- certificate_authorities = principals.toArray(new X500Principal[principals.size()]);
- this.length = 3 + certificate_types.length + totalPrincipalsLength;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect CertificateRequest");
- }
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
-
- out.writeUint8(certificate_types.length);
- for (int i = 0; i < certificate_types.length; i++) {
- out.write(certificate_types[i]);
- }
- int authoritiesLength = 0;
- for (int i = 0; i < certificate_authorities.length; i++) {
- authoritiesLength += encoded_principals[i].length +2;
- }
- out.writeUint16(authoritiesLength);
- for (int i = 0; i < certificate_authorities.length; i++) {
- out.writeUint16(encoded_principals[i].length);
- out.write(encoded_principals[i]);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE_REQUEST;
- }
-
- /**
- * Returns requested certificate types as array of strings
- */
- public String[] getTypesAsString() {
- if (types == null) {
- types = new String[certificate_types.length];
- for (int i = 0; i < types.length; i++) {
- String type = CipherSuite.getClientKeyType(certificate_types[i]);
- if (type == null) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateRequest");
- }
- types[i] = type;
- }
- }
- return types;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/CertificateVerify.java b/crypto/src/main/java/org/conscrypt/CertificateVerify.java
deleted file mode 100644
index 8ba394a..0000000
--- a/crypto/src/main/java/org/conscrypt/CertificateVerify.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * Represents certificate verify message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.8.
- * Certificate verify</a>
- */
-public class CertificateVerify extends Message {
-
- /**
- * Signature
- */
- byte[] signedHash;
-
- /**
- * Creates outbound message
- *
- * @param hash
- */
- public CertificateVerify(byte[] hash) {
- if (hash == null || hash.length == 0) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "INTERNAL ERROR: incorrect certificate verify hash");
- }
- this.signedHash = hash;
- length = hash.length + 2;
- }
-
- /**
- * Creates inbound message
- *
- * @param in
- * @param length
- * @throws IOException
- */
- public CertificateVerify(HandshakeIODataStream in, int length)
- throws IOException {
- if (length == 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateVerify");
- } else {
- if (in.readUint16() != length - 2) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect CertificateVerify");
- }
- signedHash = in.read(length -2);
- }
- this.length = length;
- }
-
- /**
- * Sends message
- *
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- if (signedHash.length != 0) {
- out.writeUint16(signedHash.length);
- out.write(signedHash);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CERTIFICATE_VERIFY;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java b/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java
deleted file mode 100644
index dc4f9b7..0000000
--- a/crypto/src/main/java/org/conscrypt/ChainStrengthAnalyzer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-
-public final class ChainStrengthAnalyzer {
-
- private static final int MIN_MODULUS = 1024;
- private static final String[] OID_BLACKLIST = {"1.2.840.113549.1.1.4"}; // MD5withRSA
-
- public static final void check(X509Certificate[] chain) throws CertificateException {
- for (X509Certificate cert : chain) {
- checkCert(cert);
- }
- }
-
- private static final void checkCert(X509Certificate cert) throws CertificateException {
- checkModulusLength(cert);
- checkNotMD5(cert);
- }
-
- private static final void checkModulusLength(X509Certificate cert) throws CertificateException {
- Object pubkey = cert.getPublicKey();
- if (pubkey instanceof RSAPublicKey) {
- int modulusLength = ((RSAPublicKey) pubkey).getModulus().bitLength();
- if(!(modulusLength >= MIN_MODULUS)) {
- throw new CertificateException("Modulus is < 1024 bits");
- }
- }
- }
-
- private static final void checkNotMD5(X509Certificate cert) throws CertificateException {
- String oid = cert.getSigAlgOID();
- for (String blacklisted : OID_BLACKLIST) {
- if (oid.equals(blacklisted)) {
- throw new CertificateException("Signature uses an insecure hash function");
- }
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/CipherSuite.java b/crypto/src/main/java/org/conscrypt/CipherSuite.java
deleted file mode 100644
index 6d2a3e8..0000000
--- a/crypto/src/main/java/org/conscrypt/CipherSuite.java
+++ /dev/null
@@ -1,1184 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.util.Hashtable;
-import javax.crypto.Cipher;
-
-/**
- * Represents Cipher Suite as defined in TLS 1.0 spec.,
- * A.5. The CipherSuite;
- * C. CipherSuite definitions.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec.</a>
- *
- */
-public class CipherSuite {
-
- /**
- * true if this cipher suite is supported
- */
- boolean supported = true;
-
- /**
- * cipher suite key exchange
- */
- final int keyExchange;
-
- /**
- * algorithm used for authentication ("RSA", "DSA", "DH", null for anonymous)
- */
- final String authType;
-
- /**
- * cipher
- */
- final String cipherName;
-
- /**
- * Cipher information
- */
- final int keyMaterial;
- final int expandedKeyMaterial;
- final int effectiveKeyBytes;
- final int ivSize;
- final private int blockSize;
-
- // cipher suite code
- private final byte[] cipherSuiteCode;
-
- // cipher suite name
- private final String name;
-
- // true if cipher suite is exportable
- private final boolean isExportable;
-
- // Hash algorithm
- final private String hashName;
-
- // MAC algorithm
- final private String hmacName;
-
- // Hash size
- final private int hashSize;
-
- /**
- * key exchange values
- */
- static final int KEY_EXCHANGE_RSA = 1;
- static final int KEY_EXCHANGE_RSA_EXPORT = 2;
- static final int KEY_EXCHANGE_DHE_DSS = 3;
- static final int KEY_EXCHANGE_DHE_DSS_EXPORT = 4;
- static final int KEY_EXCHANGE_DHE_RSA = 5;
- static final int KEY_EXCHANGE_DHE_RSA_EXPORT = 6;
- // BEGIN android-removed
- // static final int KEY_EXCHANGE_DH_DSS = 7;
- // static final int KEY_EXCHANGE_DH_RSA = 8;
- // END android-removed
- static final int KEY_EXCHANGE_DH_anon = 9;
- static final int KEY_EXCHANGE_DH_anon_EXPORT = 10;
- // BEGIN android-removed
- // static final int KEY_EXCHANGE_DH_DSS_EXPORT = 11;
- // static final int KEY_EXCHANGE_DH_RSA_EXPORT = 12;
- // END android-removed
- static final int KEY_EXCHANGE_ECDH_ECDSA = 13;
- static final int KEY_EXCHANGE_ECDHE_ECDSA = 14;
- static final int KEY_EXCHANGE_ECDH_RSA = 15;
- static final int KEY_EXCHANGE_ECDHE_RSA = 16;
- static final int KEY_EXCHANGE_ECDH_anon = 17;
-
- /**
- * TLS cipher suite codes
- */
- static final byte[] CODE_SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
- static final byte[] CODE_SSL_RSA_WITH_NULL_MD5 = { 0x00, 0x01 };
- static final byte[] CODE_SSL_RSA_WITH_NULL_SHA = { 0x00, 0x02 };
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x03 };
- static final byte[] CODE_SSL_RSA_WITH_RC4_128_MD5 = { 0x00, 0x04 };
- static final byte[] CODE_SSL_RSA_WITH_RC4_128_SHA = { 0x00, 0x05 };
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00, 0x06 };
- // BEGIN android-removed
- // static final byte[] CODE_TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00, 0x07 };
- // END android-removed
- static final byte[] CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x08 };
- static final byte[] CODE_SSL_RSA_WITH_DES_CBC_SHA = { 0x00, 0x09 };
- static final byte[] CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0A };
- // BEGIN android-removed
- // static final byte[] CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
- // static final byte[] CODE_SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
- // static final byte[] CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x0D };
- // static final byte[] CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0E };
- // static final byte[] CODE_SSL_DH_RSA_WITH_DES_CBC_SHA = { 0x00, 0x0F };
- // static final byte[] CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x10 };
- // END android-removed
- static final byte[] CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x11 };
- static final byte[] CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA = { 0x00, 0x12 };
- static final byte[] CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x13 };
- static final byte[] CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x14 };
- static final byte[] CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA = { 0x00, 0x15 };
- static final byte[] CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x16 };
- static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
- static final byte[] CODE_SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
- static final byte[] CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x19 };
- static final byte[] CODE_SSL_DH_anon_WITH_DES_CBC_SHA = { 0x00, 0x1A };
- static final byte[] CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x1B };
-
- // AES Cipher Suites from RFC 3268 - http://www.ietf.org/rfc/rfc3268.txt
- static final byte[] CODE_TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x2F };
- //static final byte[] CODE_TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x30 };
- //static final byte[] CODE_TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x31 };
- static final byte[] CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00, 0x32 };
- static final byte[] CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00, 0x33 };
- static final byte[] CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00, 0x34 };
- static final byte[] CODE_TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x35 };
- //static final byte[] CODE_TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x36 };
- //static final byte[] CODE_TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x37 };
- static final byte[] CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00, 0x38 };
- static final byte[] CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00, 0x39 };
- static final byte[] CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00, 0x3A };
-
- // EC Cipher Suites from RFC 4492 - http://www.ietf.org/rfc/rfc4492.txt
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_NULL_SHA = { (byte) 0xc0, 0x01};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x02};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x03};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x04};
- static final byte[] CODE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x05};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_NULL_SHA = { (byte) 0xc0, 0x06};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x07};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x08};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x09};
- static final byte[] CODE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x0A};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_NULL_SHA = { (byte) 0xc0, 0x0B};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x0C};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x0D};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x0E};
- static final byte[] CODE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x0F};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_NULL_SHA = { (byte) 0xc0, 0x10};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_RC4_128_SHA = { (byte) 0xc0, 0x11};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x12};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x13};
- static final byte[] CODE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x14};
- static final byte[] CODE_TLS_ECDH_anon_WITH_NULL_SHA = { (byte) 0xc0, 0x15};
- static final byte[] CODE_TLS_ECDH_anon_WITH_RC4_128_SHA = { (byte) 0xc0, 0x16};
- static final byte[] CODE_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = { (byte) 0xc0, 0x17};
- static final byte[] CODE_TLS_ECDH_anon_WITH_AES_128_CBC_SHA = { (byte) 0xc0, 0x18};
- static final byte[] CODE_TLS_ECDH_anon_WITH_AES_256_CBC_SHA = { (byte) 0xc0, 0x19};
-
- static final CipherSuite SSL_NULL_WITH_NULL_NULL = new CipherSuite(
- "SSL_NULL_WITH_NULL_NULL", true, 0, null, null, null,
- CODE_SSL_NULL_WITH_NULL_NULL);
-
- static final CipherSuite SSL_RSA_WITH_NULL_MD5 = new CipherSuite(
- "SSL_RSA_WITH_NULL_MD5", true, KEY_EXCHANGE_RSA, "RSA", null, "MD5",
- CODE_SSL_RSA_WITH_NULL_MD5);
-
- static final CipherSuite SSL_RSA_WITH_NULL_SHA = new CipherSuite(
- "SSL_RSA_WITH_NULL_SHA", true, KEY_EXCHANGE_RSA, "RSA", null, "SHA",
- CODE_SSL_RSA_WITH_NULL_SHA);
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "RC4_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC4_40_MD5);
-
- static final CipherSuite SSL_RSA_WITH_RC4_128_MD5 = new CipherSuite(
- "SSL_RSA_WITH_RC4_128_MD5", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
- "MD5", CODE_SSL_RSA_WITH_RC4_128_MD5);
-
- static final CipherSuite SSL_RSA_WITH_RC4_128_SHA = new CipherSuite(
- "SSL_RSA_WITH_RC4_128_SHA", false, KEY_EXCHANGE_RSA, "RSA", "RC4_128",
- "SHA", CODE_SSL_RSA_WITH_RC4_128_SHA);
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "RC2_CBC_40", "MD5", CODE_SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
-
- // BEGIN android-removed
- // static final CipherSuite TLS_RSA_WITH_IDEA_CBC_SHA = new CipherSuite(
- // "TLS_RSA_WITH_IDEA_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "IDEA_CBC",
- // "SHA", CODE_TLS_RSA_WITH_IDEA_CBC_SHA);
- // END android-removed
-
- static final CipherSuite SSL_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", true, KEY_EXCHANGE_RSA_EXPORT,
- "RSA", "DES40_CBC", "SHA", CODE_SSL_RSA_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_RSA, "RSA", "DES_CBC",
- "SHA", CODE_SSL_RSA_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_RSA,
- "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_RSA_WITH_3DES_EDE_CBC_SHA);
-
- // BEGIN android-removed
- // static final CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
- // KEY_EXCHANGE_DH_DSS_EXPORT, "DH", "DES40_CBC", "SHA",
- // CODE_SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
- // "DH", "DES_CBC", "SHA", CODE_SSL_DH_DSS_WITH_DES_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- // "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
- // "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
- // KEY_EXCHANGE_DH_RSA_EXPORT, "DH", "DES40_CBC", "SHA",
- // CODE_SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
- // "DH", "DES_CBC", "SHA", CODE_SSL_DH_RSA_WITH_DES_CBC_SHA);
- //
- // static final CipherSuite SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- // "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
- // "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA);
- // END android-removed
-
- static final CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DHE_DSS_EXPORT, "DSA", "DES40_CBC", "SHA",
- CODE_SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DHE_DSS_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
- "DSA", "DES_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_DSS,
- "DSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DHE_RSA_EXPORT, "RSA", "DES40_CBC", "SHA",
- CODE_SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
- "RSA", "DES_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DHE_RSA,
- "RSA", "3DES_EDE_CBC", "SHA", CODE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = new CipherSuite(
- "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", true,
- KEY_EXCHANGE_DH_anon_EXPORT, "DH", "RC4_40", "MD5",
- CODE_SSL_DH_anon_EXPORT_WITH_RC4_40_MD5);
-
- static final CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = new CipherSuite(
- "SSL_DH_anon_WITH_RC4_128_MD5", false, KEY_EXCHANGE_DH_anon,
- "DH", "RC4_128", "MD5", CODE_SSL_DH_anon_WITH_RC4_128_MD5);
-
- static final CipherSuite SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", true,
- KEY_EXCHANGE_DH_anon_EXPORT, "DH", "DES40_CBC", "SHA",
- CODE_SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_WITH_DES_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
- "DH", "DES_CBC", "SHA", CODE_SSL_DH_anon_WITH_DES_CBC_SHA);
-
- static final CipherSuite SSL_DH_anon_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_anon,
- "DH", "3DES_EDE_CBC", "SHA", CODE_SSL_DH_anon_WITH_3DES_EDE_CBC_SHA);
-
- static final CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_RSA,
- "RSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_DSS,
- "DSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_RSA,
- "RSA",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_DH_anon_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_DH_anon,
- "DH",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_DH_anon_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_RSA,
- "RSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_DSS,
- "DSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DHE_DSS_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DHE_RSA,
- "RSA",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_DH_anon_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_DH_anon,
- "DH",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_DH_anon_WITH_AES_256_CBC_SHA);
-
- static final CipherSuite TLS_ECDH_ECDSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_ECDSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_ECDSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_RSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDHE_RSA,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_NULL_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_NULL_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- null,
- "SHA",
- CODE_TLS_ECDH_anon_WITH_NULL_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_RC4_128_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_RC4_128_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "RC4_128",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_RC4_128_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "3DES_EDE_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_AES_128_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "AES_128_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
- static final CipherSuite TLS_ECDH_anon_WITH_AES_256_CBC_SHA
- = new CipherSuite("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
- false,
- KEY_EXCHANGE_ECDH_anon,
- "EC",
- "AES_256_CBC",
- "SHA",
- CODE_TLS_ECDH_anon_WITH_AES_256_CBC_SHA);
-
- // arrays for quick access to cipher suite by code
- private static final CipherSuite[] SUITES_BY_CODE_0x00 = {
- // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
- SSL_NULL_WITH_NULL_NULL, // { 0x00, 0x00 };
- SSL_RSA_WITH_NULL_MD5, // { 0x00, 0x01 };
- SSL_RSA_WITH_NULL_SHA, // { 0x00, 0x02 };
- SSL_RSA_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x03 };
- SSL_RSA_WITH_RC4_128_MD5, // { 0x00, 0x04 };
- SSL_RSA_WITH_RC4_128_SHA, // { 0x00, 0x05 };
- // BEGIN android-changed
- null, // SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, // { 0x00, 0x06 };
- null, // TLS_RSA_WITH_IDEA_CBC_SHA, // { 0x00, 0x07 };
- // END android-changed
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x08 };
- SSL_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x09 };
- SSL_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0a };
- // BEGIN android-changed
- null, // SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA // { 0x00, 0x0b };
- null, // SSL_DH_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x0c };
- null, // SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x0d };
- null, // SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x0e };
- null, // SSL_DH_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x0f };
- null, // SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x10 };
- // END android-changed
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x11 };
- SSL_DHE_DSS_WITH_DES_CBC_SHA, // { 0x00, 0x12 };
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x13 };
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x14 };
- SSL_DHE_RSA_WITH_DES_CBC_SHA, // { 0x00, 0x15 };
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x16 };
- SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, // { 0x00, 0x17 };
- SSL_DH_anon_WITH_RC4_128_MD5, // { 0x00, 0x18 };
- SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, // { 0x00, 0x19 };
- SSL_DH_anon_WITH_DES_CBC_SHA, // { 0x00, 0x1A };
- SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, // { 0x00, 0x1B };
- // BEGIN android-added
- null, // SSL_FORTEZZA_KEA_WITH_NULL_SHA // { 0x00, 0x1C };
- null, // SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA // { 0x00, 0x1D };
- null, // TLS_KRB5_WITH_DES_CBC_SHA // { 0x00, 0x1E };
- null, // TLS_KRB5_WITH_3DES_EDE_CBC_SHA // { 0x00, 0x1F };
- null, // TLS_KRB5_WITH_RC4_128_SHA // { 0x00, 0x20 };
- null, // TLS_KRB5_WITH_IDEA_CBC_SHA // { 0x00, 0x21 };
- null, // TLS_KRB5_WITH_DES_CBC_MD5 // { 0x00, 0x22 };
- null, // TLS_KRB5_WITH_3DES_EDE_CBC_MD5 // { 0x00, 0x23 };
- null, // TLS_KRB5_WITH_RC4_128_MD5 // { 0x00, 0x24 };
- null, // TLS_KRB5_WITH_IDEA_CBC_MD5 // { 0x00, 0x25 };
- null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA // { 0x00, 0x26 };
- null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA // { 0x00, 0x27 };
- null, // TLS_KRB5_EXPORT_WITH_RC4_40_SHA // { 0x00, 0x28 };
- null, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 // { 0x00, 0x29 };
- null, // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 // { 0x00, 0x2A };
- null, // TLS_KRB5_EXPORT_WITH_RC4_40_MD5 // { 0x00, 0x2B };
- null, // TLS_PSK_WITH_NULL_SHA // { 0x00, 0x2C };
- null, // TLS_DHE_PSK_WITH_NULL_SHA // { 0x00, 0x2D };
- null, // TLS_RSA_PSK_WITH_NULL_SHA // { 0x00, 0x2E };
- TLS_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x2F };
- null, // TLS_DH_DSS_WITH_AES_128_CBC_SHA // { 0x00, 0x30 };
- null, // TLS_DH_RSA_WITH_AES_128_CBC_SHA // { 0x00, 0x31 };
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA, // { 0x00, 0x32 };
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA, // { 0x00, 0x33 };
- TLS_DH_anon_WITH_AES_128_CBC_SHA, // { 0x00, 0x34 };
- TLS_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x35 };
- null, // TLS_DH_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x36 };
- null, // TLS_DH_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x37 };
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA, // { 0x00, 0x38 };
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA, // { 0x00, 0x39 };
- TLS_DH_anon_WITH_AES_256_CBC_SHA, // { 0x00, 0x3A };
- // END android-added
- };
- private static final CipherSuite[] SUITES_BY_CODE_0xc0 = {
- null, // { 0xc0, 0x00};
- TLS_ECDH_ECDSA_WITH_NULL_SHA, // { 0xc0, 0x01};
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA, // { 0xc0, 0x02};
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x03};
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x04};
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x05};
- TLS_ECDHE_ECDSA_WITH_NULL_SHA, // { 0xc0, 0x06};
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, // { 0xc0, 0x07};
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x08};
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x09};
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x0A};
- TLS_ECDH_RSA_WITH_NULL_SHA, // { 0xc0, 0x0B};
- TLS_ECDH_RSA_WITH_RC4_128_SHA, // { 0xc0, 0x0C};
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x0D};
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x0E};
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x0F};
- TLS_ECDHE_RSA_WITH_NULL_SHA, // { 0xc0, 0x10};
- TLS_ECDHE_RSA_WITH_RC4_128_SHA, // { 0xc0, 0x11};
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x12};
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x13};
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x14};
- TLS_ECDH_anon_WITH_NULL_SHA, // { 0xc0, 0x15};
- TLS_ECDH_anon_WITH_RC4_128_SHA, // { 0xc0, 0x16};
- TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x17};
- TLS_ECDH_anon_WITH_AES_128_CBC_SHA, // { 0xc0, 0x18};
- TLS_ECDH_anon_WITH_AES_256_CBC_SHA, // { 0xc0, 0x19};
- // TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1A};
- // TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1B};
- // TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x1C};
- // TLS_SRP_SHA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1D};
- // TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1E};
- // TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, // { 0xc0, 0x1F};
- // TLS_SRP_SHA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x20};
- // TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, // { 0xc0, 0x21};
- // TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, // { 0xc0, 0x22};
- // TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x23};
- // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x24};
- // TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x25};
- // TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x26};
- // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x27};
- // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x28};
- // TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x29};
- // TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x2A};
- // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2B};
- // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x2C};
- // TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2D};
- // TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x2E};
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x2F};
- // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x30};
- // TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, // { 0xc0, 0x31};
- // TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, // { 0xc0, 0x32};
- // TLS_ECDHE_PSK_WITH_RC4_128_SHA, // { 0xc0, 0x33};
- // TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, // { 0xc0, 0x34};
- // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, // { 0xc0, 0x35};
- // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, // { 0xc0, 0x36};
- // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, // { 0xc0, 0x37};
- // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, // { 0xc0, 0x38};
- // TLS_ECDHE_PSK_WITH_NULL_SHA, // { 0xc0, 0x39};
- // TLS_ECDHE_PSK_WITH_NULL_SHA256, // { 0xc0, 0x3A};
- // TLS_ECDHE_PSK_WITH_NULL_SHA384, // { 0xc0, 0x3B};
- };
-
- // hash for quick access to cipher suite by name
- private static final Hashtable<String, CipherSuite> SUITES_BY_NAME;
-
- /**
- * array of supported cipher suites.
- * Set of supported suites is defined at the moment provider's start
- */
- // TODO Dynamically supported suites: new providers may be dynamically
- // added/removed and the set of supported suites may be changed
- static final CipherSuite[] SUPPORTED_CIPHER_SUITES;
-
- /**
- * array of supported cipher suites names
- */
- static final String[] SUPPORTED_CIPHER_SUITE_NAMES;
-
- /**
- * default cipher suites
- */
- static final CipherSuite[] DEFAULT_CIPHER_SUITES;
-
- static {
- SUITES_BY_NAME = new Hashtable<String, CipherSuite>();
- int count_0x00 = registerCipherSuitesByCode(SUITES_BY_CODE_0x00);
- int count_0xc0 = registerCipherSuitesByCode(SUITES_BY_CODE_0xc0);
- int count = count_0x00 + count_0xc0;
- SUPPORTED_CIPHER_SUITES = new CipherSuite[count];
- SUPPORTED_CIPHER_SUITE_NAMES = new String[count];
- registerSupportedCipherSuites(0, SUITES_BY_CODE_0x00);
- registerSupportedCipherSuites(count_0x00, SUITES_BY_CODE_0xc0);
-
- CipherSuite[] defaultCipherSuites = {
- SSL_RSA_WITH_RC4_128_MD5,
- SSL_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- SSL_RSA_WITH_DES_CBC_SHA,
- SSL_DHE_RSA_WITH_DES_CBC_SHA,
- SSL_DHE_DSS_WITH_DES_CBC_SHA,
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
- SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- };
- count = 0;
- for (int i = 0; i < defaultCipherSuites.length; i++) {
- if (defaultCipherSuites[i].supported) {
- count++;
- }
- }
- DEFAULT_CIPHER_SUITES = new CipherSuite[count];
- count = 0;
- for (int i = 0; i < defaultCipherSuites.length; i++) {
- if (defaultCipherSuites[i].supported) {
- DEFAULT_CIPHER_SUITES[count++] = defaultCipherSuites[i];
- }
- }
- }
- private static int registerCipherSuitesByCode(CipherSuite[] cipherSuites) {
- int count = 0;
- for (int i = 0; i < cipherSuites.length; i++) {
- if (cipherSuites[i] == SSL_NULL_WITH_NULL_NULL) {
- continue;
- }
- if (cipherSuites[i] == null) {
- continue;
- }
- SUITES_BY_NAME.put(cipherSuites[i].getName(), cipherSuites[i]);
- if (cipherSuites[i].supported) {
- count++;
- }
- }
- return count;
- }
- private static void registerSupportedCipherSuites(int offset, CipherSuite[] cipherSuites) {
- int count = offset;
- for (int i = 0; i < cipherSuites.length; i++) {
- if (cipherSuites[i] == SSL_NULL_WITH_NULL_NULL) {
- continue;
- }
- if (cipherSuites[i] == null) {
- continue;
- }
- if (cipherSuites[i].supported) {
- SUPPORTED_CIPHER_SUITES[count] = cipherSuites[i];
- SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName();
- count++;
- }
- }
- }
-
- /**
- * Returns CipherSuite by name
- */
- public static CipherSuite getByName(String name) {
- return SUITES_BY_NAME.get(name);
- }
-
- /**
- * Returns CipherSuite based on TLS CipherSuite code
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., A.5. The CipherSuite</a>
- */
- public static CipherSuite getByCode(byte b1, byte b2) {
- int i1 = b1 & 0xff;
- int i2 = b2 & 0xff;
- CipherSuite cs = getCipherSuiteByCode(0, i1, i2);
- if (cs != null) {
- return cs;
- }
- return new CipherSuite("UNKNOWN_" + i1 + "_" + i2, false, 0, null,
- null, null, new byte[] { b1, b2 });
- }
-
- /**
- * Returns CipherSuite based on V2CipherSpec code
- * as described in TLS 1.0 spec., E. Backward Compatibility With SSL
- */
- public static CipherSuite getByCode(byte b1, byte b2, byte b3) {
- int i1 = b1 & 0xff;
- int i2 = b2 & 0xff;
- int i3 = b3 & 0xff;
- CipherSuite cs = getCipherSuiteByCode(i1, i2, i3);
- if (cs != null) {
- return cs;
- }
- return new CipherSuite("UNKNOWN_" + i1 + "_" + i2 + "_" + i3, false, 0,
- null, null, null, new byte[] { b1, b2, b3 });
- }
-
- private static CipherSuite getCipherSuiteByCode(int i1, int i2, int i3) {
- CipherSuite[] cipherSuites;
- if (i1 == 0x00 && i2 == 0x00) {
- cipherSuites = SUITES_BY_CODE_0x00;
- } else if (i1 == 0x00 && i2 == 0xc0) {
- cipherSuites = SUITES_BY_CODE_0xc0;
- } else {
- return null;
- }
- if (i3 >= cipherSuites.length) {
- return null;
- }
- return cipherSuites[i3];
- }
-
- /**
- * Creates CipherSuite
- */
- private CipherSuite(String name, boolean isExportable, int keyExchange,
- String authType, String cipherName, String hash, byte[] code) {
- this.name = name;
- this.keyExchange = keyExchange;
- this.authType = authType;
- this.isExportable = isExportable;
- if (cipherName == null) {
- this.cipherName = null;
- keyMaterial = 0;
- expandedKeyMaterial = 0;
- effectiveKeyBytes = 0;
- ivSize = 0;
- blockSize = 0;
- // BEGIN android-removed
- // } else if ("IDEA_CBC".equals(cipherName)) {
- // this.cipherName = "IDEA/CBC/NoPadding";
- // keyMaterial = 16;
- // expandedKeyMaterial = 16;
- // effectiveKeyBytes = 16;
- // ivSize = 8;
- // blockSize = 8;
- // } else if ("RC2_CBC_40".equals(cipherName)) {
- // this.cipherName = "RC2/CBC/NoPadding";
- // keyMaterial = 5;
- // expandedKeyMaterial = 16;
- // effectiveKeyBytes = 5;
- // ivSize = 8;
- // blockSize = 8;
- // END android-removed
- } else if ("RC4_40".equals(cipherName)) {
- this.cipherName = "RC4";
- keyMaterial = 5;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 5;
- ivSize = 0;
- blockSize = 0;
- } else if ("RC4_128".equals(cipherName)) {
- this.cipherName = "RC4";
- keyMaterial = 16;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 16;
- ivSize = 0;
- blockSize = 0;
- } else if ("DES40_CBC".equals(cipherName)) {
- this.cipherName = "DES/CBC/NoPadding";
- keyMaterial = 5;
- expandedKeyMaterial = 8;
- effectiveKeyBytes = 5;
- ivSize = 8;
- blockSize = 8;
- } else if ("DES_CBC".equals(cipherName)) {
- this.cipherName = "DES/CBC/NoPadding";
- keyMaterial = 8;
- expandedKeyMaterial = 8;
- effectiveKeyBytes = 7;
- ivSize = 8;
- blockSize = 8;
- } else if ("3DES_EDE_CBC".equals(cipherName)) {
- this.cipherName = "DESede/CBC/NoPadding";
- keyMaterial = 24;
- expandedKeyMaterial = 24;
- effectiveKeyBytes = 24;
- ivSize = 8;
- blockSize = 8;
- } else if ("AES_128_CBC".equals(cipherName)) {
- this.cipherName = "AES/CBC/NoPadding";
- keyMaterial = 16;
- expandedKeyMaterial = 16;
- effectiveKeyBytes = 16;
- ivSize = 16;
- blockSize = 16;
- } else if ("AES_256_CBC".equals(cipherName)) {
- this.cipherName = "AES/CBC/NoPadding";
- keyMaterial = 32;
- expandedKeyMaterial = 32;
- effectiveKeyBytes = 32;
- ivSize = 16;
- blockSize = 16;
- } else {
- this.cipherName = cipherName;
- keyMaterial = 0;
- expandedKeyMaterial = 0;
- effectiveKeyBytes = 0;
- ivSize = 0;
- blockSize = 0;
- }
-
- if ("MD5".equals(hash)) {
- this.hmacName = "HmacMD5";
- this.hashName = "MD5";
- hashSize = 16;
- } else if ("SHA".equals(hash)) {
- this.hmacName = "HmacSHA1";
- this.hashName = "SHA-1";
- hashSize = 20;
- } else {
- this.hmacName = null;
- this.hashName = null;
- hashSize = 0;
- }
-
- cipherSuiteCode = code;
-
- if (this.cipherName != null) {
- try {
- Cipher.getInstance(this.cipherName);
- } catch (GeneralSecurityException e) {
- supported = false;
- }
- }
-
- // We define the Elliptic Curve cipher suites for use with
- // code shared by OpenSSL, but they are not supported by
- // SSLEngine or SSLSocket's built with SSLEngine.
- if (this.name.startsWith("TLS_EC")) {
- supported = false;
- }
- }
-
- /**
- * Returns true if cipher suite is anonymous
- */
- public boolean isAnonymous() {
- if (keyExchange == KEY_EXCHANGE_DH_anon
- || keyExchange == KEY_EXCHANGE_DH_anon_EXPORT
- || keyExchange == KEY_EXCHANGE_ECDH_anon) {
- return true;
- }
- return false;
- }
-
- /**
- * Returns array of supported CipherSuites
- */
- public static CipherSuite[] getSupported() {
- return SUPPORTED_CIPHER_SUITES;
- }
-
- /**
- * Returns array of supported cipher suites names
- */
- public static String[] getSupportedCipherSuiteNames() {
- return SUPPORTED_CIPHER_SUITE_NAMES.clone();
- }
-
- /**
- * Returns cipher suite name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns cipher suite code as byte array
- */
- public byte[] toBytes() {
- return cipherSuiteCode;
- }
-
- /**
- * Returns cipher suite description
- */
- @Override
- public String toString() {
- return name + ": " + cipherSuiteCode[0] + " " + cipherSuiteCode[1];
- }
-
- /**
- * Returns cipher algorithm name
- */
- public String getBulkEncryptionAlgorithm() {
- return cipherName;
- }
-
- /**
- * Returns cipher block size
- */
- public int getBlockSize() {
- return blockSize;
- }
-
- /**
- * Returns MAC algorithm name
- */
- public String getHmacName() {
- return hmacName;
- }
-
- /**
- * Returns hash algorithm name
- */
- public String getHashName() {
- return hashName;
- }
-
- /**
- * Returns hash size
- */
- public int getMACLength() {
- return hashSize;
- }
-
- /**
- * Indicates whether this cipher suite is exportable
- */
- public boolean isExportable() {
- return isExportable;
- }
-
- static final String KEY_TYPE_RSA = "RSA";
- static final String KEY_TYPE_DSA = "DSA";
- static final String KEY_TYPE_DH_RSA = "DH_RSA";
- static final String KEY_TYPE_DH_DSA = "DH_DSA";
- static final String KEY_TYPE_EC = "EC";
- static final String KEY_TYPE_EC_EC = "EC_EC";
- static final String KEY_TYPE_EC_RSA = "EC_RSA";
-
- /**
- * Returns key type constant suitable for calling
- * X509KeyManager.chooseServerAlias or
- * X509ExtendedKeyManager.chooseEngineServerAlias.
- */
- public String getServerKeyType() {
- switch (keyExchange) {
- case KEY_EXCHANGE_DHE_RSA:
- case KEY_EXCHANGE_DHE_RSA_EXPORT:
- case KEY_EXCHANGE_ECDHE_RSA:
- case KEY_EXCHANGE_RSA:
- case KEY_EXCHANGE_RSA_EXPORT:
- return KEY_TYPE_RSA;
- case KEY_EXCHANGE_DHE_DSS:
- case KEY_EXCHANGE_DHE_DSS_EXPORT:
- return KEY_TYPE_DSA;
- case KEY_EXCHANGE_ECDH_ECDSA:
- case KEY_EXCHANGE_ECDHE_ECDSA:
- return KEY_TYPE_EC_EC;
- case KEY_EXCHANGE_ECDH_RSA:
- return KEY_TYPE_EC_RSA;
- case KEY_EXCHANGE_DH_anon:
- case KEY_EXCHANGE_DH_anon_EXPORT:
- case KEY_EXCHANGE_ECDH_anon:
- return null;
- default:
- throw new IllegalStateException("Unknown key type for key exchange " + keyExchange);
- }
- }
-
- /**
- * Client certificate types as defined in
- * TLS 1.0 spec., 7.4.4. Certificate request.
- * EC constants from RFC 4492.
- * Names match openssl constants.
- */
- static final byte TLS_CT_RSA_SIGN = 1;
- static final byte TLS_CT_DSS_SIGN = 2;
- static final byte TLS_CT_RSA_FIXED_DH = 3;
- static final byte TLS_CT_DSS_FIXED_DH = 4;
- static final byte TLS_CT_ECDSA_SIGN = 64;
- static final byte TLS_CT_RSA_FIXED_ECDH = 65;
- static final byte TLS_CT_ECDSA_FIXED_ECDH = 66;
-
- /**
- * Similar to getServerKeyType, but returns value given TLS
- * ClientCertificateType byte values from a CertificateRequest
- * message for use with X509KeyManager.chooseClientAlias or
- * X509ExtendedKeyManager.chooseEngineClientAlias.
- */
- public static String getClientKeyType(byte keyType) {
- // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml
- switch (keyType) {
- case TLS_CT_RSA_SIGN:
- return KEY_TYPE_RSA; // RFC rsa_sign
- case TLS_CT_DSS_SIGN:
- return KEY_TYPE_DSA; // RFC dss_sign
- case TLS_CT_RSA_FIXED_DH:
- return KEY_TYPE_DH_RSA; // RFC rsa_fixed_dh
- case TLS_CT_DSS_FIXED_DH:
- return KEY_TYPE_DH_DSA; // RFC dss_fixed_dh
- case TLS_CT_ECDSA_SIGN:
- return KEY_TYPE_EC; // RFC ecdsa_sign
- case TLS_CT_RSA_FIXED_ECDH:
- return KEY_TYPE_EC_RSA; // RFC rsa_fixed_ecdh
- case TLS_CT_ECDSA_FIXED_ECDH:
- return KEY_TYPE_EC_EC; // RFC ecdsa_fixed_ecdh
- default:
- return null;
- }
- }
-
- private static final String AUTH_TYPE_RSA = "RSA";
- private static final String AUTH_TYPE_RSA_EXPORT = "RSA_EXPORT";
- private static final String AUTH_TYPE_DHE_DSS = "DHE_DSS";
- private static final String AUTH_TYPE_DHE_RSA = "DHE_RSA";
- private static final String AUTH_TYPE_DH_DSS = "DH_DSS";
- private static final String AUTH_TYPE_DH_RSA = "DH_RSA";
- private static final String AUTH_TYPE_ECDH_ECDSA = "ECDH_ECDSA";
- private static final String AUTH_TYPE_ECDH_RSA = "ECDH_RSA";
- private static final String AUTH_TYPE_ECDHE_ECDSA = "ECDHE_ECDSA";
- private static final String AUTH_TYPE_ECDHE_RSA = "ECDHE_RSA";
-
- /**
- * Returns auth type constant suitable for calling X509TrustManager.checkServerTrusted.
- */
- public String getAuthType(boolean emphemeral) {
- switch (keyExchange) {
- case KEY_EXCHANGE_RSA:
- return AUTH_TYPE_RSA;
- case KEY_EXCHANGE_RSA_EXPORT:
- return emphemeral ? AUTH_TYPE_RSA_EXPORT : AUTH_TYPE_RSA;
- case KEY_EXCHANGE_DHE_DSS:
- case KEY_EXCHANGE_DHE_DSS_EXPORT:
- return AUTH_TYPE_DHE_DSS;
- case KEY_EXCHANGE_DHE_RSA:
- case KEY_EXCHANGE_DHE_RSA_EXPORT:
- return AUTH_TYPE_DHE_RSA;
- case KEY_EXCHANGE_ECDH_ECDSA:
- return AUTH_TYPE_ECDH_ECDSA;
- case KEY_EXCHANGE_ECDHE_ECDSA:
- return AUTH_TYPE_ECDHE_ECDSA;
- case KEY_EXCHANGE_ECDH_RSA:
- return AUTH_TYPE_ECDH_RSA;
- case KEY_EXCHANGE_ECDHE_RSA:
- return AUTH_TYPE_ECDHE_RSA;
- case KEY_EXCHANGE_DH_anon:
- case KEY_EXCHANGE_DH_anon_EXPORT:
- case KEY_EXCHANGE_ECDH_anon:
- return null;
- default:
- throw new IllegalStateException("Unknown auth type for key exchange " + keyExchange);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java b/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java
deleted file mode 100644
index 8706ec0..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientHandshakeImpl.java
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHKey;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Client side handshake protocol implementation.
- * Handshake protocol operates on top of the Record Protocol.
- * It is responsible for session negotiating.
- *
- * The implementation processes inbound server handshake messages,
- * creates and sends respond messages. Outbound messages are supplied
- * to Record Protocol. Detected errors are reported to the Alert protocol.
- *
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7. The
- * TLS Handshake Protocol</a>
- *
- */
-public class ClientHandshakeImpl extends HandshakeProtocol {
-
- /**
- * Creates Client Handshake Implementation
- *
- * @param owner
- */
- ClientHandshakeImpl(Object owner) {
- super(owner);
- }
-
- /**
- * Starts handshake
- *
- */
- @Override
- public void start() {
- if (session == null) { // initial handshake
- session = findSessionToResume();
- } else { // start session renegotiation
- if (clientHello != null && this.status != FINISHED) {
- // current negotiation has not completed
- return; // ignore
- }
- if (!session.isValid()) {
- session = null;
- }
- }
- if (session != null) {
- isResuming = true;
- } else if (parameters.getEnableSessionCreation()){
- isResuming = false;
- session = new SSLSessionImpl(parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
- }
- session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
- recordProtocol.setVersion(session.protocol.version);
- } else {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created ");
- }
- startSession();
- }
-
- /**
- * Starts renegotiation on a new session
- *
- */
- private void renegotiateNewSession() {
- if (parameters.getEnableSessionCreation()){
- isResuming = false;
- session = new SSLSessionImpl(parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getPeerHostName(), socketOwner.getPeerPort());
- }
- session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
- recordProtocol.setVersion(session.protocol.version);
- startSession();
- } else {
- status = NOT_HANDSHAKING;
- sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
- }
- }
-
- /*
- * Starts/resumes session
- */
- private void startSession() {
- CipherSuite[] cipher_suites;
- if (isResuming) {
- cipher_suites = new CipherSuite[] { session.cipherSuite };
- } else {
- cipher_suites = parameters.getEnabledCipherSuitesMember();
- }
- clientHello = new ClientHello(parameters.getSecureRandom(),
- session.protocol.version, session.id, cipher_suites);
- session.clientRandom = clientHello.random;
- send(clientHello);
- status = NEED_UNWRAP;
- }
-
- /**
- * Processes inbound handshake messages
- * @param bytes
- */
- @Override
- public void unwrap(byte[] bytes) {
- if (this.delegatedTaskErr != null) {
- Exception e = this.delegatedTaskErr;
- this.delegatedTaskErr = null;
- this.fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Error in delegated task", e);
- }
- int handshakeType;
- io_stream.append(bytes);
- while (io_stream.available() > 0) {
- io_stream.mark();
- int length;
- try {
- handshakeType = io_stream.read();
- length = io_stream.readUint24();
- if (io_stream.available() < length) {
- io_stream.reset();
- return;
- }
- switch (handshakeType) {
- case 0: // HELLO_REQUEST
- // we don't need to take this message into account
- // during FINISH message verification, so remove it
- io_stream.removeFromMarkedPosition();
- if (clientHello != null
- && (clientFinished == null || serverFinished == null)) {
- //currently negotiating - ignore
- break;
- }
- // renegotiate
- if (session.isValid()) {
- session = (SSLSessionImpl) session.clone();
- isResuming = true;
- startSession();
- } else {
- // if SSLSession is invalidated (e.g. timeout limit is
- // exceeded) connection can't resume the session.
- renegotiateNewSession();
- }
- break;
- case 2: // SERVER_HELLO
- if (clientHello == null || serverHello != null) {
- unexpectedMessage();
- return;
- }
- serverHello = new ServerHello(io_stream, length);
-
- //check protocol version
- ProtocolVersion servProt = ProtocolVersion.getByVersion(serverHello.server_version);
- String[] enabled = parameters.getEnabledProtocols();
- find: {
- for (int i = 0; i < enabled.length; i++) {
- if (servProt.equals(ProtocolVersion.getByName(enabled[i]))) {
- break find;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello protocol version");
- }
-
- // check compression method
- if (serverHello.compression_method != 0) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello compression method");
- }
-
- //check cipher_suite
- CipherSuite[] enabledSuites = parameters.getEnabledCipherSuitesMember();
- find: {
- for (int i = 0; i < enabledSuites.length; i++) {
- if (serverHello.cipher_suite.equals(enabledSuites[i])) {
- break find;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello cipher suite");
- }
-
- if (isResuming) {
- if (serverHello.session_id.length == 0) {
- // server is not willing to establish the new connection
- // using specified session
- isResuming = false;
- } else if (!Arrays.equals(serverHello.session_id, clientHello.session_id)) {
- isResuming = false;
- } else if (!session.protocol.equals(servProt)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello protocol version");
- } else if (!session.cipherSuite.equals(serverHello.cipher_suite)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Bad server hello cipher suite");
- }
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("server finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
- }
- }
- session.protocol = servProt;
- recordProtocol.setVersion(session.protocol.version);
- session.cipherSuite = serverHello.cipher_suite;
- session.id = serverHello.session_id.clone();
- session.serverRandom = serverHello.random;
- break;
- case 11: // CERTIFICATE
- if (serverHello == null || serverKeyExchange != null
- || serverCert != null || isResuming) {
- unexpectedMessage();
- return;
- }
- serverCert = new CertificateMessage(io_stream, length);
- break;
- case 12: // SERVER_KEY_EXCHANGE
- if (serverHello == null || serverKeyExchange != null
- || isResuming) {
- unexpectedMessage();
- return;
- }
- serverKeyExchange = new ServerKeyExchange(io_stream,
- length, session.cipherSuite.keyExchange);
- break;
- case 13: // CERTIFICATE_REQUEST
- if (serverCert == null || certificateRequest != null
- || session.cipherSuite.isAnonymous() || isResuming) {
- unexpectedMessage();
- return;
- }
- certificateRequest = new CertificateRequest(io_stream, length);
- break;
- case 14: // SERVER_HELLO_DONE
- if (serverHello == null || serverHelloDone != null || isResuming) {
- unexpectedMessage();
- return;
- }
- serverHelloDone = new ServerHelloDone(io_stream, length);
- if (this.nonBlocking) {
- delegatedTasks.add(new DelegatedTask(new Runnable() {
- public void run() {
- processServerHelloDone();
- }
- }, this));
- return;
- }
- processServerHelloDone();
- break;
- case 20: // FINISHED
- if (!changeCipherSpecReceived) {
- unexpectedMessage();
- return;
- }
- serverFinished = new Finished(io_stream, length);
- verifyFinished(serverFinished.getData());
- session.lastAccessedTime = System.currentTimeMillis();
- session.context = parameters.getClientSessionContext();
- parameters.getClientSessionContext().putSession(session);
- if (isResuming) {
- sendChangeCipherSpec();
- } else {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- }
- // XXX there is no cleanup work
- break;
- default:
- unexpectedMessage();
- return;
- }
- } catch (IOException e) {
- // io stream dosn't contain complete handshake message
- io_stream.reset();
- return;
- }
- }
-
- }
-
- /**
- * Processes SSLv2 Hello message.
- * SSLv2 client hello message message is an unexpected message
- * for client side of handshake protocol.
- * See TLS 1.0 spec., E.1. Version 2 client hello
- * @param bytes
- */
- @Override
- public void unwrapSSLv2(byte[] bytes) {
- unexpectedMessage();
- }
-
- /**
- * Creates and sends Finished message
- */
- @Override
- protected void makeFinished() {
- byte[] verify_data;
- if (serverHello.server_version[1] == 1) {
- verify_data = new byte[12];
- computerVerifyDataTLS("client finished", verify_data);
- } else {
- verify_data = new byte[36];
- computerVerifyDataSSLv3(SSLv3Constants.client, verify_data);
- }
- clientFinished = new Finished(verify_data);
- send(clientFinished);
- if (isResuming) {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- } else {
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("server finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
- }
- status = NEED_UNWRAP;
- }
- }
-
- /**
- * Processes ServerHelloDone: makes verification of the server messages; sends
- * client messages, computers masterSecret, sends ChangeCipherSpec
- */
- void processServerHelloDone() {
- PrivateKey clientKey = null;
-
- if (serverCert != null) {
- if (session.cipherSuite.isAnonymous()) {
- unexpectedMessage();
- return;
- }
- verifyServerCert();
- } else {
- if (!session.cipherSuite.isAnonymous()) {
- unexpectedMessage();
- return;
- }
- }
-
- // Client certificate
- if (certificateRequest != null) {
- X509Certificate[] certs = null;
- // obtain certificates from key manager
- String alias = null;
- String[] certTypes = certificateRequest.getTypesAsString();
- X500Principal[] issuers = certificateRequest.certificate_authorities;
- X509KeyManager km = parameters.getKeyManager();
- if (km instanceof X509ExtendedKeyManager) {
- X509ExtendedKeyManager ekm = (X509ExtendedKeyManager)km;
- if (this.socketOwner != null) {
- alias = ekm.chooseClientAlias(certTypes, issuers, this.socketOwner);
- } else {
- alias = ekm.chooseEngineClientAlias(certTypes, issuers, this.engineOwner);
- }
- if (alias != null) {
- certs = ekm.getCertificateChain(alias);
- }
- } else {
- alias = km.chooseClientAlias(certTypes, issuers, this.socketOwner);
- if (alias != null) {
- certs = km.getCertificateChain(alias);
- }
- }
-
- session.localCertificates = certs;
- clientCert = new CertificateMessage(certs);
- clientKey = km.getPrivateKey(alias);
- send(clientCert);
- }
- // Client key exchange
- if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- // RSA encrypted premaster secret message
- Cipher c;
- try {
- c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- if (serverKeyExchange != null) {
- if (!session.cipherSuite.isAnonymous()) {
- DigitalSignature ds = new DigitalSignature(serverCert.getAuthType());
- ds.init(serverCert.certs[0]);
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
- if (!serverKeyExchange.verifySignature(ds)) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Cannot verify RSA params");
- return;
- }
- }
- c.init(Cipher.WRAP_MODE, serverKeyExchange
- .getRSAPublicKey());
- } else {
- c.init(Cipher.WRAP_MODE, serverCert.certs[0]);
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- preMasterSecret = new byte[48];
- parameters.getSecureRandom().nextBytes(preMasterSecret);
- System.arraycopy(clientHello.client_version, 0, preMasterSecret, 0, 2);
- try {
- clientKeyExchange = new ClientKeyExchange(c
- .wrap(new SecretKeySpec(preMasterSecret, "preMasterSecret")),
- serverHello.server_version[1] == 1);
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- } else if (session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon
- || session.cipherSuite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) {
- /*
- * All other key exchanges should have had a DH key communicated via
- * ServerKeyExchange beforehand.
- */
- if (serverKeyExchange == null) {
- fatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, "Expected ServerKeyExchange");
- return;
- }
- if (session.cipherSuite.isAnonymous() != serverKeyExchange.isAnonymous()) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Wrong type in ServerKeyExchange");
- return;
- }
- try {
- if (!session.cipherSuite.isAnonymous()) {
- DigitalSignature ds = new DigitalSignature(serverCert.getAuthType());
- ds.init(serverCert.certs[0]);
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
- if (!serverKeyExchange.verifySignature(ds)) {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Cannot verify DH params");
- return;
- }
- }
- KeyFactory kf = KeyFactory.getInstance("DH");
- KeyAgreement agreement = KeyAgreement.getInstance("DH");
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
- PublicKey serverDhPublic = kf.generatePublic(new DHPublicKeySpec(
- serverKeyExchange.par3, serverKeyExchange.par1,
- serverKeyExchange.par2));
- DHParameterSpec spec = new DHParameterSpec(serverKeyExchange.par1,
- serverKeyExchange.par2);
- kpg.initialize(spec);
- KeyPair kp = kpg.generateKeyPair();
- DHPublicKey pubDhKey = (DHPublicKey) kp.getPublic();
- clientKeyExchange = new ClientKeyExchange(pubDhKey.getY());
- PrivateKey privDhKey = kp.getPrivate();
- agreement.init(privDhKey);
- agreement.doPhase(serverDhPublic, true);
- preMasterSecret = agreement.generateSecret();
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Unexpected exception", e);
- return;
- }
- } else {
- fatalAlert(AlertProtocol.DECRYPT_ERROR, "Unsupported handshake type");
- return;
- }
-
- if (clientKeyExchange != null) {
- send(clientKeyExchange);
- }
-
- computerMasterSecret();
-
- // send certificate verify for all certificates except those containing
- // fixed DH parameters
- if (clientCert != null && clientCert.certs.length > 0 && !clientKeyExchange.isEmpty()) {
- // Certificate verify
- String authType = clientKey.getAlgorithm();
- DigitalSignature ds = new DigitalSignature(authType);
- ds.init(clientKey);
-
- if ("RSA".equals(authType)) {
- ds.setMD5(io_stream.getDigestMD5());
- ds.setSHA(io_stream.getDigestSHA());
- } else if ("DSA".equals(authType)) {
- ds.setSHA(io_stream.getDigestSHA());
- // The Signature should be empty in case of anonymous signature algorithm:
- // } else if ("DH".equals(authType)) {
- }
- certificateVerify = new CertificateVerify(ds.sign());
- send(certificateVerify);
- }
-
- sendChangeCipherSpec();
- }
-
- /*
- * Verifies certificate path
- */
- private void verifyServerCert() {
- String authType = session.cipherSuite.getAuthType(serverKeyExchange != null);
- if (authType == null) {
- return;
- }
- String hostname = null;
- if (engineOwner != null) {
- hostname = engineOwner.getPeerHost();
- } else {
- // we don't want to do an inet address lookup here in case we're talking to a proxy
- hostname = socketOwner.getWrappedHostName();
- }
- try {
- X509TrustManager x509tm = parameters.getTrustManager();
- if (x509tm instanceof TrustManagerImpl) {
- TrustManagerImpl tm = (TrustManagerImpl) x509tm;
- tm.checkServerTrusted(serverCert.certs, authType, hostname);
- } else {
- x509tm.checkServerTrusted(serverCert.certs, authType);
- }
- } catch (CertificateException e) {
- fatalAlert(AlertProtocol.BAD_CERTIFICATE, "Not trusted server certificate", e);
- return;
- }
- session.peerCertificates = serverCert.certs;
- }
-
- /**
- * Processes ChangeCipherSpec message
- */
- @Override
- public void receiveChangeCipherSpec() {
- if (isResuming) {
- if (serverHello == null) {
- unexpectedMessage();
- }
- } else if (clientFinished == null) {
- unexpectedMessage();
- }
- changeCipherSpecReceived = true;
- }
-
- // Find session to resume in client session context
- private SSLSessionImpl findSessionToResume() {
- String host = null;
- int port = -1;
- if (engineOwner != null) {
- host = engineOwner.getPeerHost();
- port = engineOwner.getPeerPort();
- } else {
- host = socketOwner.getPeerHostName();
- port = socketOwner.getPeerPort();
- }
- if (host == null || port == -1) {
- return null; // starts new session
- }
-
- ClientSessionContext context = parameters.getClientSessionContext();
- SSLSessionImpl session
- = (SSLSessionImpl) context.getSession(host, port);
- if (session != null) {
- session = (SSLSessionImpl) session.clone();
- }
- return session;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientHello.java b/crypto/src/main/java/org/conscrypt/ClientHello.java
deleted file mode 100644
index 2bf9f5f..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientHello.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import libcore.io.Streams;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Represents Client Hello message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.2.
- * Client hello</a>
- *
- */
-public class ClientHello extends Message {
-
- /**
- * Client version
- */
- final byte[] client_version;
-
- /**
- * Random bytes
- */
- final byte[] random = new byte[32];
-
- /**
- * Session id
- */
- final byte[] session_id;
-
- /**
- * Cipher suites supported by the client
- */
- final CipherSuite[] cipher_suites;
-
- /**
- * Compression methods supported by the client
- */
- final byte[] compression_methods;
-
- /**
- * Creates outbound message
- * @param sr
- * @param version
- * @param ses_id
- * @param cipher_suite
- */
- public ClientHello(SecureRandom sr, byte[] version, byte[] ses_id,
- CipherSuite[] cipher_suite) {
- client_version = version;
- long gmt_unix_time = System.currentTimeMillis()/1000;
- sr.nextBytes(random);
- random[0] = (byte) (gmt_unix_time & 0xFF000000 >>> 24);
- random[1] = (byte) (gmt_unix_time & 0xFF0000 >>> 16);
- random[2] = (byte) (gmt_unix_time & 0xFF00 >>> 8);
- random[3] = (byte) (gmt_unix_time & 0xFF);
- session_id = ses_id;
- this.cipher_suites = cipher_suite;
- compression_methods = new byte[] { 0 }; // CompressionMethod.null
- length = 38 + session_id.length + (this.cipher_suites.length << 1)
- + compression_methods.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ClientHello(HandshakeIODataStream in, int length) throws IOException {
- client_version = new byte[2];
- client_version[0] = (byte) in.readUint8();
- client_version[1] = (byte) in.readUint8();
- Streams.readFully(in, random);
- int size = in.read();
- session_id = new byte[size];
- in.read(session_id, 0, size);
- int l = in.readUint16();
- if ((l & 0x01) == 0x01) { // cipher suites length must be an even number
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect ClientHello");
- }
- size = l >> 1;
- cipher_suites = new CipherSuite[size];
- for (int i = 0; i < size; i++) {
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- cipher_suites[i] = CipherSuite.getByCode(b0, b1);
- }
- size = in.read();
- compression_methods = new byte[size];
- in.read(compression_methods, 0, size);
- this.length = 38 + session_id.length + (cipher_suites.length << 1)
- + compression_methods.length;
- if (this.length > length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ClientHello");
- }
- // for forward compatibility, extra data is permitted;
- // must be ignored
- if (this.length < length) {
- in.skip(length - this.length);
- this.length = length;
- }
- }
- /**
- * Parse V2ClientHello
- * @param in
- * @throws IOException
- */
- public ClientHello(HandshakeIODataStream in) throws IOException {
- if (in.readUint8() != 1) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello");
- }
- client_version = new byte[2];
- client_version[0] = (byte) in.readUint8();
- client_version[1] = (byte) in.readUint8();
- int cipher_spec_length = in.readUint16();
- if (in.readUint16() != 0) { // session_id_length
- // as client already knows the protocol known to a server it should
- // initiate the connection in that native protocol
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect V2ClientHello, cannot be used for resuming");
- }
- int challenge_length = in.readUint16();
- if (challenge_length < 16) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello, short challenge data");
- }
- session_id = EmptyArray.BYTE;
- cipher_suites = new CipherSuite[cipher_spec_length/3];
- for (int i = 0; i < cipher_suites.length; i++) {
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- byte b2 = (byte) in.read();
- cipher_suites[i] = CipherSuite.getByCode(b0, b1, b2);
- }
- compression_methods = new byte[] { 0 }; // CompressionMethod.null
-
- if (challenge_length < 32) {
- Arrays.fill(random, 0, 32 - challenge_length, (byte)0);
- System.arraycopy(in.read(challenge_length), 0, random, 32 - challenge_length, challenge_length);
- } else if (challenge_length == 32) {
- System.arraycopy(in.read(32), 0, random, 0, 32);
- } else {
- System.arraycopy(in.read(challenge_length), challenge_length - 32, random, 0, 32);
- }
- if (in.available() > 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect V2ClientHello, extra data");
- }
- this.length = 38 + session_id.length + (cipher_suites.length << 1)
- + compression_methods.length;
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(client_version);
- out.write(random);
- out.writeUint8(session_id.length);
- out.write(session_id);
- int size = cipher_suites.length << 1;
- out.writeUint16(size);
- for (int i = 0; i < cipher_suites.length; i++) {
- out.write(cipher_suites[i].toBytes());
- }
- out.writeUint8(compression_methods.length);
- for (int i = 0; i < compression_methods.length; i++) {
- out.write(compression_methods[i]);
- }
- }
-
- /**
- * Returns client random
- * @return client random
- */
- public byte[] getRandom() {
- return random;
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CLIENT_HELLO;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java b/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java
deleted file mode 100644
index 5cad36b..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientKeyExchange.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import libcore.io.Streams;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Represents client key exchange message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.7.
- * Client key exchange message</a>
- *
- */
-public class ClientKeyExchange extends Message {
-
- /**
- * Exchange keys
- */
- final byte[] exchange_keys;
-
- /**
- * Equals true if TLS1.0 protocol is used
- */
- boolean isTLS;
-
- /**
- * Equals true if key exchange algorithm is RSA
- */
- final boolean isRSA;
-
- /**
- * Creates outbound message
- * @param encrypted_pre_master_secret
- * @param isTLS
- */
- public ClientKeyExchange(byte[] encrypted_pre_master_secret, boolean isTLS) {
- this.exchange_keys = encrypted_pre_master_secret;
- length = this.exchange_keys.length;
- if (isTLS) {
- length += 2;
- }
- this.isTLS = isTLS;
- isRSA = true;
- }
-
- /**
- * Creates outbound message
- * @param dh_Yc
- */
- public ClientKeyExchange(BigInteger dh_Yc) {
- byte[] bb = dh_Yc.toByteArray();
- if (bb[0] == 0) {
- exchange_keys = new byte[bb.length-1];
- System.arraycopy(bb, 1, exchange_keys, 0, exchange_keys.length);
- } else {
- exchange_keys = bb;
- }
- length = exchange_keys.length +2;
- isRSA = false;
- }
-
- /**
- * Creates empty message
- *
- */
- public ClientKeyExchange() {
- exchange_keys = EmptyArray.BYTE;
- length = 0;
- isRSA = false;
- }
-
- /**
- * Creates inbound message
- * @param length
- * @param isTLS
- * @param isRSA
- * @throws IOException
- */
- public ClientKeyExchange(HandshakeIODataStream in, int length, boolean isTLS, boolean isRSA)
- throws IOException {
- this.isTLS = isTLS;
- this.isRSA = isRSA;
- if (length == 0) {
- this.length = 0;
- exchange_keys = EmptyArray.BYTE;
- } else {
- int size;
- if (isRSA && !isTLS) {// SSL3.0 RSA
- size = length;
- this.length = size;
- } else { // DH or TLSv1 RSA
- size = in.readUint16();
- this.length = 2 + size;
- }
- exchange_keys = new byte[size];
- Streams.readFully(in, exchange_keys);
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ClientKeyExchange");
- }
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- if (exchange_keys.length != 0) {
- if (!isRSA || isTLS) {// DH or TLSv1 RSA
- out.writeUint16(exchange_keys.length);
- }
- out.write(exchange_keys);
- }
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.CLIENT_KEY_EXCHANGE;
- }
-
- /**
- * Returns true if the message is empty (in case of implicit DH Yc)
- */
- public boolean isEmpty() {
- return (exchange_keys.length == 0);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ClientSessionContext.java b/crypto/src/main/java/org/conscrypt/ClientSessionContext.java
deleted file mode 100644
index 27a39cf..0000000
--- a/crypto/src/main/java/org/conscrypt/ClientSessionContext.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLSession;
-
-/**
- * Caches client sessions. Indexes by host and port. Users are typically
- * looking to reuse any session for a given host and port.
- */
-public class ClientSessionContext extends AbstractSessionContext {
-
- /**
- * Sessions indexed by host and port. Protect from concurrent
- * access by holding a lock on sessionsByHostAndPort.
- */
- final Map<HostAndPort, SSLSession> sessionsByHostAndPort
- = new HashMap<HostAndPort, SSLSession>();
-
- private SSLClientSessionCache persistentCache;
-
- public ClientSessionContext() {
- super(10, 0);
- }
-
- public int size() {
- return sessionsByHostAndPort.size();
- }
-
- public void setPersistentCache(SSLClientSessionCache persistentCache) {
- this.persistentCache = persistentCache;
- }
-
- protected void sessionRemoved(SSLSession session) {
- String host = session.getPeerHost();
- int port = session.getPeerPort();
- if (host == null) {
- return;
- }
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.remove(hostAndPortKey);
- }
- }
-
- /**
- * Finds a cached session for the given host name and port.
- *
- * @param host of server
- * @param port of server
- * @return cached session or null if none found
- */
- public SSLSession getSession(String host, int port) {
- if (host == null) {
- return null;
- }
- SSLSession session;
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- session = sessionsByHostAndPort.get(hostAndPortKey);
- }
- if (session != null && session.isValid()) {
- return session;
- }
-
- // Look in persistent cache.
- if (persistentCache != null) {
- byte[] data = persistentCache.getSessionData(host, port);
- if (data != null) {
- session = toSession(data, host, port);
- if (session != null && session.isValid()) {
- super.putSession(session);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.put(hostAndPortKey, session);
- }
- return session;
- }
- }
- }
-
- return null;
- }
-
- @Override
- public void putSession(SSLSession session) {
- super.putSession(session);
-
- String host = session.getPeerHost();
- int port = session.getPeerPort();
- if (host == null) {
- return;
- }
-
- HostAndPort hostAndPortKey = new HostAndPort(host, port);
- synchronized (sessionsByHostAndPort) {
- sessionsByHostAndPort.put(hostAndPortKey, session);
- }
-
- // TODO: This in a background thread.
- if (persistentCache != null) {
- byte[] data = toBytes(session);
- if (data != null) {
- persistentCache.putSessionData(session, data);
- }
- }
- }
-
- static class HostAndPort {
- final String host;
- final int port;
-
- HostAndPort(String host, int port) {
- this.host = host;
- this.port = port;
- }
-
- @Override public int hashCode() {
- return host.hashCode() * 31 + port;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof HostAndPort)) {
- return false;
- }
- HostAndPort lhs = (HostAndPort) o;
- return host.equals(lhs.host) && port == lhs.port;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionState.java b/crypto/src/main/java/org/conscrypt/ConnectionState.java
deleted file mode 100644
index 82fbf3c..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionState.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.crypto.Cipher;
-
-/**
- * This abstract class is a base for Record Protocol operating environmet
- * of different SSL protocol versions.
- */
-public abstract class ConnectionState {
-
- /**
- * The cipher used for encode operations
- */
- protected Cipher encCipher;
-
- /**
- * The cipher used for decode operations
- */
- protected Cipher decCipher;
-
- /**
- * The block size, or zero if not a block cipher
- */
- protected int block_size;
-
- /**
- * The size of MAC used under this connection state
- */
- protected int hash_size;
-
- /**
- * Write sequence number which is incremented after each
- * encrypt call
- */
- protected final byte[] write_seq_num = {0, 0, 0, 0, 0, 0, 0, 0};
-
- /**
- * Read sequence number which is incremented after each
- * decrypt call
- */
- protected final byte[] read_seq_num = {0, 0, 0, 0, 0, 0, 0, 0};
-
- protected Logger.Stream logger = Logger.getStream("conn_state");
-
- /**
- * Returns the minimal possible size of the
- * Generic[Stream|Block]Cipher structure under this
- * connection state.
- */
- protected int getMinFragmentSize() {
- // block ciphers return value with padding included
- return encCipher.getOutputSize(1+hash_size); // 1 byte for data
- }
-
- /**
- * Returns the size of the Generic[Stream|Block]Cipher structure
- * corresponding to the content data of specified size.
- */
- protected int getFragmentSize(int content_size) {
- return encCipher.getOutputSize(content_size+hash_size);
- }
-
- /**
- * Returns the minimal upper bound of the content size enclosed
- * into the Generic[Stream|Block]Cipher structure of specified size.
- * For stream ciphers the returned value will be exact value.
- */
- protected int getContentSize(int generic_cipher_size) {
- //it does not take the padding of block ciphered structures
- //into account (so returned value can be greater than actual)
- return decCipher.getOutputSize(generic_cipher_size)-hash_size;
- }
-
- /**
- * Returns the number of bytes of padding required to round the
- * content up to the required block size. Assumes power of two
- * block size.
- */
- protected int getPaddingSize(int content_size) {
- int mask = block_size - 1;
- return (block_size - (content_size & mask));
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @param type - the ContentType of the provided data
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- */
- protected byte[] encrypt(byte type, byte[] fragment) {
- return encrypt(type, fragment, 0, fragment.length);
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @param type - the ContentType of the provided data
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- * @param offset - the offset from which the data begins with.
- * @param len - the length of the data.
- */
- protected abstract byte[] encrypt
- (byte type, byte[] fragment, int offset, int len);
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data.
- * @param type - the ContentType of the data to be decrypted.
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- */
- protected byte[] decrypt(byte type, byte[] fragment) {
- return decrypt(type, fragment, 0, fragment.length);
- }
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data.
- * @param type - the ContentType of the data to be decrypted.
- * @param fragment - the byte array containing the
- * data to be encrypted under the current connection state.
- * @param offset - the offset from which the data begins with.
- * @param len - the length of the data.
- */
- protected abstract byte[] decrypt
- (byte type, byte[] fragment, int offset, int len);
-
- /**
- * Increments the sequence number.
- */
- protected static void incSequenceNumber(byte[] seq_num) {
- int octet = 7;
- while (octet >= 0) {
- seq_num[octet] ++;
- if (seq_num[octet] == 0) {
- // characteristic overflow, so
- // carrying a number in adding
- octet --;
- } else {
- return;
- }
- }
- }
-
- /**
- * Shutdownes the protocol. It will be impossiblke to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- encCipher = null;
- decCipher = null;
- for (int i=0; i<write_seq_num.length; i++) {
- write_seq_num[i] = 0;
- read_seq_num[i] = 0;
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java b/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java
deleted file mode 100644
index 84b8483..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionStateSSLv3.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.NullCipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class encapsulates the operating environment of the SSL v3
- * (http://wp.netscape.com/eng/ssl3) Record Protocol and provides
- * relating encryption/decryption functionality.
- * The work functionality is based on the security
- * parameters negotiated during the handshake.
- */
-public class ConnectionStateSSLv3 extends ConnectionState {
-
- // digest to create and check the message integrity info
- private final MessageDigest messageDigest;
- private final byte[] mac_write_secret;
- private final byte[] mac_read_secret;
-
- // paddings
- private final byte[] pad_1;
- private final byte[] pad_2;
- // array will hold the part of the MAC material:
- // length of 3 == 1(SSLCompressed.type) + 2(SSLCompressed.length)
- // (more on SSLv3 MAC computation and payload protection see
- // SSL v3 specification, p. 5.2.3)
- private final byte[] mac_material_part = new byte[3];
-
- /**
- * Creates the instance of SSL v3 Connection State. All of the
- * security parameters are provided by session object.
- * @param session the sessin object which incapsulates
- * all of the security parameters established by handshake protocol.
- * The key calculation for the state is done according
- * to the SSL v3 Protocol specification.
- * (http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt)
- */
- protected ConnectionStateSSLv3(SSLSessionImpl session) {
- try {
- CipherSuite cipherSuite = session.cipherSuite;
-
- boolean is_exportabe = cipherSuite.isExportable();
- hash_size = cipherSuite.getMACLength();
- int key_size = (is_exportabe)
- ? cipherSuite.keyMaterial
- : cipherSuite.expandedKeyMaterial;
- int iv_size = cipherSuite.ivSize;
- block_size = cipherSuite.getBlockSize();
-
- String algName = cipherSuite.getBulkEncryptionAlgorithm();
- String hashName = cipherSuite.getHashName();
- if (logger != null) {
- logger.println("ConnectionStateSSLv3.create:");
- logger.println(" cipher suite name: "
- + session.getCipherSuite());
- logger.println(" encryption alg name: " + algName);
- logger.println(" hash alg name: " + hashName);
- logger.println(" hash size: " + hash_size);
- logger.println(" block size: " + block_size);
- logger.println(" IV size:" + iv_size);
- logger.println(" key size: " + key_size);
- }
-
- byte[] clientRandom = session.clientRandom;
- byte[] serverRandom = session.serverRandom;
- // so we need PRF value of size of
- // 2*hash_size + 2*key_size + 2*iv_size
- byte[] key_block = new byte[2*hash_size + 2*key_size + 2*iv_size];
- byte[] seed = new byte[clientRandom.length + serverRandom.length];
- System.arraycopy(serverRandom, 0, seed, 0, serverRandom.length);
- System.arraycopy(clientRandom, 0, seed, serverRandom.length,
- clientRandom.length);
-
- PRF.computePRF_SSLv3(key_block, session.master_secret, seed);
-
- byte[] client_mac_secret = new byte[hash_size];
- byte[] server_mac_secret = new byte[hash_size];
- byte[] client_key = new byte[key_size];
- byte[] server_key = new byte[key_size];
-
- boolean is_client = !session.isServer;
-
- System.arraycopy(key_block, 0, client_mac_secret, 0, hash_size);
- System.arraycopy(key_block, hash_size,
- server_mac_secret, 0, hash_size);
- System.arraycopy(key_block, 2*hash_size, client_key, 0, key_size);
- System.arraycopy(key_block, 2*hash_size+key_size,
- server_key, 0, key_size);
-
- IvParameterSpec clientIV = null;
- IvParameterSpec serverIV = null;
-
- if (is_exportabe) {
- if (logger != null) {
- logger.println("ConnectionStateSSLv3: is_exportable");
- }
-
- MessageDigest md5 = MessageDigest.getInstance("MD5");
- md5.update(client_key);
- md5.update(clientRandom);
- md5.update(serverRandom);
- client_key = md5.digest();
-
- md5.update(server_key);
- md5.update(serverRandom);
- md5.update(clientRandom);
- server_key = md5.digest();
-
- key_size = cipherSuite.expandedKeyMaterial;
-
- if (block_size != 0) {
- md5.update(clientRandom);
- md5.update(serverRandom);
- clientIV = new IvParameterSpec(md5.digest(), 0, iv_size);
- md5.update(serverRandom);
- md5.update(clientRandom);
- serverIV = new IvParameterSpec(md5.digest(), 0, iv_size);
- }
- } else if (block_size != 0) {
- clientIV = new IvParameterSpec(key_block,
- 2*hash_size+2*key_size, iv_size);
- serverIV = new IvParameterSpec(key_block,
- 2*hash_size+2*key_size+iv_size, iv_size);
- }
-
- if (logger != null) {
- logger.println("is exportable: "+is_exportabe);
- logger.println("master_secret");
- logger.print(session.master_secret);
- logger.println("client_random");
- logger.print(clientRandom);
- logger.println("server_random");
- logger.print(serverRandom);
- //logger.println("key_block");
- //logger.print(key_block);
- logger.println("client_mac_secret");
- logger.print(client_mac_secret);
- logger.println("server_mac_secret");
- logger.print(server_mac_secret);
- logger.println("client_key");
- logger.print(client_key, 0, key_size);
- logger.println("server_key");
- logger.print(server_key, 0, key_size);
- if (clientIV != null) {
- logger.println("client_iv");
- logger.print(clientIV.getIV());
- logger.println("server_iv");
- logger.print(serverIV.getIV());
- } else {
- logger.println("no IV.");
- }
- }
-
- if (algName == null) {
- encCipher = new NullCipher();
- decCipher = new NullCipher();
- } else {
- encCipher = Cipher.getInstance(algName);
- decCipher = Cipher.getInstance(algName);
- if (is_client) { // client side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(client_key, 0, key_size, algName),
- clientIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(server_key, 0, key_size, algName),
- serverIV);
- } else { // server side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(server_key, 0, key_size, algName),
- serverIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(client_key, 0, key_size, algName),
- clientIV);
- }
- }
-
- messageDigest = MessageDigest.getInstance(hashName);
- if (is_client) { // client side
- mac_write_secret = client_mac_secret;
- mac_read_secret = server_mac_secret;
- } else { // server side
- mac_write_secret = server_mac_secret;
- mac_read_secret = client_mac_secret;
- }
- if (hashName.equals("MD5")) {
- pad_1 = SSLv3Constants.MD5pad1;
- pad_2 = SSLv3Constants.MD5pad2;
- } else {
- pad_1 = SSLv3Constants.SHApad1;
- pad_2 = SSLv3Constants.SHApad2;
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "Error during computation of security parameters"));
- }
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @throws AlertException if alert was occurred.
- */
- @Override
- protected byte[] encrypt(byte type, byte[] fragment, int offset, int len) {
- try {
- int content_mac_length = len + hash_size;
- int padding_length = (block_size == 0) ? 0 : getPaddingSize(++content_mac_length);
- byte[] res = new byte[content_mac_length + padding_length];
- System.arraycopy(fragment, offset, res, 0, len);
-
- mac_material_part[0] = type;
- mac_material_part[1] = (byte) ((0x00FF00 & len) >> 8);
- mac_material_part[2] = (byte) (0x0000FF & len);
-
- messageDigest.update(mac_write_secret);
- messageDigest.update(pad_1);
- messageDigest.update(write_seq_num);
- messageDigest.update(mac_material_part);
- messageDigest.update(fragment, offset, len);
- byte[] digest = messageDigest.digest();
- messageDigest.update(mac_write_secret);
- messageDigest.update(pad_2);
- messageDigest.update(digest);
- digest = messageDigest.digest();
- System.arraycopy(digest, 0, res, len, hash_size);
-
- //if (logger != null) {
- // logger.println("MAC Material:");
- // logger.print(write_seq_num);
- // logger.print(mac_material_header);
- // logger.print(fragment, offset, len);
- //}
-
- if (block_size != 0) {
- // do padding:
- Arrays.fill(res, content_mac_length-1,
- res.length, (byte) (padding_length));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.encrypt: "
- + (block_size != 0
- ? "GenericBlockCipher with padding["
- +padding_length+"]:"
- : "GenericStreamCipher:"));
- logger.print(res);
- }
- byte[] rez = new byte[encCipher.getOutputSize(res.length)];
- encCipher.update(res, 0, res.length, rez);
- incSequenceNumber(write_seq_num);
- return rez;
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException("Error during the encryption"));
- }
- }
-
- /**
- * 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] & 0xFF;
- for (int i=0; i<padding_length; i++) {
- if ((data[data.length-2-i] & 0xFF) != 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;
- }
-
- /**
- * Shutdown the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- @Override
- protected void shutdown() {
- Arrays.fill(mac_write_secret, (byte) 0);
- Arrays.fill(mac_read_secret, (byte) 0);
- super.shutdown();
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java b/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java
deleted file mode 100644
index a4d9de8..0000000
--- a/crypto/src/main/java/org/conscrypt/ConnectionStateTLS.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.NullCipher;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class encapsulates the operating environment of the TLS v1
- * (http://www.ietf.org/rfc/rfc2246.txt) Record Protocol and provides
- * relating encryption/decryption functionality.
- * The work functionality is based on the security
- * parameters negotiated during the handshake.
- */
-public class ConnectionStateTLS extends ConnectionState {
-
- // Pre-calculated prf label values:
- // "key expansion".getBytes()
- private static byte[] KEY_EXPANSION_LABEL = {
- (byte) 0x6B, (byte) 0x65, (byte) 0x79, (byte) 0x20, (byte) 0x65,
- (byte) 0x78, (byte) 0x70, (byte) 0x61, (byte) 0x6E, (byte) 0x73,
- (byte) 0x69, (byte) 0x6F, (byte) 0x6E };
-
- // "client write key".getBytes()
- private static byte[] CLIENT_WRITE_KEY_LABEL = {
- (byte) 0x63, (byte) 0x6C, (byte) 0x69, (byte) 0x65, (byte) 0x6E,
- (byte) 0x74, (byte) 0x20, (byte) 0x77, (byte) 0x72, (byte) 0x69,
- (byte) 0x74, (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65,
- (byte) 0x79 };
-
- // "server write key".getBytes()
- private static byte[] SERVER_WRITE_KEY_LABEL = {
- (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
- (byte) 0x72, (byte) 0x20, (byte) 0x77, (byte) 0x72, (byte) 0x69,
- (byte) 0x74, (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65,
- (byte) 0x79 };
-
- // "IV block".getBytes()
- private static byte[] IV_BLOCK_LABEL = {
- (byte) 0x49, (byte) 0x56, (byte) 0x20, (byte) 0x62, (byte) 0x6C,
- (byte) 0x6F, (byte) 0x63, (byte) 0x6B };
-
- // MACs to create and check the message integrity info
- private final Mac encMac;
- private final Mac decMac;
-
- // Once created permanently used array:
- // is used to create the header of the MAC material value:
- // 5 == 1(TLSCompressed.type) + 2(TLSCompressed.version) +
- // 2(TLSCompressed.length)
- private final byte[] mac_material_header = new byte[] {0, 3, 1, 0, 0};
-
- /**
- * Creates the instance of TLS v1 Connection State. All of the
- * security parameters are provided by session object.
- * @param session the sessin object which incapsulates
- * all of the security parameters established by handshake protocol.
- * The key calculation for the state is done according
- * to the TLS v 1.0 Protocol specification.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- */
- protected ConnectionStateTLS(SSLSessionImpl session) {
- try {
- CipherSuite cipherSuite = session.cipherSuite;
-
- hash_size = cipherSuite.getMACLength();
- boolean is_exportabe = cipherSuite.isExportable();
- int key_size = (is_exportabe)
- ? cipherSuite.keyMaterial
- : cipherSuite.expandedKeyMaterial;
- int iv_size = cipherSuite.ivSize;
- block_size = cipherSuite.getBlockSize();
-
- String algName = cipherSuite.getBulkEncryptionAlgorithm();
- String macName = cipherSuite.getHmacName();
- if (logger != null) {
- logger.println("ConnectionStateTLS.create:");
- logger.println(" cipher suite name: "
- + cipherSuite.getName());
- logger.println(" encryption alg name: " + algName);
- logger.println(" mac alg name: " + macName);
- logger.println(" hash size: " + hash_size);
- logger.println(" block size: " + block_size);
- logger.println(" IV size:" + iv_size);
- logger.println(" key size: " + key_size);
- }
-
- byte[] clientRandom = session.clientRandom;
- byte[] serverRandom = session.serverRandom;
- // so we need PRF value of size of
- // 2*hash_size + 2*key_size + 2*iv_size
- byte[] key_block = new byte[2*hash_size + 2*key_size + 2*iv_size];
- byte[] seed = new byte[clientRandom.length + serverRandom.length];
- System.arraycopy(serverRandom, 0, seed, 0, serverRandom.length);
- System.arraycopy(clientRandom, 0, seed, serverRandom.length,
- clientRandom.length);
-
- PRF.computePRF(key_block, session.master_secret,
- KEY_EXPANSION_LABEL, seed);
-
- byte[] client_mac_secret = new byte[hash_size];
- byte[] server_mac_secret = new byte[hash_size];
- byte[] client_key = new byte[key_size];
- byte[] server_key = new byte[key_size];
-
- boolean is_client = !session.isServer;
-
- System.arraycopy(key_block, 0, client_mac_secret, 0, hash_size);
- System.arraycopy(key_block, hash_size,
- server_mac_secret, 0, hash_size);
- System.arraycopy(key_block, 2*hash_size, client_key, 0, key_size);
- System.arraycopy(key_block, 2*hash_size+key_size,
- server_key, 0, key_size);
-
- IvParameterSpec clientIV = null;
- IvParameterSpec serverIV = null;
-
- if (is_exportabe) {
- System.arraycopy(clientRandom, 0,
- seed, 0, clientRandom.length);
- System.arraycopy(serverRandom, 0,
- seed, clientRandom.length, serverRandom.length);
- byte[] final_client_key =
- new byte[cipherSuite.expandedKeyMaterial];
- byte[] final_server_key =
- new byte[cipherSuite.expandedKeyMaterial];
- PRF.computePRF(final_client_key, client_key,
- CLIENT_WRITE_KEY_LABEL, seed);
- PRF.computePRF(final_server_key, server_key,
- SERVER_WRITE_KEY_LABEL, seed);
- client_key = final_client_key;
- server_key = final_server_key;
- if (block_size != 0) {
- byte[] iv_block = new byte[2*iv_size];
- PRF.computePRF(iv_block, null, IV_BLOCK_LABEL, seed);
- clientIV = new IvParameterSpec(iv_block, 0, iv_size);
- serverIV = new IvParameterSpec(iv_block, iv_size, iv_size);
- }
- } else if (block_size != 0) {
- clientIV = new IvParameterSpec(key_block,
- 2*(hash_size+key_size), iv_size);
- serverIV = new IvParameterSpec(key_block,
- 2*(hash_size+key_size)+iv_size, iv_size);
- }
-
- if (logger != null) {
- logger.println("is exportable: "+is_exportabe);
- logger.println("master_secret");
- logger.print(session.master_secret);
- logger.println("client_random");
- logger.print(clientRandom);
- logger.println("server_random");
- logger.print(serverRandom);
- //logger.println("key_block");
- //logger.print(key_block);
- logger.println("client_mac_secret");
- logger.print(client_mac_secret);
- logger.println("server_mac_secret");
- logger.print(server_mac_secret);
- logger.println("client_key");
- logger.print(client_key);
- logger.println("server_key");
- logger.print(server_key);
- if (clientIV == null) {
- logger.println("no IV.");
- } else {
- logger.println("client_iv");
- logger.print(clientIV.getIV());
- logger.println("server_iv");
- logger.print(serverIV.getIV());
- }
- }
-
- if (algName == null) {
- encCipher = new NullCipher();
- decCipher = new NullCipher();
- } else {
- encCipher = Cipher.getInstance(algName);
- decCipher = Cipher.getInstance(algName);
- if (is_client) { // client side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(client_key, algName), clientIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(server_key, algName), serverIV);
- } else { // server side
- encCipher.init(Cipher.ENCRYPT_MODE,
- new SecretKeySpec(server_key, algName), serverIV);
- decCipher.init(Cipher.DECRYPT_MODE,
- new SecretKeySpec(client_key, algName), clientIV);
- }
- }
-
- encMac = Mac.getInstance(macName);
- decMac = Mac.getInstance(macName);
- if (is_client) { // client side
- encMac.init(new SecretKeySpec(client_mac_secret, macName));
- decMac.init(new SecretKeySpec(server_mac_secret, macName));
- } else { // server side
- encMac.init(new SecretKeySpec(server_mac_secret, macName));
- decMac.init(new SecretKeySpec(client_mac_secret, macName));
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "Error during computation of security parameters"));
- }
- }
-
- /**
- * Creates the GenericStreamCipher or GenericBlockCipher
- * data structure for specified data of specified type.
- * @throws AlertException if alert was occurred.
- */
- @Override
- protected byte[] encrypt(byte type, byte[] fragment, int offset, int len) {
- try {
- int content_mac_length = len + hash_size;
- int padding_length = (block_size == 0) ? 0 : getPaddingSize(++content_mac_length);
- byte[] res = new byte[content_mac_length + padding_length];
- System.arraycopy(fragment, offset, res, 0, len);
-
- mac_material_header[0] = type;
- mac_material_header[3] = (byte) ((0x00FF00 & len) >> 8);
- mac_material_header[4] = (byte) (0x0000FF & len);
-
- encMac.update(write_seq_num);
- encMac.update(mac_material_header);
- encMac.update(fragment, offset, len);
- encMac.doFinal(res, len);
-
- //if (logger != null) {
- // logger.println("MAC Material:");
- // logger.print(write_seq_num);
- // logger.print(mac_material_header);
- // logger.print(fragment, offset, len);
- //}
-
- if (block_size != 0) {
- // do padding:
- Arrays.fill(res, content_mac_length-1,
- res.length, (byte) (padding_length));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.do_encryption: Generic"
- + (block_size != 0
- ? "BlockCipher with padding["+padding_length+"]:"
- : "StreamCipher:"));
- logger.print(res);
- }
- byte[] rez = new byte[encCipher.getOutputSize(res.length)];
- // We should not call just doFinal because it reinitialize
- // the cipher, but as says rfc 2246:
- // "For stream ciphers that do not use a synchronization
- // vector (such as RC4), the stream cipher state from the end
- // of one record is simply used on the subsequent packet."
- // and for block ciphers:
- // "The IV for subsequent records is the last ciphertext block from
- // the previous record."
- // i.e. we should keep the cipher state.
- encCipher.update(res, 0, res.length, rez);
- incSequenceNumber(write_seq_num);
- return rez;
- } catch (GeneralSecurityException e) {
- e.printStackTrace();
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException("Error during the encryption"));
- }
- }
-
- /**
- * Retrieves the fragment of the Plaintext structure of
- * the specified type from the provided data representing
- * the Generic[Stream|Block]Cipher structure.
- * @throws AlertException if alert was occurred.
- */
- @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] & 0xFF;
- for (int i=0; i<padding_length; i++) {
- if ((data[data.length-2-i] & 0xFF) != 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];
- }
-
- mac_material_header[0] = type;
- mac_material_header[3] = (byte) ((0x00FF00 & content.length) >> 8);
- mac_material_header[4] = (byte) (0x0000FF & content.length);
-
- decMac.update(read_seq_num);
- decMac.update(mac_material_header);
- decMac.update(data, 0, content.length); // mac.update(fragment);
- byte[] mac_value = decMac.doFinal();
- 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;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/ContentType.java b/crypto/src/main/java/org/conscrypt/ContentType.java
deleted file mode 100644
index b09f029..0000000
--- a/crypto/src/main/java/org/conscrypt/ContentType.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This class incapsulates the constants determining the
- * types of SSL/TLS record's content data.
- * Constant values are taken according to the TLS v1 specification
- * (http://www.ietf.org/rfc/rfc2246.txt).
- */
-public class ContentType {
-
- /**
- * Identifies change cipher spec message
- */
- protected static final byte CHANGE_CIPHER_SPEC = 20;
-
- /**
- * Identifies alert message
- */
- protected static final byte ALERT = 21;
-
- /**
- * Identifies handshake message
- */
- protected static final byte HANDSHAKE = 22;
-
- /**
- * Identifies application data message
- */
- protected static final byte APPLICATION_DATA = 23;
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/DHParameters.java b/crypto/src/main/java/org/conscrypt/DHParameters.java
deleted file mode 100644
index 7a742b2..0000000
--- a/crypto/src/main/java/org/conscrypt/DHParameters.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-/**
- * This class contains well-known primes
- */
-public class DHParameters {
-
- // Well-known 512 bit prime
- // http://news.hping.org/sci.crypt.archive/2370.html
- private static byte[] prime512 = new byte[] { (byte) 0xF5, (byte) 0x2A, (byte) 0xFF,
- (byte) 0x3C, (byte) 0xE1, (byte) 0xB1, (byte) 0x29, (byte) 0x40,
- (byte) 0x18, (byte) 0x11, (byte) 0x8D, (byte) 0x7C, (byte) 0x84,
- (byte) 0xA7, (byte) 0x0A, (byte) 0x72, (byte) 0xD6, (byte) 0x86,
- (byte) 0xC4, (byte) 0x03, (byte) 0x19, (byte) 0xC8, (byte) 0x07,
- (byte) 0x29, (byte) 0x7A, (byte) 0xCA, (byte) 0x95, (byte) 0x0C,
- (byte) 0xD9, (byte) 0x96, (byte) 0x9F, (byte) 0xAB, (byte) 0xD0,
- (byte) 0x0A, (byte) 0x50, (byte) 0x9B, (byte) 0x02, (byte) 0x46,
- (byte) 0xD3, (byte) 0x08, (byte) 0x3D, (byte) 0x66, (byte) 0xA4,
- (byte) 0x5D, (byte) 0x41, (byte) 0x9F, (byte) 0x9C, (byte) 0x7C,
- (byte) 0xBD, (byte) 0x89, (byte) 0x4B, (byte) 0x22, (byte) 0x19,
- (byte) 0x26, (byte) 0xBA, (byte) 0xAB, (byte) 0xA2, (byte) 0x5E,
- (byte) 0xC3, (byte) 0x55, (byte) 0xE9, (byte) 0x2A, (byte) 0x05,
- (byte) 0x5F };
-
- // Well-Known Group 1: A 768 bit prime rfc 2539
- // (http://www.ietf.org/rfc/rfc2539.txt?number=2539)
- private static byte[] primeGroup1 = { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9,
- (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68,
- (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62,
- (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1,
- (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A,
- (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B,
- (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
- (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79,
- (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF,
- (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A,
- (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A,
- (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37,
- (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D,
- (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
- (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
- (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9,
- (byte) 0xA6, (byte) 0x3A, (byte) 0x36, (byte) 0x20, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF };
-
- // Well-Known Group 2: A 1024 bit prime rfc 2539
- // (http://www.ietf.org/rfc/rfc2539.txt?number=2539)
- private static byte[] primeGroup2 = { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC9,
- (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68,
- (byte) 0xC2, (byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62,
- (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C, (byte) 0xD1,
- (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A,
- (byte) 0x67, (byte) 0xCC, (byte) 0x74, (byte) 0x02, (byte) 0x0B,
- (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
- (byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79,
- (byte) 0x8E, (byte) 0x34, (byte) 0x04, (byte) 0xDD, (byte) 0xEF,
- (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A,
- (byte) 0x43, (byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A,
- (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14, (byte) 0x37,
- (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D,
- (byte) 0x51, (byte) 0xC2, (byte) 0x45, (byte) 0xE4, (byte) 0x85,
- (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
- (byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9,
- (byte) 0xA6, (byte) 0x37, (byte) 0xED, (byte) 0x6B, (byte) 0x0B,
- (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06,
- (byte) 0xB7, (byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B,
- (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F, (byte) 0xA5,
- (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C,
- (byte) 0x4B, (byte) 0x1F, (byte) 0xE6, (byte) 0x49, (byte) 0x28,
- (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE6, (byte) 0x53,
- (byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
- (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
- };
-
- private static byte[] prime;
-
- static {
-//TODO set prime depand on some system or security property
- prime = prime512;
- }
-
- /**
- * Returns prime bytes
- * @return
- */
- public static byte[] getPrime() {
- return prime;
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/DataStream.java b/crypto/src/main/java/org/conscrypt/DataStream.java
deleted file mode 100644
index d65b01a..0000000
--- a/crypto/src/main/java/org/conscrypt/DataStream.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * This interface represents the ability of the
- * classes to provide the chunks of data.
- */
-public interface DataStream {
-
- /**
- * Checks if there is data to be read.
- * @return true if there is the input data in the stream,
- * false otherwise
- */
- public boolean hasData();
-
- /**
- * Retrieves the data of specified length from the stream.
- * If the data size in the stream is less than specified length,
- * method returns all the data contained in the stream.
- * @return byte array containing the demanded data.
- */
- public byte[] getData(int length);
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java b/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java
deleted file mode 100644
index c90787f..0000000
--- a/crypto/src/main/java/org/conscrypt/DefaultSSLContextImpl.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-/**
- * Support class for this package.
- */
-public final class DefaultSSLContextImpl extends OpenSSLContextImpl {
-
- /**
- * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
- * DefaultSSLContextImpl.class monitor
- */
- private static KeyManager[] KEY_MANAGERS;
-
- /**
- * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
- * DefaultSSLContextImpl.class monitor
- */
- private static TrustManager[] TRUST_MANAGERS;
-
- /**
- * DefaultSSLContextImpl delegates the work to the super class
- * since there is no way to put a synchronized around both the
- * call to super and the rest of this constructor to guarantee
- * that we don't have races in creating the state shared between
- * all default SSLContexts.
- */
- public DefaultSSLContextImpl() throws GeneralSecurityException, IOException {
- super(null);
- }
-
- // TODO javax.net.ssl.keyStoreProvider system property
- KeyManager[] getKeyManagers () throws GeneralSecurityException, IOException {
- if (KEY_MANAGERS != null) {
- return KEY_MANAGERS;
- }
- // find KeyStore, KeyManagers
- String keystore = System.getProperty("javax.net.ssl.keyStore");
- if (keystore == null) {
- return null;
- }
- String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
- char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
-
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(keystore));
- ks.load(is, pwd);
- } finally {
- if (is != null) {
- is.close();
- }
- }
-
- String kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
- kmf.init(ks, pwd);
- KEY_MANAGERS = kmf.getKeyManagers();
- return KEY_MANAGERS;
- }
-
- // TODO javax.net.ssl.trustStoreProvider system property
- TrustManager[] getTrustManagers() throws GeneralSecurityException, IOException {
- if (TRUST_MANAGERS != null) {
- return TRUST_MANAGERS;
- }
-
- // find TrustStore, TrustManagers
- String keystore = System.getProperty("javax.net.ssl.trustStore");
- if (keystore == null) {
- return null;
- }
- String keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
- char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
-
- // TODO Defaults: jssecacerts; cacerts
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(keystore));
- ks.load(is, pwd);
- } finally {
- if (is != null) {
- is.close();
- }
- }
- String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
- tmf.init(ks);
- TRUST_MANAGERS = tmf.getTrustManagers();
- return TRUST_MANAGERS;
- }
-
- @Override
- public void engineInit(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr) throws KeyManagementException {
- throw new KeyManagementException("Do not init() the default SSLContext ");
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/DelegatedTask.java b/crypto/src/main/java/org/conscrypt/DelegatedTask.java
deleted file mode 100644
index 8eab2ea..0000000
--- a/crypto/src/main/java/org/conscrypt/DelegatedTask.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- * Delegated Runnable task for SSLEngine
- */
-public class DelegatedTask implements Runnable {
-
- private final HandshakeProtocol handshaker;
- private final Runnable action;
-
- public DelegatedTask(Runnable action, HandshakeProtocol handshaker) {
- this.action = action;
- this.handshaker = handshaker;
- }
-
- public void run() {
- synchronized (handshaker) {
- try {
- action.run();
- } catch (RuntimeException e) {
- // pass exception to HandshakeProtocol
- handshaker.delegatedTaskErr = e;
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/DigitalSignature.java b/crypto/src/main/java/org/conscrypt/DigitalSignature.java
deleted file mode 100644
index e24056e..0000000
--- a/crypto/src/main/java/org/conscrypt/DigitalSignature.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.security.DigestException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.net.ssl.SSLException;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * This class represents Signature type, as described in TLS v 1.0 Protocol
- * specification, 7.4.3. It allow to init, update and sign hash. Hash algorithm
- * depends on SignatureAlgorithm.
- *
- * select (SignatureAlgorithm)
- * { case anonymous: struct { };
- * case rsa:
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- * case dsa:
- * digitally-signed struct {
- * opaque sha_hash[20];
- * };
- * } Signature;
- *
- * Digital signing description see in TLS spec., 4.7.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- *
- */
-public class DigitalSignature {
-
- private final MessageDigest md5;
- private final MessageDigest sha;
- private final Signature signature;
- private final Cipher cipher;
-
- private byte[] md5_hash;
- private byte[] sha_hash;
-
- /**
- * Create Signature type
- * @param algorithm the key algorithm used for the signature
- */
- public DigitalSignature(String algorithm) {
- try {
- sha = MessageDigest.getInstance("SHA-1");
-
- if ("RSA".equals(algorithm)) {
- md5 = MessageDigest.getInstance("MD5");
- cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
- signature = null;
- } else if ("DSA".equals(algorithm)) {
- // SignatureAlgorithm is dsa
- signature = Signature.getInstance("NONEwithDSA");
- cipher = null;
- md5 = null;
- } else {
- cipher = null;
- signature = null;
- md5 = null;
- }
- } catch (NoSuchAlgorithmException e) {
- // this should never happen
- throw new AssertionError(e);
- } catch (NoSuchPaddingException e) {
- // this should never happen
- throw new AssertionError(e);
- }
- }
-
- /**
- * Initiate Signature type by private key
- * @param key
- */
- public void init(PrivateKey key) {
- try {
- if (signature != null) {
- signature.initSign(key);
- } else if (cipher != null) {
- cipher.init(Cipher.ENCRYPT_MODE, key);
- }
- } catch (InvalidKeyException e){
- throw new AlertException(AlertProtocol.BAD_CERTIFICATE,
- new SSLException("init - invalid private key", e));
- }
- }
-
- /**
- * Initiate Signature type by certificate
- * @param cert
- */
- public void init(Certificate cert) {
- try {
- if (signature != null) {
- signature.initVerify(cert);
- } else if (cipher != null) {
- cipher.init(Cipher.DECRYPT_MODE, cert);
- }
- } catch (InvalidKeyException e){
- throw new AlertException(AlertProtocol.BAD_CERTIFICATE,
- new SSLException("init - invalid certificate", e));
- }
- }
-
- /**
- * Update Signature hash
- * @param data
- */
- public void update(byte[] data) {
- if (sha != null) {
- sha.update(data);
- }
- if (md5 != null) {
- md5.update(data);
- }
- }
-
- /**
- * Sets MD5 hash
- * @param data
- */
- public void setMD5(byte[] data) {
- md5_hash = data;
- }
-
- /**
- * Sets SHA hash
- * @param data
- */
- public void setSHA(byte[] data) {
- sha_hash = data;
- }
-
- /**
- * Sign hash
- * @return Signature bytes
- */
- public byte[] sign() {
- try {
- if (md5 != null && md5_hash == null) {
- md5_hash = new byte[16];
- md5.digest(md5_hash, 0, md5_hash.length);
- }
- if (md5_hash != null) {
- if (signature != null) {
- signature.update(md5_hash);
- } else if (cipher != null) {
- cipher.update(md5_hash);
- }
- }
- if (sha != null && sha_hash == null) {
- sha_hash = new byte[20];
- sha.digest(sha_hash, 0, sha_hash.length);
- }
- if (sha_hash != null) {
- if (signature != null) {
- signature.update(sha_hash);
- } else if (cipher != null) {
- cipher.update(sha_hash);
- }
- }
- if (signature != null) {
- return signature.sign();
- } else if (cipher != null) {
- return cipher.doFinal();
- }
- return EmptyArray.BYTE;
- } catch (DigestException e){
- return EmptyArray.BYTE;
- } catch (SignatureException e){
- return EmptyArray.BYTE;
- } catch (BadPaddingException e){
- return EmptyArray.BYTE;
- } catch (IllegalBlockSizeException e){
- return EmptyArray.BYTE;
- }
- }
-
- /**
- * Verifies the signature data.
- * @param data - the signature bytes
- * @return true if verified
- */
- public boolean verifySignature(byte[] data) {
- if (signature != null) {
- try {
- if (sha_hash == null) {
- sha_hash = sha.digest();
- }
- signature.update(sha_hash);
- return signature.verify(data);
- } catch (SignatureException e) {
- return false;
- }
- }
-
- if (cipher != null) {
- final byte[] decrypt;
- try {
- decrypt = cipher.doFinal(data);
- } catch (IllegalBlockSizeException e) {
- return false;
- } catch (BadPaddingException e) {
- return false;
- }
-
- final byte[] md5_sha;
- if (sha != null && sha_hash == null) {
- sha_hash = sha.digest();
- }
- if (md5 != null && md5_hash == null) {
- md5_hash = md5.digest();
- }
- if (md5_hash != null && sha_hash != null) {
- md5_sha = new byte[md5_hash.length + sha_hash.length];
- System.arraycopy(md5_hash, 0, md5_sha, 0, md5_hash.length);
- System.arraycopy(sha_hash, 0, md5_sha, md5_hash.length, sha_hash.length);
- } else if (md5_hash != null) {
- md5_sha = md5_hash;
- } else {
- md5_sha = sha_hash;
- }
-
- return Arrays.equals(decrypt, md5_sha);
- } else if (data == null || data.length == 0) {
- return true;
- } else {
- return false;
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/EndOfBufferException.java b/crypto/src/main/java/org/conscrypt/EndOfBufferException.java
deleted file mode 100644
index acd3417..0000000
--- a/crypto/src/main/java/org/conscrypt/EndOfBufferException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * This exception indicates that data could not be read from the stream because the underlying input
- * stream reached its end.
- */
-public class EndOfBufferException extends IOException {
-
- private static final long serialVersionUID = 1838636631255369519L;
-
- public EndOfBufferException() {
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/EndOfSourceException.java b/crypto/src/main/java/org/conscrypt/EndOfSourceException.java
deleted file mode 100644
index 4789cd8..0000000
--- a/crypto/src/main/java/org/conscrypt/EndOfSourceException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- * This exception indicates that data could not be read from the buffered stream because underlying
- * data buffer was exhausted.
- */
-public class EndOfSourceException extends IOException {
-
- private static final long serialVersionUID = -4673611435974054413L;
-
- public EndOfSourceException() {
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java b/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java
deleted file mode 100644
index e4dab13..0000000
--- a/crypto/src/main/java/org/conscrypt/FileClientSessionCache.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import javax.net.ssl.SSLSession;
-import libcore.io.IoUtils;
-
-/**
- * File-based cache implementation. Only one process should access the
- * underlying directory at a time.
- */
-public class FileClientSessionCache {
-
- public static final int MAX_SIZE = 12; // ~72k
-
- private FileClientSessionCache() {}
-
- /**
- * This cache creates one file per SSL session using "host.port" for
- * the file name. Files are created or replaced when session data is put
- * in the cache (see {@link #putSessionData}). Files are read on
- * cache hits, but not on cache misses.
- *
- * <p>When the number of session files exceeds MAX_SIZE, we delete the
- * least-recently-used file. We don't current persist the last access time,
- * so the ordering actually ends up being least-recently-modified in some
- * cases and even just "not accessed in this process" if the filesystem
- * doesn't track last modified times.
- */
- static class Impl implements SSLClientSessionCache {
-
- /** Directory to store session files in. */
- final File directory;
-
- /**
- * Map of name -> File. Keeps track of the order files were accessed in.
- */
- Map<String, File> accessOrder = newAccessOrder();
-
- /** The number of files on disk. */
- int size;
-
- /**
- * The initial set of files. We use this to defer adding information
- * about all files to accessOrder until necessary.
- */
- String[] initialFiles;
-
- /**
- * Constructs a new cache backed by the given directory.
- */
- Impl(File directory) throws IOException {
- boolean exists = directory.exists();
- if (exists && !directory.isDirectory()) {
- throw new IOException(directory + " exists but is not a directory.");
- }
-
- if (exists) {
- // Read and sort initial list of files. We defer adding
- // information about these files to accessOrder until necessary
- // (see indexFiles()). Sorting the list enables us to detect
- // cache misses in getSessionData().
- // Note: Sorting an array here was faster than creating a
- // HashSet on Dalvik.
- initialFiles = directory.list();
- if (initialFiles == null) {
- // File.list() will return null in error cases without throwing IOException
- // http://b/3363561
- throw new IOException(directory + " exists but cannot list contents.");
- }
- Arrays.sort(initialFiles);
- size = initialFiles.length;
- } else {
- // Create directory.
- if (!directory.mkdirs()) {
- throw new IOException("Creation of " + directory + " directory failed.");
- }
- size = 0;
- }
-
- this.directory = directory;
- }
-
- /**
- * Creates a new access-ordered linked hash map.
- */
- private static Map<String, File> newAccessOrder() {
- return new LinkedHashMap<String, File>(
- MAX_SIZE, 0.75f, true /* access order */);
- }
-
- /**
- * Gets the file name for the given host and port.
- */
- private static String fileName(String host, int port) {
- if (host == null) {
- throw new NullPointerException("host == null");
- }
- return host + "." + port;
- }
-
- public synchronized byte[] getSessionData(String host, int port) {
- /*
- * Note: This method is only called when the in-memory cache
- * in SSLSessionContext misses, so it would be unnecessarily
- * redundant for this cache to store data in memory.
- */
-
- String name = fileName(host, port);
- File file = accessOrder.get(name);
-
- if (file == null) {
- // File wasn't in access order. Check initialFiles...
- if (initialFiles == null) {
- // All files are in accessOrder, so it doesn't exist.
- return null;
- }
-
- // Look in initialFiles.
- if (Arrays.binarySearch(initialFiles, name) < 0) {
- // Not found.
- return null;
- }
-
- // The file is on disk but not in accessOrder yet.
- file = new File(directory, name);
- accessOrder.put(name, file);
- }
-
- FileInputStream in;
- try {
- in = new FileInputStream(file);
- } catch (FileNotFoundException e) {
- logReadError(host, file, e);
- return null;
- }
- try {
- int size = (int) file.length();
- byte[] data = new byte[size];
- new DataInputStream(in).readFully(data);
- return data;
- } catch (IOException e) {
- logReadError(host, file, e);
- return null;
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- static void logReadError(String host, File file, Throwable t) {
- System.logW("Error reading session data for " + host + " from " + file + ".", t);
- }
-
- public synchronized void putSessionData(SSLSession session,
- byte[] sessionData) {
- String host = session.getPeerHost();
- if (sessionData == null) {
- throw new NullPointerException("sessionData == null");
- }
-
- String name = fileName(host, session.getPeerPort());
- File file = new File(directory, name);
-
- // Used to keep track of whether or not we're expanding the cache.
- boolean existedBefore = file.exists();
-
- FileOutputStream out;
- try {
- out = new FileOutputStream(file);
- } catch (FileNotFoundException e) {
- // We can't write to the file.
- logWriteError(host, file, e);
- return;
- }
-
- // If we expanded the cache (by creating a new file)...
- if (!existedBefore) {
- size++;
-
- // Delete an old file if necessary.
- makeRoom();
- }
-
- boolean writeSuccessful = false;
- try {
- out.write(sessionData);
- writeSuccessful = true;
- } catch (IOException e) {
- logWriteError(host, file, e);
- } finally {
- boolean closeSuccessful = false;
- try {
- out.close();
- closeSuccessful = true;
- } catch (IOException e) {
- logWriteError(host, file, e);
- } finally {
- if (!writeSuccessful || !closeSuccessful) {
- // Storage failed. Clean up.
- delete(file);
- } else {
- // Success!
- accessOrder.put(name, file);
- }
- }
- }
- }
-
- /**
- * Deletes old files if necessary.
- */
- private void makeRoom() {
- if (size <= MAX_SIZE) {
- return;
- }
-
- indexFiles();
-
- // Delete LRUed files.
- int removals = size - MAX_SIZE;
- Iterator<File> i = accessOrder.values().iterator();
- do {
- delete(i.next());
- i.remove();
- } while (--removals > 0);
- }
-
- /**
- * Lazily updates accessOrder to know about all files as opposed to
- * just the files accessed since this process started.
- */
- private void indexFiles() {
- String[] initialFiles = this.initialFiles;
- if (initialFiles != null) {
- this.initialFiles = null;
-
- // Files on disk only, sorted by last modified time.
- // TODO: Use last access time.
- Set<CacheFile> diskOnly = new TreeSet<CacheFile>();
- for (String name : initialFiles) {
- // If the file hasn't been accessed in this process...
- if (!accessOrder.containsKey(name)) {
- diskOnly.add(new CacheFile(directory, name));
- }
- }
-
- if (!diskOnly.isEmpty()) {
- // Add files not accessed in this process to the beginning
- // of accessOrder.
- Map<String, File> newOrder = newAccessOrder();
- for (CacheFile cacheFile : diskOnly) {
- newOrder.put(cacheFile.name, cacheFile);
- }
- newOrder.putAll(accessOrder);
-
- this.accessOrder = newOrder;
- }
- }
- }
-
- @SuppressWarnings("ThrowableInstanceNeverThrown")
- private void delete(File file) {
- if (!file.delete()) {
- System.logW("Failed to delete " + file + ".", new IOException());
- }
- size--;
- }
-
- static void logWriteError(String host, File file, Throwable t) {
- System.logW("Error writing session data for " + host + " to " + file + ".", t);
- }
- }
-
- /**
- * Maps directories to the cache instances that are backed by those
- * directories. We synchronize access using the cache instance, so it's
- * important that everyone shares the same instance.
- */
- static final Map<File, FileClientSessionCache.Impl> caches
- = new HashMap<File, FileClientSessionCache.Impl>();
-
- /**
- * Returns a cache backed by the given directory. Creates the directory
- * (including parent directories) if necessary. This cache should have
- * exclusive access to the given directory.
- *
- * @param directory to store files in
- * @return a cache backed by the given directory
- * @throws IOException if the file exists and is not a directory or if
- * creating the directories fails
- */
- public static synchronized SSLClientSessionCache usingDirectory(
- File directory) throws IOException {
- FileClientSessionCache.Impl cache = caches.get(directory);
- if (cache == null) {
- cache = new FileClientSessionCache.Impl(directory);
- caches.put(directory, cache);
- }
- return cache;
- }
-
- /** For testing. */
- static synchronized void reset() {
- caches.clear();
- }
-
- /** A file containing a piece of cached data. */
- static class CacheFile extends File {
-
- final String name;
-
- CacheFile(File dir, String name) {
- super(dir, name);
- this.name = name;
- }
-
- long lastModified = -1;
-
- @Override
- public long lastModified() {
- long lastModified = this.lastModified;
- if (lastModified == -1) {
- lastModified = this.lastModified = super.lastModified();
- }
- return lastModified;
- }
-
- @Override
- public int compareTo(File another) {
- // Sort by last modified time.
- long result = lastModified() - another.lastModified();
- if (result == 0) {
- return super.compareTo(another);
- }
- return result < 0 ? -1 : 1;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Finished.java b/crypto/src/main/java/org/conscrypt/Finished.java
deleted file mode 100644
index e0b7eaa..0000000
--- a/crypto/src/main/java/org/conscrypt/Finished.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents Finished message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.9.
- * Finished</a>
- *
- */
-public class Finished extends Message {
-
- // verify data
- private byte[] data;
-
- /**
- * Creates outbound message
- * @param bytes
- */
- public Finished(byte[] bytes) {
- data = bytes;
- length = data.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public Finished(HandshakeIODataStream in, int length)
- throws IOException {
- if (length == 12 || length == 36) {
- data = in.read(length);
- this.length = data.length;
- } else {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect Finished");
- }
- }
-
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(data);
- }
-
- /**
- * Returns message type
- */
- @Override
- public int getType() {
- return Handshake.FINISHED;
- }
-
- /**
- * Returns verify data
- */
- public byte[] getData() {
- return data;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Handshake.java b/crypto/src/main/java/org/conscrypt/Handshake.java
deleted file mode 100644
index 7cee71b..0000000
--- a/crypto/src/main/java/org/conscrypt/Handshake.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- *
- * This class incapsulates the constants determining the types of handshake
- * messages as defined in TLS 1.0 spec., 7.4. Handshake protocol.
- * (http://www.ietf.org/rfc/rfc2246.txt)
- *
- */
-public class Handshake {
-
- /**
- *
- * hello_request handshake type
- */
- public static final byte HELLO_REQUEST = 0;
-
- /**
- *
- * client_hello handshake type
- */
- public static final byte CLIENT_HELLO = 1;
-
- /**
- *
- * server_hello handshake type
- */
- public static final byte SERVER_HELLO = 2;
-
- /**
- *
- * certificate handshake type
- */
- public static final byte CERTIFICATE = 11;
-
- /**
- *
- * server_key_exchange handshake type
- */
- public static final byte SERVER_KEY_EXCHANGE = 12;
-
- /**
- *
- * certificate_request handshake type
- */
- public static final byte CERTIFICATE_REQUEST = 13;
-
- /**
- *
- * server_hello_done handshake type
- */
- public static final byte SERVER_HELLO_DONE = 14;
-
- /**
- *
- * certificate_verify handshake type
- */
- public static final byte CERTIFICATE_VERIFY = 15;
-
- /**
- *
- * client_key_exchange handshake type
- */
- public static final byte CLIENT_KEY_EXCHANGE = 16;
-
- /**
- *
- * finished handshake type
- */
- public static final byte FINISHED = 20;
-
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java b/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java
deleted file mode 100644
index 0723820..0000000
--- a/crypto/src/main/java/org/conscrypt/HandshakeIODataStream.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- * This class provides Input/Output data functionality
- * for handshake layer. It provides read and write operations
- * and accumulates all sent/received handshake's data.
- * This class can be presented as a combination of 2 data pipes.
- * The first data pipe is a pipe of income data: append method
- * places the data at the beginning of the pipe, and read methods
- * consume the data from the pipe. The second pipe is an outcoming
- * data pipe: write operations plases the data into the pipe,
- * and getData methods consume the data.
- * It is important to note that work with pipe cound not be
- * started if there is unconsumed data in another pipe. It is
- * reasoned by the following: handshake protocol performs read
- * and write operations consecuently. I.e. it first reads all
- * income data and only than produces the responce and places it
- * into the stream.
- * The read operations of the stream presented by the methods
- * of SSLInputStream which in its turn is an extension of InputStream.
- * So this stream can be used as an InputStream parameter for
- * certificate generation.
- * Also input stream functionality supports marks. The marks
- * help to reset the position of the stream in case of incompleate
- * handshake records. Note that in case of exhausting
- * of income data the EndOfBufferException is thown which implies
- * the following:
- * 1. the stream contains scrappy handshake record,
- * 2. the read position should be reseted to marked,
- * 3. and more income data is expected.
- * The throwing of the exception (instead of returning of -1 value
- * or incompleate filling of destination buffer)
- * helps to speed up the process of scrappy data recognition and
- * processing.
- * For more information about TLS handshake process see
- * TLS v 1 specification at http://www.ietf.org/rfc/rfc2246.txt.
- */
-public class HandshakeIODataStream
- extends SSLInputStream implements org.conscrypt.Appendable, DataStream {
-
- // Objects are used to compute digests of data passed
- // during the handshake phase
- private static final MessageDigest md5;
- private static final MessageDigest sha;
-
- static {
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException(
- "Could not initialize the Digest Algorithms.");
- }
- }
-
- public HandshakeIODataStream() {}
-
- // buffer is used to keep the handshaking data;
- private int buff_size = 1024;
- private int inc_buff_size = 1024;
- private byte[] buffer = new byte[buff_size];
-
-
- // ---------------- Input related functionality -----------------
-
- // position of the next byte to read
- private int read_pos;
- private int marked_pos;
- // position of the last byte to read + 1
- private int read_pos_end;
-
- @Override
- public int available() {
- return read_pos_end - read_pos;
- }
-
- @Override
- public boolean markSupported() {
- return true;
- }
-
- @Override
- public void mark(int limit) {
- marked_pos = read_pos;
- }
-
- public void mark() {
- marked_pos = read_pos;
- }
-
- @Override
- public void reset() {
- read_pos = marked_pos;
- }
-
- /**
- * Removes the data from the marked position to
- * the current read position. The method is usefull when it is needed
- * to delete one message from the internal buffer.
- */
- protected void removeFromMarkedPosition() {
- System.arraycopy(buffer, read_pos,
- buffer, marked_pos, read_pos_end - read_pos);
- read_pos_end -= (read_pos - marked_pos);
- read_pos = marked_pos;
- }
-
- /**
- * read an opaque value;
- * @param byte: byte
- * @return
- */
- @Override
- public int read() throws IOException {
- if (read_pos == read_pos_end) {
- //return -1;
- throw new EndOfBufferException();
- }
- return buffer[read_pos++] & 0xFF;
- }
-
- /**
- * reads vector of opaque values
- * @param new: long
- * @return
- */
- @Override
- public byte[] read(int length) throws IOException {
- if (length > available()) {
- throw new EndOfBufferException();
- }
- byte[] res = new byte[length];
- System.arraycopy(buffer, read_pos, res, 0, length);
- read_pos = read_pos + length;
- return res;
- }
-
- @Override
- public int read(byte[] dst, int offset, int length) throws IOException {
- if (length > available()) {
- throw new EndOfBufferException();
- }
- System.arraycopy(buffer, read_pos, dst, offset, length);
- read_pos = read_pos + length;
- return length;
- }
-
- // ------------------- Extending of the input data ---------------------
-
- /**
- * Appends the income data to be read by handshake protocol.
- * The attempts to overflow the buffer by means of this methods
- * seem to be futile because of:
- * 1. The SSL protocol specifies the maximum size of the record
- * and record protocol does not pass huge messages.
- * (see TLS v1 specification http://www.ietf.org/rfc/rfc2246.txt ,
- * p 6.2)
- * 2. After each call of this method, handshake protocol should
- * start (and starts) the operations on received data and recognize
- * the fake data if such was provided (to check the size of certificate
- * for example).
- */
- public void append(byte[] src) {
- append(src, 0, src.length);
- }
-
- private void append(byte[] src, int from, int length) {
- if (read_pos == read_pos_end) {
- // start reading state after writing
- if (write_pos_beg != write_pos) {
- // error: outboud handshake data was not sent,
- // but inbound handshake data has been received.
- throw new AlertException(
- AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLHandshakeException(
- "Handshake message has been received before "
- + "the last oubound message had been sent."));
- }
- if (read_pos < write_pos) {
- read_pos = write_pos;
- read_pos_end = read_pos;
- }
- }
- if (read_pos_end + length > buff_size) {
- enlargeBuffer(read_pos_end+length-buff_size);
- }
- System.arraycopy(src, from, buffer, read_pos_end, length);
- read_pos_end += length;
- }
-
- private void enlargeBuffer(int size) {
- buff_size = (size < inc_buff_size)
- ? buff_size + inc_buff_size
- : buff_size + size;
- byte[] new_buff = new byte[buff_size];
- System.arraycopy(buffer, 0, new_buff, 0, buffer.length);
- buffer = new_buff;
- }
-
- protected void clearBuffer() {
- read_pos = 0;
- marked_pos = 0;
- read_pos_end = 0;
- write_pos = 0;
- write_pos_beg = 0;
- Arrays.fill(buffer, (byte) 0);
- }
-
- // ------------------- Output related functionality --------------------
-
- // position in the buffer available for write
- private int write_pos;
- // position in the buffer where the last write session has begun
- private int write_pos_beg;
-
- // checks if the data can be written in the buffer
- private void check(int length) {
- // (write_pos == write_pos_beg) iff:
- // 1. there were not write operations yet
- // 2. all written data was demanded by getData methods
- if (write_pos == write_pos_beg) {
- // just started to write after the reading
- if (read_pos != read_pos_end) {
- // error: attempt to write outbound data into the stream before
- // all the inbound handshake data had been read
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLHandshakeException("Data was not fully read: "
- + read_pos + " " + read_pos_end));
- }
- // set up the write positions
- if (write_pos_beg < read_pos_end) {
- write_pos_beg = read_pos_end;
- write_pos = write_pos_beg;
- }
- }
- // if there is not enought free space in the buffer - enlarge it:
- if (write_pos + length >= buff_size) {
- enlargeBuffer(length);
- }
- }
-
- /**
- * Writes an opaque value
- * @param byte: byte
- */
- public void write(byte b) {
- check(1);
- buffer[write_pos++] = b;
- }
-
- /**
- * Writes Uint8 value
- * @param long: the value to be written (last byte)
- */
- public void writeUint8(long n) {
- check(1);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint16 value
- * @param long: the value to be written (last 2 bytes)
- */
- public void writeUint16(long n) {
- check(2);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint24 value
- * @param long: the value to be written (last 3 bytes)
- */
- public void writeUint24(long n) {
- check(3);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint32 value
- * @param long: the value to be written (last 4 bytes)
- */
- public void writeUint32(long n) {
- check(4);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * Writes Uint64 value
- * @param long: the value to be written
- */
- public void writeUint64(long n) {
- check(8);
- buffer[write_pos++] = (byte) ((n & 0x00ff00000000000000L) >> 56);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000000000L) >> 48);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000000000L) >> 40);
- buffer[write_pos++] = (byte) ((n & 0x00ff00000000L) >> 32);
- buffer[write_pos++] = (byte) ((n & 0x00ff000000) >> 24);
- buffer[write_pos++] = (byte) ((n & 0x00ff0000) >> 16);
- buffer[write_pos++] = (byte) ((n & 0x00ff00) >> 8);
- buffer[write_pos++] = (byte) (n & 0x00ff);
- }
-
- /**
- * writes vector of opaque values
- * @param vector the vector to be written
- */
- public void write(byte[] vector) {
- check(vector.length);
- System.arraycopy(vector, 0, buffer, write_pos, vector.length);
- write_pos += vector.length;
- }
-
- // ------------------- Retrieve the written bytes ----------------------
-
- public boolean hasData() {
- return (write_pos > write_pos_beg);
- }
-
- /**
- * returns the chunk of stored data with the length no more than specified.
- * @param length: int
- * @return
- */
- public byte[] getData(int length) {
- byte[] res;
- if (write_pos - write_pos_beg < length) {
- res = new byte[write_pos - write_pos_beg];
- System.arraycopy(buffer, write_pos_beg,
- res, 0, write_pos-write_pos_beg);
- write_pos_beg = write_pos;
- } else {
- res = new byte[length];
- System.arraycopy(buffer, write_pos_beg, res, 0, length);
- write_pos_beg += length;
- }
- return res;
- }
-
- // ---------------------- Message Digest Functionality ----------------
-
- /**
- * Returns the MD5 digest of the data passed throught the stream
- * @return MD5 digest
- */
- protected byte[] getDigestMD5() {
- synchronized (md5) {
- int len = (read_pos_end > write_pos)
- ? read_pos_end
- : write_pos;
- md5.update(buffer, 0, len);
- return md5.digest();
- }
- }
-
- /**
- * Returns the SHA-1 digest of the data passed throught the stream
- * @return SHA-1 digest
- */
- protected byte[] getDigestSHA() {
- synchronized (sha) {
- int len = (read_pos_end > write_pos)
- ? read_pos_end
- : write_pos;
- sha.update(buffer, 0, len);
- return sha.digest();
- }
- }
-
- /**
- * Returns the MD5 digest of the data passed throught the stream
- * except last message
- * @return MD5 digest
- */
- protected byte[] getDigestMD5withoutLast() {
- synchronized (md5) {
- md5.update(buffer, 0, marked_pos);
- return md5.digest();
- }
- }
-
- /**
- * Returns the SHA-1 digest of the data passed throught the stream
- * except last message
- * @return SHA-1 digest
- */
- protected byte[] getDigestSHAwithoutLast() {
- synchronized (sha) {
- sha.update(buffer, 0, marked_pos);
- return sha.digest();
- }
- }
-
- /**
- * Returns all the data passed throught the stream
- * @return all the data passed throught the stream at the moment
- */
- protected byte[] getMessages() {
- int len = (read_pos_end > write_pos) ? read_pos_end : write_pos;
- byte[] res = new byte[len];
- System.arraycopy(buffer, 0, res, 0, len);
- return res;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java b/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java
deleted file mode 100644
index 73d00ae..0000000
--- a/crypto/src/main/java/org/conscrypt/HandshakeProtocol.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.interfaces.RSAKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPublicKeySpec;
-import java.util.Arrays;
-import java.util.Vector;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- * Base class for ClientHandshakeImpl and ServerHandshakeImpl classes.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.
- * Handshake protocol</a>
- *
- */
-public abstract class HandshakeProtocol {
-
- /**
- * Handshake status NEED_UNWRAP - HandshakeProtocol needs to receive data
- */
- public static final int NEED_UNWRAP = 1;
-
- /**
- * Handshake status NOT_HANDSHAKING - is not currently handshaking
- */
- public static final int NOT_HANDSHAKING = 2;
-
- /**
- * Handshake status FINISHED - HandshakeProtocol has just finished
- */
- public static final int FINISHED = 3;
-
- /**
- * Handshake status NEED_TASK - HandshakeProtocol needs the results of delegated task
- */
- public static final int NEED_TASK = 4;
-
- /**
- * Current handshake status
- */
- protected int status = NOT_HANDSHAKING;
-
- /**
- * IO stream for income/outcome handshake data
- */
- protected HandshakeIODataStream io_stream = new HandshakeIODataStream();
-
- /**
- * SSL Record Protocol implementation.
- */
- protected SSLRecordProtocol recordProtocol;
-
- /**
- * SSLParametersImpl suplied by SSLSocket or SSLEngine
- */
- protected SSLParametersImpl parameters;
-
- /**
- * Delegated tasks for this handshake implementation
- */
- protected Vector<DelegatedTask> delegatedTasks = new Vector<DelegatedTask>();
-
- /**
- * Indicates non-blocking handshake
- */
- protected boolean nonBlocking;
-
- /**
- * Pending session
- */
- protected SSLSessionImpl session;
-
- /**
- * Sent and received handshake messages
- */
- protected ClientHello clientHello;
- protected ServerHello serverHello;
- protected CertificateMessage serverCert;
- protected ServerKeyExchange serverKeyExchange;
- protected CertificateRequest certificateRequest;
- protected ServerHelloDone serverHelloDone;
- protected CertificateMessage clientCert;
- protected ClientKeyExchange clientKeyExchange;
- protected CertificateVerify certificateVerify;
- protected Finished clientFinished;
- protected Finished serverFinished;
-
- /**
- * Indicates that change cipher spec message has been received
- */
- protected boolean changeCipherSpecReceived = false;
-
- /**
- * Indicates previous session resuming
- */
- protected boolean isResuming = false;
-
- /**
- * Premaster secret
- */
- protected byte[] preMasterSecret;
-
- /**
- * Exception occured in delegated task
- */
- protected Exception delegatedTaskErr;
-
- // reference verify_data used to verify finished message
- private byte[] verify_data = new byte[12];
-
- // Encoding of "master secret" string: "master secret".getBytes()
- private byte[] master_secret_bytes =
- {109, 97, 115, 116, 101, 114, 32, 115, 101, 99, 114, 101, 116 };
-
- // indicates whether protocol needs to send change cipher spec message
- private boolean needSendCCSpec = false;
-
- // indicates whether protocol needs to send change cipher spec message
- protected boolean needSendHelloRequest = false;
-
- /**
- * SSLEngine owning this HandshakeProtocol
- */
- public SSLEngineImpl engineOwner;
-
- /**
- * SSLSocket owning this HandshakeProtocol
- */
- public SSLSocketImpl socketOwner;
-
- /**
- * Creates HandshakeProtocol instance
- * @param owner
- */
- protected HandshakeProtocol(Object owner) {
- if (owner instanceof SSLEngineImpl) {
- engineOwner = (SSLEngineImpl) owner;
- nonBlocking = true;
- this.parameters = engineOwner.sslParameters;
- }
- else if (owner instanceof SSLSocketImpl) {
- socketOwner = (SSLSocketImpl) owner;
- nonBlocking = false;
- this.parameters = socketOwner.sslParameters;
- }
- }
-
- /**
- * Sets SSL Record Protocol
- * @param recordProtocol
- */
- public void setRecordProtocol(SSLRecordProtocol recordProtocol) {
- this.recordProtocol = recordProtocol;
- }
-
- /**
- * Start session negotiation
- */
- public abstract void start();
-
- /**
- * Stops the current session renegotiation process.
- * Such functionality is needed when it is session renegotiation
- * process and no_renegotiation alert message is received
- * from another peer.
- * @param session
- */
- protected void stop() {
- clearMessages();
- status = NOT_HANDSHAKING;
- }
-
- /**
- * Returns handshake status
- */
- public SSLEngineResult.HandshakeStatus getStatus() {
- if (io_stream.hasData() || needSendCCSpec ||
- needSendHelloRequest || delegatedTaskErr != null) {
- return SSLEngineResult.HandshakeStatus.NEED_WRAP;
- }
- if (!delegatedTasks.isEmpty()) {
- return SSLEngineResult.HandshakeStatus.NEED_TASK;
- }
-
- switch (status) {
- case HandshakeProtocol.NEED_UNWRAP:
- return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
- case HandshakeProtocol.FINISHED:
- status = NOT_HANDSHAKING;
- clearMessages();
- return SSLEngineResult.HandshakeStatus.FINISHED;
- default: // HandshakeProtocol.NOT_HANDSHAKING:
- return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
- }
- }
-
- /**
- * Returns pending session
- * @return session
- */
- public SSLSessionImpl getSession() {
- return session;
- }
-
- protected void sendChangeCipherSpec() {
- needSendCCSpec = true;
- }
-
- protected void sendHelloRequest() {
- needSendHelloRequest = true;
- }
-
- /**
- * Proceses inbound ChangeCipherSpec message
- */
- abstract void receiveChangeCipherSpec();
-
- /**
- * Creates and sends finished message
- */
- abstract void makeFinished();
-
- /**
- * Proceses inbound handshake messages
- * @param bytes
- */
- public abstract void unwrap(byte[] bytes);
-
- /**
- * Processes SSLv2 Hello message
- * @param bytes
- */
- public abstract void unwrapSSLv2(byte[] bytes);
-
- /**
- * Processes outbound handshake messages
- */
- public byte[] wrap() {
- if (delegatedTaskErr != null) {
- // process error occured in delegated task
- Exception e = delegatedTaskErr;
- delegatedTaskErr = null;
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "Error occured in delegated task:" + e.getMessage(), e);
- }
- if (io_stream.hasData()) {
- return recordProtocol.wrap(ContentType.HANDSHAKE, io_stream);
- } else if (needSendCCSpec) {
- makeFinished();
- needSendCCSpec = false;
- return recordProtocol.getChangeCipherSpecMesage(getSession());
- } else if (needSendHelloRequest) {
- needSendHelloRequest = false;
- return recordProtocol.wrap(ContentType.HANDSHAKE,
- // hello request message
- // (see TLS v 1 specification:
- // http://www.ietf.org/rfc/rfc2246.txt)
- new byte[] {0, 0, 0, 0}, 0, 4);
- } else {
- return null; // nothing to send;
- }
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- */
- protected void sendWarningAlert(byte description) {
- recordProtocol.alert(AlertProtocol.WARNING, description);
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param reason
- */
- protected void fatalAlert(byte description, String reason) {
- throw new AlertException(description, new SSLHandshakeException(reason));
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param reason
- * @param cause
- */
- protected void fatalAlert(byte description, String reason, Exception cause) {
- throw new AlertException(description, new SSLException(reason, cause));
- }
-
- /**
- * Sends fatal alert, breaks execution
- *
- * @param description
- * @param cause
- */
- protected void fatalAlert(byte description, SSLException cause) {
- throw new AlertException(description, cause);
- }
-
- /**
- * Computers reference TLS verify_data that is used to verify finished message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS spec. 7.4.9. Finished</a>
- * @param label
- */
- protected void computerReferenceVerifyDataTLS(String label) {
- computerVerifyDataTLS(label, verify_data);
- }
-
- /**
- * Computer TLS verify_data
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS spec. 7.4.9. Finished</a>
- * @param label
- * @param buf
- */
- protected void computerVerifyDataTLS(String label, byte[] buf) {
- byte[] md5_digest = io_stream.getDigestMD5();
- byte[] sha_digest = io_stream.getDigestSHA();
-
- byte[] digest = new byte[md5_digest.length + sha_digest.length];
- System.arraycopy(md5_digest, 0, digest, 0, md5_digest.length);
- System.arraycopy(sha_digest, 0, digest, md5_digest.length,
- sha_digest.length);
- try {
- PRF.computePRF(buf, session.master_secret,
- label.getBytes(), digest);
- } catch (GeneralSecurityException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
- }
- }
-
- /**
- * Computer reference SSLv3 verify_data that is used to verify finished message
- * @see "SSLv3 spec. 7.6.9. Finished"
- * @param label
- */
- protected void computerReferenceVerifyDataSSLv3(byte[] sender) {
- verify_data = new byte[36];
- computerVerifyDataSSLv3(sender, verify_data);
- }
-
- /**
- * Computer SSLv3 verify_data
- * @see "SSLv3 spec. 7.6.9. Finished"
- * @param label
- * @param buf
- */
- protected void computerVerifyDataSSLv3(byte[] sender, byte[] buf) {
- MessageDigest md5;
- MessageDigest sha;
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR,
- "Could not initialize the Digest Algorithms.",
- e);
- return;
- }
- try {
- byte[] handshake_messages = io_stream.getMessages();
- md5.update(handshake_messages);
- md5.update(sender);
- md5.update(session.master_secret);
- byte[] b = md5.digest(SSLv3Constants.MD5pad1);
- md5.update(session.master_secret);
- md5.update(SSLv3Constants.MD5pad2);
- System.arraycopy(md5.digest(b), 0, buf, 0, 16);
-
- sha.update(handshake_messages);
- sha.update(sender);
- sha.update(session.master_secret);
- b = sha.digest(SSLv3Constants.SHApad1);
- sha.update(session.master_secret);
- sha.update(SSLv3Constants.SHApad2);
- System.arraycopy(sha.digest(b), 0, buf, 16, 20);
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
-
- }
- }
-
- /**
- * Verifies finished data
- *
- * @param data
- * @param isServer
- */
- protected void verifyFinished(byte[] data) {
- if (!Arrays.equals(verify_data, data)) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Incorrect FINISED");
- }
- }
-
- /**
- * Sends fatal alert "UNEXPECTED MESSAGE"
- *
- */
- protected void unexpectedMessage() {
- fatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, "UNEXPECTED MESSAGE");
- }
-
- /**
- * Writes message to HandshakeIODataStream
- *
- * @param message
- */
- public void send(Message message) {
- io_stream.writeUint8(message.getType());
- io_stream.writeUint24(message.length());
- message.send(io_stream);
- }
-
- /**
- * Computers master secret
- *
- */
- public void computerMasterSecret() {
- byte[] seed = new byte[64];
- System.arraycopy(clientHello.getRandom(), 0, seed, 0, 32);
- System.arraycopy(serverHello.getRandom(), 0, seed, 32, 32);
- session.master_secret = new byte[48];
- if (serverHello.server_version[1] == 1) { // TLSv1
- try {
- PRF.computePRF(session.master_secret, preMasterSecret,
- master_secret_bytes, seed);
- } catch (GeneralSecurityException e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "PRF error", e);
- }
- } else { // SSL3.0
- PRF.computePRF_SSLv3(session.master_secret, preMasterSecret, seed);
- }
-
- //delete preMasterSecret from memory
- Arrays.fill(preMasterSecret, (byte)0);
- preMasterSecret = null;
- }
-
- /**
- * Returns a delegated task.
- * @return Delegated task or null
- */
- public Runnable getTask() {
- if (delegatedTasks.isEmpty()) {
- return null;
- }
- return delegatedTasks.remove(0);
- }
-
- /**
- * Clears previously sent and received handshake messages
- */
- protected void clearMessages() {
- io_stream.clearBuffer();
- clientHello = null;
- serverHello = null;
- serverCert = null;
- serverKeyExchange = null;
- certificateRequest = null;
- serverHelloDone = null;
- clientCert = null;
- clientKeyExchange = null;
- certificateVerify = null;
- clientFinished = null;
- serverFinished = null;
- }
-
- /**
- * Returns RSA key length
- * @param pk
- * @return
- * @throws NoSuchAlgorithmException
- * @throws InvalidKeySpecException
- */
- protected static int getRSAKeyLength(PublicKey pk)
- throws NoSuchAlgorithmException, InvalidKeySpecException {
-
- BigInteger mod;
- if (pk instanceof RSAKey) {
- mod = ((RSAKey) pk).getModulus();
- } else {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- mod = kf.getKeySpec(pk, RSAPublicKeySpec.class)
- .getModulus();
- }
- return mod.bitLength();
- }
-
- /**
- * Shuts down the protocol. It will be impossible to use the instance
- * after calling this method.
- */
- protected void shutdown() {
- clearMessages();
- session = null;
- preMasterSecret = null;
- delegatedTasks.clear();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/HelloRequest.java b/crypto/src/main/java/org/conscrypt/HelloRequest.java
deleted file mode 100644
index 20efbfd..0000000
--- a/crypto/src/main/java/org/conscrypt/HelloRequest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents Hello Request message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.1.
- * Hello request</a>
- *
- */
-public class HelloRequest extends Message {
-
- /**
- * Creates outbound message
- *
- */
- public HelloRequest() {
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public HelloRequest(HandshakeIODataStream in, int length)
- throws IOException {
- if (length != 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect HelloRequest");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- }
-
- @Override
- public int length() {
- return 0;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.HELLO_REQUEST;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/JSSEProvider.java b/crypto/src/main/java/org/conscrypt/JSSEProvider.java
deleted file mode 100644
index ad56976..0000000
--- a/crypto/src/main/java/org/conscrypt/JSSEProvider.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-
-/**
- * JSSE Provider implementation.
- *
- * This implementation is based on TLS v 1.0 and SSL v3 protocol specifications.
- *
- * <ul>
- * <li><a href="http://www.ietf.org/rfc/rfc2246.txt">TLS v 1.0 Protocol
- * specification</a></li>
- * <li><a href="http://wp.netscape.com/eng/ssl3">SSL v3 Protocol
- * specification</a></li>
- * </ul>
- *
- * Provider implementation supports the following cipher suites:
- * TLS_NULL_WITH_NULL_NULL
- * TLS_RSA_WITH_NULL_MD5
- * TLS_RSA_WITH_NULL_SHA
- * TLS_RSA_EXPORT_WITH_RC4_40_MD5
- * TLS_RSA_WITH_RC4_128_MD5
- * TLS_RSA_WITH_RC4_128_SHA
- * TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
- * TLS_RSA_WITH_IDEA_CBC_SHA
- * TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_RSA_WITH_DES_CBC_SHA
- * TLS_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_DSS_WITH_DES_CBC_SHA
- * TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_RSA_WITH_DES_CBC_SHA
- * TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DHE_DSS_WITH_DES_CBC_SHA
- * TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
- * TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DHE_RSA_WITH_DES_CBC_SHA
- * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- * TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
- * TLS_DH_anon_WITH_RC4_128_MD5
- * TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
- * TLS_DH_anon_WITH_DES_CBC_SHA
- * TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
- *
- * The real set of available cipher suites depends on set of available
- * crypto algorithms. These algorithms must be provided by some crypto
- * provider.
- *
- * The following cipher algorithms are used by different cipher suites:
- * IDEA/CBC/NoPadding
- * RC2/CBC/NoPadding
- * RC4
- * DES/CBC/NoPadding
- * DES/CBC/NoPadding
- * DESede/CBC/NoPadding
- *
- * Also the current JSSE provider implementation uses the following
- * crypto algorithms:
- *
- * Algorithms that MUST be provided by crypto provider:
- * Mac HmacMD5
- * Mac HmacSHA1
- * MessageDigest MD5
- * MessageDigest SHA-1
- * CertificateFactory X509
- *
- * The cipher suites with RSA key exchange may also require:
- * Cipher RSA
- * KeyPairGenerator RSA
- * KeyFactory RSA
- *
- * The cipher suites with DH key exchange may also require:
- * Signature NONEwithDSA
- * KeyPairGenerator DiffieHellman or DH
- * KeyFactory DiffieHellman or DH
- * KeyAgreement DiffieHellman or DH
- * KeyPairGenerator DiffieHellman or DH
- *
- * Trust manager implementation requires:
- * CertPathValidator PKIX
- * CertificateFactory X509
- *
- */
-public final class JSSEProvider extends Provider {
-
- private static final long serialVersionUID = 3075686092260669675L;
-
- public JSSEProvider() {
- super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
-
- put("SSLContext.SSL", SSLContextImpl.class.getName());
- put("SSLContext.SSLv3", SSLContextImpl.class.getName());
- put("SSLContext.TLS", SSLContextImpl.class.getName());
- put("SSLContext.TLSv1", SSLContextImpl.class.getName());
-
- put("KeyManagerFactory.PKIX", KeyManagerFactoryImpl.class.getName());
- put("Alg.Alias.KeyManagerFactory.X509", "PKIX");
-
- put("TrustManagerFactory.PKIX", TrustManagerFactoryImpl.class.getName());
- put("Alg.Alias.TrustManagerFactory.X509", "PKIX");
-
- put("KeyStore.AndroidCAStore", TrustedCertificateKeyStoreSpi.class.getName());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java b/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java
deleted file mode 100644
index 3ad9be9..0000000
--- a/crypto/src/main/java/org/conscrypt/KeyManagerFactoryImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactorySpi;
-import javax.net.ssl.ManagerFactoryParameters;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * KeyManagerFactory implementation.
- * @see KeyManagerFactorySpi
- */
-public class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
-
- // source of key material
- private KeyStore keyStore;
-
- //password
- private char[] pwd;
-
- /**
- * @see KeyManagerFactorySpi#engineInit(KeyStore ks, char[] password)
- */
- @Override
- protected void engineInit(KeyStore ks, char[] password)
- throws KeyStoreException, NoSuchAlgorithmException,
- UnrecoverableKeyException {
- if (ks != null) {
- keyStore = ks;
- if (password != null) {
- pwd = password.clone();
- } else {
- pwd = EmptyArray.CHAR;
- }
- } else {
- keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
- String keyStoreName = System.getProperty("javax.net.ssl.keyStore");
- String keyStorePwd = null;
- if (keyStoreName == null || keyStoreName.equalsIgnoreCase("NONE") || keyStoreName.isEmpty()) {
- try {
- keyStore.load(null, null);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- }
- } else {
- keyStorePwd = System.getProperty("javax.net.ssl.keyStorePassword");
- if (keyStorePwd == null) {
- pwd = EmptyArray.CHAR;
- } else {
- pwd = keyStorePwd.toCharArray();
- }
- try {
- keyStore.load(new FileInputStream(new File(keyStoreName)), pwd);
- } catch (FileNotFoundException e) {
- throw new KeyStoreException(e);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- }
- }
-
- }
-
- }
-
- /**
- * @see KeyManagerFactorySpi#engineInit(ManagerFactoryParameters spec)
- */
- @Override
- protected void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- throw new InvalidAlgorithmParameterException(
- "ManagerFactoryParameters not supported");
-
- }
-
- /**
- * @see KeyManagerFactorySpi#engineGetKeyManagers()
- */
- @Override
- protected KeyManager[] engineGetKeyManagers() {
- if (keyStore == null) {
- throw new IllegalStateException("KeyManagerFactory is not initialized");
- }
- return new KeyManager[] { new KeyManagerImpl(keyStore, pwd) };
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java b/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java
deleted file mode 100644
index 7a6c92c..0000000
--- a/crypto/src/main/java/org/conscrypt/KeyManagerImpl.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.net.Socket;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.UnrecoverableEntryException;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Locale;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * KeyManager implementation.
- *
- * This implementation uses hashed key store information. It works faster than retrieving all of the
- * data from the key store. Any key store changes, that happen after key manager was created, have
- * no effect. The implementation does not use peer information (host, port) that may be obtained
- * from socket or engine.
- *
- * @see javax.net.ssl.KeyManager
- *
- */
-public class KeyManagerImpl extends X509ExtendedKeyManager {
-
- // hashed key store information
- private final Hashtable<String, PrivateKeyEntry> hash;
-
- /**
- * Creates Key manager
- *
- * @param keyStore
- * @param pwd
- */
- public KeyManagerImpl(KeyStore keyStore, char[] pwd) {
- this.hash = new Hashtable<String, PrivateKeyEntry>();
- final Enumeration<String> aliases;
- try {
- aliases = keyStore.aliases();
- } catch (KeyStoreException e) {
- return;
- }
- for (; aliases.hasMoreElements();) {
- final String alias = aliases.nextElement();
- try {
- if (keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
- final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore
- .getEntry(alias, new KeyStore.PasswordProtection(pwd));
- hash.put(alias, entry);
- }
- } catch (KeyStoreException e) {
- continue;
- } catch (UnrecoverableEntryException e) {
- continue;
- } catch (NoSuchAlgorithmException e) {
- continue;
- }
- }
- }
-
- public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
- final String[] al = chooseAlias(keyTypes, issuers);
- return (al == null ? null : al[0]);
- }
-
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- final String[] al = chooseAlias(new String[] { keyType }, issuers);
- return (al == null ? null : al[0]);
- }
-
- public X509Certificate[] getCertificateChain(String alias) {
- if (alias == null) {
- return null;
- }
- if (hash.containsKey(alias)) {
- Certificate[] certs = hash.get(alias).getCertificateChain();
- if (certs[0] instanceof X509Certificate) {
- X509Certificate[] xcerts = new X509Certificate[certs.length];
- for (int i = 0; i < certs.length; i++) {
- xcerts[i] = (X509Certificate) certs[i];
- }
- return xcerts;
- }
- }
- return null;
-
- }
-
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- return chooseAlias(new String[] { keyType }, issuers);
- }
-
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- return chooseAlias(new String[] { keyType }, issuers);
- }
-
- public PrivateKey getPrivateKey(String alias) {
- if (alias == null) {
- return null;
- }
- if (hash.containsKey(alias)) {
- return hash.get(alias).getPrivateKey();
- }
- return null;
- }
-
- @Override
- public String chooseEngineClientAlias(String[] keyTypes, Principal[] issuers, SSLEngine engine) {
- final String[] al = chooseAlias(keyTypes, issuers);
- return (al == null ? null : al[0]);
- }
-
- @Override
- public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
- final String[] al = chooseAlias(new String[] { keyType }, issuers);
- return (al == null ? null : al[0]);
- }
-
- private String[] chooseAlias(String[] keyTypes, Principal[] issuers) {
- if (keyTypes == null || keyTypes.length == 0) {
- return null;
- }
- List<Principal> issuersList = (issuers == null) ? null : Arrays.asList(issuers);
- ArrayList<String> found = new ArrayList<String>();
- for (Enumeration<String> aliases = hash.keys(); aliases.hasMoreElements();) {
- final String alias = aliases.nextElement();
- final KeyStore.PrivateKeyEntry entry = hash.get(alias);
- final Certificate[] chain = entry.getCertificateChain();
- final Certificate cert = chain[0];
- final String certKeyAlg = cert.getPublicKey().getAlgorithm();
- final String certSigAlg = (cert instanceof X509Certificate
- ? ((X509Certificate) cert).getSigAlgName().toUpperCase(Locale.US)
- : null);
- for (String keyAlgorithm : keyTypes) {
- if (keyAlgorithm == null) {
- continue;
- }
- final String sigAlgorithm;
- // handle cases like EC_EC and EC_RSA
- int index = keyAlgorithm.indexOf('_');
- if (index == -1) {
- sigAlgorithm = null;
- } else {
- sigAlgorithm = keyAlgorithm.substring(index + 1);
- keyAlgorithm = keyAlgorithm.substring(0, index);
- }
- // key algorithm does not match
- if (!certKeyAlg.equals(keyAlgorithm)) {
- continue;
- }
- /*
- * TODO find a more reliable test for signature
- * algorithm. Unfortunately value varies with
- * provider. For example for "EC" it could be
- * "SHA1WithECDSA" or simply "ECDSA".
- */
- // sig algorithm does not match
- if (sigAlgorithm != null && certSigAlg != null
- && !certSigAlg.contains(sigAlgorithm)) {
- continue;
- }
- // no issuers to match, just add to return list and continue
- if (issuers == null || issuers.length == 0) {
- found.add(alias);
- continue;
- }
- // check that a certificate in the chain was issued by one of the specified issuers
- for (Certificate certFromChain : chain) {
- if (!(certFromChain instanceof X509Certificate)) {
- // skip non-X509Certificates
- continue;
- }
- X509Certificate xcertFromChain = (X509Certificate) certFromChain;
- /*
- * Note use of X500Principal from
- * getIssuerX500Principal as opposed to Principal
- * from getIssuerDN. Principal.equals test does
- * not work in the case where
- * xcertFromChain.getIssuerDN is a bouncycastle
- * org.bouncycastle.jce.X509Principal.
- */
- X500Principal issuerFromChain = xcertFromChain.getIssuerX500Principal();
- if (issuersList.contains(issuerFromChain)) {
- found.add(alias);
- }
- }
- }
- }
- if (!found.isEmpty()) {
- return found.toArray(new String[found.size()]);
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Logger.java b/crypto/src/main/java/org/conscrypt/Logger.java
deleted file mode 100644
index 9241c8a..0000000
--- a/crypto/src/main/java/org/conscrypt/Logger.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.PrintStream;
-import java.util.Locale;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * This class provides debug logging for JSSE provider implementation
- * TODO: Use java.util.logging
- */
-public class Logger {
-
- public static class Stream extends PrintStream {
- private final String prefix;
- private static int indent = 0;
-
- public Stream(String name) {
- super(System.err);
- prefix = name + "["+Thread.currentThread().getName()+"] ";
- }
-
- @Override
- public void print(String msg) {
- for (int i=0; i<indent; i++) {
- super.print(" ");
- }
- super.print(msg);
- }
-
- public void newIndent() {
- indent ++;
- }
-
- public void endIndent() {
- indent --;
- }
-
- @Override
- public void println(String msg) {
- print(prefix);
- super.println(msg);
- }
-
- public void print(byte[] data) {
- printAsHex(16, " ", "", data, 0, data.length);
- }
-
- public void print(byte[] data, int offset, int len) {
- printAsHex(16, " ", "", data, offset, len);
- }
-
- public void printAsHex(int perLine, String prefix, String delimiter, byte[] data) {
- printAsHex(perLine, prefix, delimiter, data, 0, data.length);
- }
-
- public void printAsHex(int perLine, String prefix, String delimiter,
- byte[] data, int offset, int len) {
- StringBuilder line = new StringBuilder();
- for (int i = 0; i < len; i++) {
- line.append(prefix);
- line.append(Byte.toHexString(data[i+offset], false));
- line.append(delimiter);
-
- if (((i+1)%perLine) == 0) {
- super.println(line.toString());
- line = new StringBuilder();
- }
- }
- super.println(line.toString());
- }
- }
-
- private static String[] names;
-
- static {
- try {
- names = System.getProperty("jsse", "").split(",");
- } catch (Exception e) {
- names = EmptyArray.STRING;
- }
- }
-
- public static Stream getStream(String name) {
- for (int i=0; i<names.length; i++) {
- if (names[i].equals(name)) {
- return new Stream(name);
- }
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/Message.java b/crypto/src/main/java/org/conscrypt/Message.java
deleted file mode 100644
index 3b932d0..0000000
--- a/crypto/src/main/java/org/conscrypt/Message.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-
-/**
- *
- * Base class for handshake messages
- */
-public abstract class Message {
-
- /*
- * Message length
- */
- protected int length;
-
- /**
- * Returns message type
- */
- abstract int getType();
-
- /**
- * Returns message length
- */
- public int length() {
- return length;
- }
-
- /**
- * Sends message
- * @param out
- */
- abstract void send(HandshakeIODataStream out);
-
- /**
- * Sends fatal alert
- * @param description
- * @param reason
- */
- protected void fatalAlert(byte description, String reason) {
- throw new AlertException(description, new SSLHandshakeException(reason));
- }
-
- /**
- * Sends fatal alert
- * @param description
- * @param reason
- * @param cause
- */
- protected void fatalAlert(byte description, String reason, Throwable cause) {
- throw new AlertException(description, new SSLException(reason, cause));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/NativeCrypto.java b/crypto/src/main/java/org/conscrypt/NativeCrypto.java
deleted file mode 100644
index f60e286..0000000
--- a/crypto/src/main/java/org/conscrypt/NativeCrypto.java
+++ /dev/null
@@ -1,1097 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.SocketTimeoutException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SignatureException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.net.ssl.SSLException;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Provides the Java side of our JNI glue for OpenSSL.
- */
-public final class NativeCrypto {
-
- // --- OpenSSL library initialization --------------------------------------
- static {
- /*
- * If we're compiled as part of Android, should use a different JNI
- * library name. Detect this by looking for the jarjar'd package name.
- */
- if ("com.android.org.conscrypt".equals(NativeCrypto.class.getPackage().getName())) {
- System.loadLibrary("javacrypto");
- } else {
- System.loadLibrary("conscrypt_jni");
- }
-
- clinit();
- }
-
- private native static void clinit();
-
- // --- ENGINE functions ----------------------------------------------------
- public static native void ENGINE_load_dynamic();
-
- public static native long ENGINE_by_id(String id);
-
- public static native int ENGINE_add(long e);
-
- public static native int ENGINE_init(long e);
-
- public static native int ENGINE_finish(long e);
-
- public static native int ENGINE_free(long e);
-
- public static native long ENGINE_load_private_key(long e, String key_id);
-
- public static native String ENGINE_get_id(long engineRef);
-
- public static native int ENGINE_ctrl_cmd_string(long engineRef, String cmd, String arg,
- int cmd_optional);
-
- // --- DSA/RSA public/private key handling functions -----------------------
-
- public static native long EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
- byte[] pub_key, byte[] priv_key);
-
- public static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
- byte[] dmp1, byte[] dmq1, byte[] iqmp);
-
- public static native long EVP_PKEY_new_mac_key(int type, byte[] key);
-
- public static native int EVP_PKEY_size(long pkey);
-
- public static native int EVP_PKEY_type(long pkey);
-
- public static native String EVP_PKEY_print_public(long pkeyRef);
-
- public static native String EVP_PKEY_print_private(long pkeyRef);
-
- public static native void EVP_PKEY_free(long pkey);
-
- public static native int EVP_PKEY_cmp(long pkey1, long pkey2);
-
- public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(long pkey);
-
- public static native long d2i_PKCS8_PRIV_KEY_INFO(byte[] data);
-
- public static native byte[] i2d_PUBKEY(long pkey);
-
- public static native long d2i_PUBKEY(byte[] data);
-
- public static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
-
- public static native int RSA_size(long pkey);
-
- public static native int RSA_private_encrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding);
-
- public static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding) throws BadPaddingException, SignatureException;
-
- public static native int RSA_public_encrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding);
-
- public static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, long pkey,
- int padding) throws BadPaddingException, SignatureException;
-
- /**
- * @return array of {n, e}
- */
- public static native byte[][] get_RSA_public_params(long rsa);
-
- /**
- * @return array of {n, e, d, p, q, dmp1, dmq1, iqmp}
- */
- public static native byte[][] get_RSA_private_params(long rsa);
-
- public static native long DSA_generate_key(int primeBits, byte[] seed, byte[] g, byte[] p,
- byte[] q);
-
- /**
- * @return array of {g, p, q, y(pub), x(priv)}
- */
- public static native byte[][] get_DSA_params(long dsa);
-
- public static native byte[] i2d_RSAPublicKey(long rsa);
-
- public static native byte[] i2d_RSAPrivateKey(long rsa);
-
- public static native byte[] i2d_DSAPublicKey(long dsa);
-
- public static native byte[] i2d_DSAPrivateKey(long dsa);
-
- // --- EC functions --------------------------
-
- /**
- * Used to request EC_GROUP_new_curve_GFp to EC_GROUP_new_curve
- */
- public static final int EC_CURVE_GFP = 1;
-
- /**
- * Used to request EC_GROUP_new_curve_GF2m to EC_GROUP_new_curve
- */
- public static final int EC_CURVE_GF2M = 2;
-
- /**
- * EC_GROUP_set_asn1_flag: indicates an EC_GROUP is a NamedCurve.
- */
- public static final int OPENSSL_EC_NAMED_CURVE = 0x001;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates compressed ASN.1 format
- */
- public static final int POINT_CONVERSION_COMPRESSED = 2;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates uncompressed ASN.1 format
- */
- public static final int POINT_CONVERSION_UNCOMPRESSED = 4;
-
- /**
- * EC_GROUP_set_point_conversion_form: indicates hybrid ASN.1 format
- */
- public static final int POINT_CONVERSION_HYBRID = 4;
-
- public static native long EVP_PKEY_new_EC_KEY(long groupRef, long pubkeyRef, byte[] privkey);
-
- public static native long EC_GROUP_new_by_curve_name(String curveName);
-
- public static native long EC_GROUP_new_curve(int type, byte[] p, byte[] a, byte[] b);
-
- public static native long EC_GROUP_dup(long groupRef);
-
- public static native void EC_GROUP_set_asn1_flag(long groupRef, int flag);
-
- public static native void EC_GROUP_set_point_conversion_form(long groupRef, int form);
-
- public static native String EC_GROUP_get_curve_name(long groupRef);
-
- public static native byte[][] EC_GROUP_get_curve(long groupRef);
-
- public static native void EC_GROUP_clear_free(long ctx);
-
- public static native boolean EC_GROUP_cmp(long ctx1, long ctx2);
-
- public static native void EC_GROUP_set_generator(long groupCtx, long pointCtx, byte[] n, byte[] h);
-
- public static native long EC_GROUP_get_generator(long groupCtx);
-
- public static native int get_EC_GROUP_type(long groupCtx);
-
- public static native byte[] EC_GROUP_get_order(long groupCtx);
-
- public static native int EC_GROUP_get_degree(long groupCtx);
-
- public static native byte[] EC_GROUP_get_cofactor(long groupCtx);
-
- public static native long EC_POINT_new(long groupRef);
-
- public static native void EC_POINT_clear_free(long pointRef);
-
- public static native boolean EC_POINT_cmp(long groupRef, long pointRef1, long pointRef2);
-
- public static native byte[][] EC_POINT_get_affine_coordinates(long groupCtx, long pointCtx);
-
- public static native void EC_POINT_set_affine_coordinates(long groupCtx, long pointCtx, byte[] x,
- byte[] y);
-
- public static native long EC_KEY_generate_key(long groupRef);
-
- public static native long EC_KEY_get0_group(long pkeyRef);
-
- public static native byte[] EC_KEY_get_private_key(long keyRef);
-
- public static native long EC_KEY_get_public_key(long keyRef);
-
- public static native int ECDH_compute_key(
- byte[] out, int outOffset, long publicKeyRef, long privateKeyRef);
-
- // --- Message digest functions --------------
-
- public static native long EVP_get_digestbyname(String name);
-
- public static native int EVP_MD_size(long evp_md);
-
- public static native int EVP_MD_block_size(long evp_md);
-
- // --- Message digest context functions --------------
-
- public static native long EVP_MD_CTX_create();
-
- public static native void EVP_MD_CTX_init(long ctx);
-
- public static native void EVP_MD_CTX_destroy(long ctx);
-
- public static native long EVP_MD_CTX_copy(long ctx);
-
- // --- Digest handling functions -------------------------------------------
-
- public static native long EVP_DigestInit(long evp_md);
-
- public static native void EVP_DigestUpdate(long ctx, byte[] buffer, int offset, int length);
-
- public static native int EVP_DigestFinal(long ctx, byte[] hash, int offset);
-
- // --- MAC handling functions ----------------------------------------------
-
- public static native void EVP_DigestSignInit(long evp_md_ctx, long evp_md, long evp_pkey);
-
- public static native void EVP_DigestSignUpdate(long evp_md_ctx, byte[] in);
-
- public static native byte[] EVP_DigestSignFinal(long evp_md_ctx);
-
- // --- Signature handling functions ----------------------------------------
-
- public static native long EVP_SignInit(String algorithm);
-
- public static native void EVP_SignUpdate(long ctx, byte[] buffer,
- int offset, int length);
-
- public static native int EVP_SignFinal(long ctx, byte[] signature, int offset, long key);
-
- public static native long EVP_VerifyInit(String algorithm);
-
- public static native void EVP_VerifyUpdate(long ctx, byte[] buffer,
- int offset, int length);
-
- public static native int EVP_VerifyFinal(long ctx, byte[] signature,
- int offset, int length, long key);
-
-
- // --- Block ciphers -------------------------------------------------------
-
- public static native long EVP_get_cipherbyname(String string);
-
- public static native void EVP_CipherInit_ex(long ctx, long evpCipher, byte[] key, byte[] iv,
- boolean encrypting);
-
- public static native int EVP_CipherUpdate(long ctx, byte[] out, int outOffset, byte[] in,
- int inOffset, int inLength);
-
- public static native int EVP_CipherFinal_ex(long ctx, byte[] out, int outOffset)
- throws BadPaddingException, IllegalBlockSizeException;
-
- public static native int EVP_CIPHER_iv_length(long evpCipher);
-
- public static native long EVP_CIPHER_CTX_new();
-
- public static native int EVP_CIPHER_CTX_block_size(long ctx);
-
- public static native int get_EVP_CIPHER_CTX_buf_len(long ctx);
-
- public static native void EVP_CIPHER_CTX_set_padding(long ctx, boolean enablePadding);
-
- public static native void EVP_CIPHER_CTX_set_key_length(long ctx, int keyBitSize);
-
- public static native void EVP_CIPHER_CTX_cleanup(long ctx);
-
- // --- RAND seeding --------------------------------------------------------
-
- public static final int RAND_SEED_LENGTH_IN_BYTES = 1024;
-
- public static native void RAND_seed(byte[] seed);
-
- public static native int RAND_load_file(String filename, long max_bytes);
-
- public static native void RAND_bytes(byte[] output);
-
- // --- ASN.1 objects -------------------------------------------------------
-
- public static native int OBJ_txt2nid(String oid);
-
- public static native String OBJ_txt2nid_longName(String oid);
-
- public static native String OBJ_txt2nid_oid(String oid);
-
- // --- X509_NAME -----------------------------------------------------------
-
- public static int X509_NAME_hash(X500Principal principal) {
- return X509_NAME_hash(principal, "SHA1");
- }
- public static int X509_NAME_hash_old(X500Principal principal) {
- return X509_NAME_hash(principal, "MD5");
- }
- private static int X509_NAME_hash(X500Principal principal, String algorithm) {
- try {
- byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
- int offset = 0;
- return (((digest[offset++] & 0xff) << 0) |
- ((digest[offset++] & 0xff) << 8) |
- ((digest[offset++] & 0xff) << 16) |
- ((digest[offset ] & 0xff) << 24));
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-
- public static native String X509_NAME_print_ex(long x509nameCtx, long flags);
-
- // --- X509 ----------------------------------------------------------------
-
- /** Used to request get_X509_GENERAL_NAME_stack get the "altname" field. */
- public static final int GN_STACK_SUBJECT_ALT_NAME = 1;
-
- /**
- * Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName
- * extension.
- */
- public static final int GN_STACK_ISSUER_ALT_NAME = 2;
-
- /**
- * Used to request only non-critical types in get_X509*_ext_oids.
- */
- public static final int EXTENSION_TYPE_NON_CRITICAL = 0;
-
- /**
- * Used to request only critical types in get_X509*_ext_oids.
- */
- public static final int EXTENSION_TYPE_CRITICAL = 1;
-
- public static native long d2i_X509_bio(long bioCtx);
-
- public static native long d2i_X509(byte[] encoded);
-
- public static native long PEM_read_bio_X509(long bioCtx);
-
- public static native byte[] i2d_X509(long x509ctx);
-
- /** Takes an X509 context not an X509_PUBKEY context. */
- public static native byte[] i2d_X509_PUBKEY(long x509ctx);
-
- public static native byte[] ASN1_seq_pack_X509(long[] x509CertRefs);
-
- public static native long[] ASN1_seq_unpack_X509_bio(long bioRef);
-
- public static native void X509_free(long x509ctx);
-
- public static native int X509_cmp(long x509ctx1, long x509ctx2);
-
- public static native int get_X509_hashCode(long x509ctx);
-
- public static native void X509_print_ex(long bioCtx, long x509ctx, long nmflag, long certflag);
-
- public static native byte[] X509_get_issuer_name(long x509ctx);
-
- public static native byte[] X509_get_subject_name(long x509ctx);
-
- public static native String get_X509_sig_alg_oid(long x509ctx);
-
- public static native byte[] get_X509_sig_alg_parameter(long x509ctx);
-
- public static native boolean[] get_X509_issuerUID(long x509ctx);
-
- public static native boolean[] get_X509_subjectUID(long x509ctx);
-
- public static native long X509_get_pubkey(long x509ctx) throws NoSuchAlgorithmException;
-
- public static native String get_X509_pubkey_oid(long x509ctx);
-
- public static native byte[] X509_get_ext_oid(long x509ctx, String oid);
-
- public static native String[] get_X509_ext_oids(long x509ctx, int critical);
-
- public static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, int type)
- throws CertificateParsingException;
-
- public static native boolean[] get_X509_ex_kusage(long x509ctx);
-
- public static native String[] get_X509_ex_xkusage(long x509ctx);
-
- public static native int get_X509_ex_pathlen(long x509ctx);
-
- public static native long X509_get_notBefore(long x509ctx);
-
- public static native long X509_get_notAfter(long x509ctx);
-
- public static native long X509_get_version(long x509ctx);
-
- public static native byte[] X509_get_serialNumber(long x509ctx);
-
- public static native void X509_verify(long x509ctx, long pkeyCtx);
-
- public static native byte[] get_X509_cert_info_enc(long x509ctx);
-
- public static native byte[] get_X509_signature(long x509ctx);
-
- public static native int get_X509_ex_flags(long x509ctx);
-
- public static native int X509_check_issued(long ctx, long ctx2);
-
- // --- X509 EXFLAG ---------------------------------------------------------
-
- public static final int EXFLAG_CA = 0x10;
-
- public static final int EXFLAG_CRITICAL = 0x200;
-
- // --- PKCS7 ---------------------------------------------------------------
-
- /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
- public static final int PKCS7_CERTS = 1;
-
- /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
- public static final int PKCS7_CRLS = 2;
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native long[] d2i_PKCS7_bio(long bioCtx, int which);
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native byte[] i2d_PKCS7(long[] certs);
-
- /** Returns an array of X509 or X509_CRL pointers. */
- public static native long[] PEM_read_bio_PKCS7(long bioCtx, int which);
-
- // --- X509_CRL ------------------------------------------------------------
-
- public static native long d2i_X509_CRL_bio(long bioCtx);
-
- public static native long PEM_read_bio_X509_CRL(long bioCtx);
-
- public static native byte[] i2d_X509_CRL(long x509CrlCtx);
-
- public static native void X509_CRL_free(long x509CrlCtx);
-
- public static native void X509_CRL_print(long bioCtx, long x509CrlCtx);
-
- public static native String get_X509_CRL_sig_alg_oid(long x509CrlCtx);
-
- public static native byte[] get_X509_CRL_sig_alg_parameter(long x509CrlCtx);
-
- public static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx);
-
- /** Returns X509_REVOKED reference that is not duplicated! */
- public static native long X509_CRL_get0_by_cert(long x509CrlCtx, long x509Ctx);
-
- /** Returns X509_REVOKED reference that is not duplicated! */
- public static native long X509_CRL_get0_by_serial(long x509CrlCtx, byte[] serial);
-
- /** Returns an array of X509_REVOKED that are owned by the caller. */
- public static native long[] X509_CRL_get_REVOKED(long x509CrlCtx);
-
- public static native String[] get_X509_CRL_ext_oids(long x509ctx, int critical);
-
- public static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, String oid);
-
- public static native long X509_CRL_get_version(long x509CrlCtx);
-
- public static native long X509_CRL_get_ext(long x509CrlCtx, String oid);
-
- public static native byte[] get_X509_CRL_signature(long x509ctx);
-
- public static native void X509_CRL_verify(long x509CrlCtx, long pkeyCtx);
-
- public static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx);
-
- public static native long X509_CRL_get_lastUpdate(long x509CrlCtx);
-
- public static native long X509_CRL_get_nextUpdate(long x509CrlCtx);
-
- // --- X509_REVOKED --------------------------------------------------------
-
- public static native long X509_REVOKED_dup(long x509RevokedCtx);
-
- public static native byte[] i2d_X509_REVOKED(long x509RevokedCtx);
-
- public static native String[] get_X509_REVOKED_ext_oids(long x509ctx, int critical);
-
- public static native byte[] X509_REVOKED_get_ext_oid(long x509RevokedCtx, String oid);
-
- public static native byte[] X509_REVOKED_get_serialNumber(long x509RevokedCtx);
-
- public static native long X509_REVOKED_get_ext(long x509RevokedCtx, String oid);
-
- /** Returns ASN1_TIME reference. */
- public static native long get_X509_REVOKED_revocationDate(long x509RevokedCtx);
-
- public static native void X509_REVOKED_print(long bioRef, long x509RevokedCtx);
-
- // --- X509_EXTENSION ------------------------------------------------------
-
- public static native int X509_supported_extension(long x509ExtensionRef);
-
- // --- ASN1_TIME -----------------------------------------------------------
-
- public static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal);
-
- // --- BIO stream creation -------------------------------------------------
-
- public static native long create_BIO_InputStream(OpenSSLBIOInputStream is);
-
- public static native long create_BIO_OutputStream(OutputStream os);
-
- public static native int BIO_read(long bioRef, byte[] buffer);
-
- public static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
- throws IOException;
-
- public static native void BIO_free(long bioRef);
-
- // --- SSL handling --------------------------------------------------------
-
- private static final String SUPPORTED_PROTOCOL_SSLV3 = "SSLv3";
- private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
- private static final String SUPPORTED_PROTOCOL_TLSV1_1 = "TLSv1.1";
- private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
-
- public static final Map<String, String> OPENSSL_TO_STANDARD_CIPHER_SUITES
- = new HashMap<String, String>();
- public static final Map<String, String> STANDARD_TO_OPENSSL_CIPHER_SUITES
- = new LinkedHashMap<String, String>();
-
- private static void add(String standard, String openssl) {
- OPENSSL_TO_STANDARD_CIPHER_SUITES.put(openssl, standard);
- STANDARD_TO_OPENSSL_CIPHER_SUITES.put(standard, openssl);
- }
-
- /**
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation
- * indication signaling cipher suite value. It is not a real
- * cipher suite. It is just an indication in the default and
- * supported cipher suite lists indicates that the implementation
- * supports secure renegotiation.
- *
- * In the RI, its presence means that the SCSV is sent in the
- * cipher suite list to indicate secure renegotiation support and
- * its absense means to send an empty TLS renegotiation info
- * extension instead.
- *
- * However, OpenSSL doesn't provide an API to give this level of
- * control, instead always sending the SCSV and always including
- * the empty renegotiation info if TLS is used (as opposed to
- * SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to
- * be passed for compatibility as to provide the hint that we
- * support secure renegotiation.
- */
- public static final String TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
-
- /**
- * TLS_FALLBACK_SCSV is from
- * https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
- * to indicate to the server that this is a fallback protocol
- * request.
- */
- public static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";
-
- static {
- // Note these are added in priority order
- add("SSL_RSA_WITH_RC4_128_MD5", "RC4-MD5");
- add("SSL_RSA_WITH_RC4_128_SHA", "RC4-SHA");
- add("TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA");
- add("TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA");
- add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA");
- add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA");
- add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA");
- add("TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA");
- add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA");
- add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA");
- add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA");
- add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA");
- add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA");
- add("TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA");
- add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA");
- add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA");
- add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA");
- add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA");
- add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA");
- add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA");
- add("SSL_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA");
- add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA");
- add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA");
- add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA");
- add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA");
- add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA");
- add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA");
- add("SSL_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA");
- add("SSL_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA");
- add("SSL_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-DES-CBC-SHA");
- add("SSL_RSA_EXPORT_WITH_RC4_40_MD5", "EXP-RC4-MD5");
- add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DES-CBC-SHA");
- add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA");
- add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA");
- add("SSL_RSA_WITH_NULL_MD5", "NULL-MD5");
- add("SSL_RSA_WITH_NULL_SHA", "NULL-SHA");
- add("TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA");
- add("TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA");
- add("TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA");
- add("TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA");
- add("SSL_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5");
- add("TLS_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA");
- add("TLS_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA");
- add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA");
- add("SSL_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA");
- add("TLS_ECDH_anon_WITH_RC4_128_SHA", "AECDH-RC4-SHA");
- add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA");
- add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA");
- add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "AECDH-DES-CBC3-SHA");
- add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5");
- add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA");
- add("TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA");
-
- // No Kerberos in Android
- // add("TLS_KRB5_WITH_RC4_128_SHA", "KRB5-RC4-SHA");
- // add("TLS_KRB5_WITH_RC4_128_MD5", "KRB5-RC4-MD5");
- // add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "KRB5-DES-CBC3-SHA");
- // add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "KRB5-DES-CBC3-MD5");
- // add("TLS_KRB5_WITH_DES_CBC_SHA", "KRB5-DES-CBC-SHA");
- // add("TLS_KRB5_WITH_DES_CBC_MD5", "KRB5-DES-CBC-MD5");
- // add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "EXP-KRB5-RC4-SHA");
- // add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "EXP-KRB5-RC4-MD5");
- // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "EXP-KRB5-DES-CBC-SHA");
- // add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "EXP-KRB5-DES-CBC-MD5");
-
- // not implemented by either RI or OpenSSL
- // add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", null);
- // add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", null);
-
- // EXPORT1024 suites were never standardized but were widely implemented.
- // OpenSSL 0.9.8c and later have disabled TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
- // add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", "EXP1024-DES-CBC-SHA");
- // add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", "EXP1024-RC4-SHA");
-
- // No RC2
- // add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-RC2-CBC-MD5");
- // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", "EXP-KRB5-RC2-CBC-SHA");
- // add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", "EXP-KRB5-RC2-CBC-MD5");
-
- // PSK is Private Shared Key - didn't exist in Froyo's openssl - no JSSE equivalent
- // add(null, "PSK-3DES-EDE-CBC-SHA");
- // add(null, "PSK-AES128-CBC-SHA");
- // add(null, "PSK-AES256-CBC-SHA");
- // add(null, "PSK-RC4-SHA");
-
- // Signaling Cipher Suite Value for secure renegotiation handled as special case.
- // add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", null);
-
- // Similarly, the fallback SCSV is handled as a special case.
- // add("TLS_FALLBACK_SCSV", null);
- }
-
- private static final String[] SUPPORTED_CIPHER_SUITES;
- static {
- int size = STANDARD_TO_OPENSSL_CIPHER_SUITES.size();
- SUPPORTED_CIPHER_SUITES = new String[size + 2];
- STANDARD_TO_OPENSSL_CIPHER_SUITES.keySet().toArray(SUPPORTED_CIPHER_SUITES);
- SUPPORTED_CIPHER_SUITES[size] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
- SUPPORTED_CIPHER_SUITES[size + 1] = TLS_FALLBACK_SCSV;
- }
-
- // EVP_PKEY types from evp.h and objects.h
- public static final int EVP_PKEY_RSA = 6; // NID_rsaEcnryption
- public static final int EVP_PKEY_DSA = 116; // NID_dsa
- public static final int EVP_PKEY_DH = 28; // NID_dhKeyAgreement
- public static final int EVP_PKEY_EC = 408; // NID_X9_62_id_ecPublicKey
- public static final int EVP_PKEY_HMAC = 855; // NID_hmac
- public static final int EVP_PKEY_CMAC = 894; // NID_cmac
-
- // RSA padding modes from rsa.h
- public static final int RSA_PKCS1_PADDING = 1;
- public static final int RSA_NO_PADDING = 3;
-
- // SSL mode from ssl.h
- public static final long SSL_MODE_HANDSHAKE_CUTTHROUGH = 0x00000020L;
- public static final long SSL_MODE_SEND_FALLBACK_SCSV = 0x00000200L;
-
- // SSL options from ssl.h
- public static final long SSL_OP_NO_TICKET = 0x00004000L;
- public static final long SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000L;
- public static final long SSL_OP_NO_SSLv3 = 0x02000000L;
- public static final long SSL_OP_NO_TLSv1 = 0x04000000L;
- public static final long SSL_OP_NO_TLSv1_1 = 0x10000000L;
- public static final long SSL_OP_NO_TLSv1_2 = 0x08000000L;
-
- public static native long SSL_CTX_new();
-
- public static String[] getDefaultCipherSuites() {
- return new String[] {
- "SSL_RSA_WITH_RC4_128_MD5",
- "SSL_RSA_WITH_RC4_128_SHA",
- "TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_RSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDH_RSA_WITH_RC4_128_SHA",
- "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
- "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
- "SSL_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_RSA_WITH_DES_CBC_SHA",
- "SSL_DHE_DSS_WITH_DES_CBC_SHA",
- "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
- "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
- "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
- TLS_EMPTY_RENEGOTIATION_INFO_SCSV
- };
- }
-
- public static String[] getSupportedCipherSuites() {
- return SUPPORTED_CIPHER_SUITES.clone();
- }
-
- public static native void SSL_CTX_free(long ssl_ctx);
-
- public static native void SSL_CTX_set_session_id_context(long ssl_ctx, byte[] sid_ctx);
-
- public static native long SSL_new(long ssl_ctx) throws SSLException;
-
- public static native void SSL_enable_tls_channel_id(long ssl) throws SSLException;
-
- public static native byte[] SSL_get_tls_channel_id(long ssl) throws SSLException;
-
- public static native void SSL_set1_tls_channel_id(long ssl, long pkey);
-
- public static byte[][] encodeCertificates(Certificate[] certificates)
- throws CertificateEncodingException {
- byte[][] certificateBytes = new byte[certificates.length][];
- for (int i = 0; i < certificates.length; i++) {
- certificateBytes[i] = certificates[i].getEncoded();
- }
- return certificateBytes;
- }
-
- public static native void SSL_use_certificate(long ssl, byte[][] asn1DerEncodedCertificateChain);
-
- public static native void SSL_use_PrivateKey(long ssl, long pkey);
-
- public static native void SSL_check_private_key(long ssl) throws SSLException;
-
- public static native void SSL_set_client_CA_list(long ssl, byte[][] asn1DerEncodedX500Principals);
-
- public static native long SSL_get_mode(long ssl);
-
- public static native long SSL_set_mode(long ssl, long mode);
-
- public static native long SSL_clear_mode(long ssl, long mode);
-
- public static native long SSL_get_options(long ssl);
-
- public static native long SSL_set_options(long ssl, long options);
-
- public static native long SSL_clear_options(long ssl, long options);
-
- public static String[] getDefaultProtocols() {
- return new String[] { SUPPORTED_PROTOCOL_SSLV3,
- SUPPORTED_PROTOCOL_TLSV1,
- };
- }
-
- public static String[] getSupportedProtocols() {
- return new String[] { SUPPORTED_PROTOCOL_SSLV3,
- SUPPORTED_PROTOCOL_TLSV1,
- SUPPORTED_PROTOCOL_TLSV1_1,
- SUPPORTED_PROTOCOL_TLSV1_2,
- };
- }
-
- public static void setEnabledProtocols(long ssl, String[] protocols) {
- checkEnabledProtocols(protocols);
- // openssl uses negative logic letting you disable protocols.
- // so first, assume we need to set all (disable all) and clear none (enable none).
- // in the loop, selectively move bits from set to clear (from disable to enable)
- long optionsToSet = (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
- long optionsToClear = 0;
- for (int i = 0; i < protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol.equals(SUPPORTED_PROTOCOL_SSLV3)) {
- optionsToSet &= ~SSL_OP_NO_SSLv3;
- optionsToClear |= SSL_OP_NO_SSLv3;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1;
- optionsToClear |= SSL_OP_NO_TLSv1;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1_1;
- optionsToClear |= SSL_OP_NO_TLSv1_1;
- } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)) {
- optionsToSet &= ~SSL_OP_NO_TLSv1_2;
- optionsToClear |= SSL_OP_NO_TLSv1_2;
- } else {
- // error checked by checkEnabledProtocols
- throw new IllegalStateException();
- }
- }
-
- SSL_set_options(ssl, optionsToSet);
- SSL_clear_options(ssl, optionsToClear);
- }
-
- public static String[] checkEnabledProtocols(String[] protocols) {
- if (protocols == null) {
- throw new IllegalArgumentException("protocols == null");
- }
- for (int i = 0; i < protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol == null) {
- throw new IllegalArgumentException("protocols[" + i + "] == null");
- }
- if ((!protocol.equals(SUPPORTED_PROTOCOL_SSLV3))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2))) {
- throw new IllegalArgumentException("protocol " + protocol
- + " is not supported");
- }
- }
- return protocols;
- }
-
- public static native void SSL_set_cipher_lists(long ssl, String[] ciphers);
-
- public static void setEnabledCipherSuites(long ssl, String[] cipherSuites) {
- checkEnabledCipherSuites(cipherSuites);
- List<String> opensslSuites = new ArrayList<String>();
- for (int i = 0; i < cipherSuites.length; i++) {
- String cipherSuite = cipherSuites[i];
- if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
- continue;
- }
- if (cipherSuite.equals(TLS_FALLBACK_SCSV)) {
- SSL_set_mode(ssl, SSL_MODE_SEND_FALLBACK_SCSV);
- continue;
- }
- String openssl = STANDARD_TO_OPENSSL_CIPHER_SUITES.get(cipherSuite);
- String cs = (openssl == null) ? cipherSuite : openssl;
- opensslSuites.add(cs);
- }
- SSL_set_cipher_lists(ssl, opensslSuites.toArray(new String[opensslSuites.size()]));
- }
-
- public static String[] checkEnabledCipherSuites(String[] cipherSuites) {
- if (cipherSuites == null) {
- throw new IllegalArgumentException("cipherSuites == null");
- }
- // makes sure all suites are valid, throwing on error
- for (int i = 0; i < cipherSuites.length; i++) {
- String cipherSuite = cipherSuites[i];
- if (cipherSuite == null) {
- throw new IllegalArgumentException("cipherSuites[" + i + "] == null");
- }
- if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV) ||
- cipherSuite.equals(TLS_FALLBACK_SCSV)) {
- continue;
- }
- if (STANDARD_TO_OPENSSL_CIPHER_SUITES.containsKey(cipherSuite)) {
- continue;
- }
- if (OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(cipherSuite)) {
- // TODO log warning about using backward compatability
- continue;
- }
- throw new IllegalArgumentException("cipherSuite " + cipherSuite + " is not supported.");
- }
- return cipherSuites;
- }
-
- /*
- * See the OpenSSL ssl.h header file for more information.
- */
- public static final int SSL_VERIFY_NONE = 0x00;
- public static final int SSL_VERIFY_PEER = 0x01;
- public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02;
-
- public static native void SSL_set_verify(long sslNativePointer, int mode);
-
- public static native void SSL_set_session(long sslNativePointer, long sslSessionNativePointer)
- throws SSLException;
-
- public static native void SSL_set_session_creation_enabled(
- long sslNativePointer, boolean creationEnabled) throws SSLException;
-
- public static native void SSL_set_tlsext_host_name(long sslNativePointer, String hostname)
- throws SSLException;
- public static native String SSL_get_servername(long sslNativePointer);
-
- /**
- * Enables NPN for all SSL connections in the context.
- *
- * <p>For clients this causes the NPN extension to be included in the
- * ClientHello message.
- *
- * <p>For servers this causes the NPN extension to be included in the
- * ServerHello message. The NPN extension will not be included in the
- * ServerHello response if the client didn't include it in the ClientHello
- * request.
- *
- * <p>In either case the caller should pass a non-null byte array of NPN
- * protocols to {@link #SSL_do_handshake}.
- */
- public static native void SSL_CTX_enable_npn(long sslCtxNativePointer);
-
- /**
- * Disables NPN for all SSL connections in the context.
- */
- public static native void SSL_CTX_disable_npn(long sslCtxNativePointer);
-
- /**
- * For clients, sets the list of supported ALPN protocols in wire-format
- * (length-prefixed 8-bit strings) on an SSL context.
- */
- public static native int SSL_CTX_set_alpn_protos(long sslCtxPointer, byte[] protos);
-
- /**
- * Returns the selected ALPN protocol. If the server did not select a
- * protocol, {@code null} will be returned.
- */
- public static native byte[] SSL_get0_alpn_selected(long sslPointer);
-
- /**
- * Returns the sslSessionNativePointer of the negotiated session. If this is
- * a server negotiation, supplying the {@code alpnProtocols} will enable
- * ALPN negotiation.
- */
- public static native int SSL_do_handshake(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- int timeoutMillis,
- boolean client_mode,
- byte[] npnProtocols,
- byte[] alpnProtocols)
- throws SSLException, SocketTimeoutException, CertificateException;
-
- public static native byte[] SSL_get_npn_negotiated_protocol(long sslNativePointer);
-
- /**
- * Currently only intended for forcing renegotiation for testing.
- * Not used within OpenSSLSocketImpl.
- */
- public static native void SSL_renegotiate(long sslNativePointer) throws SSLException;
-
- /**
- * Returns the local ASN.1 DER encoded X509 certificates.
- */
- public static native byte[][] SSL_get_certificate(long sslNativePointer);
-
- /**
- * Returns the peer ASN.1 DER encoded X509 certificates.
- */
- public static native byte[][] SSL_get_peer_cert_chain(long sslNativePointer);
-
- /**
- * Reads with the native SSL_read function from the encrypted data stream
- * @return -1 if error or the end of the stream is reached.
- */
- public static native int SSL_read(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- byte[] b, int off, int len, int readTimeoutMillis)
- throws IOException;
-
- /**
- * Writes with the native SSL_write function to the encrypted data stream.
- */
- public static native void SSL_write(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc,
- byte[] b, int off, int len, int writeTimeoutMillis)
- throws IOException;
-
- public static native void SSL_interrupt(long sslNativePointer);
- public static native void SSL_shutdown(long sslNativePointer,
- FileDescriptor fd,
- SSLHandshakeCallbacks shc) throws IOException;
-
- public static native void SSL_free(long sslNativePointer);
-
- public static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);
-
- public static native long SSL_SESSION_get_time(long sslSessionNativePointer);
-
- public static native String SSL_SESSION_get_version(long sslSessionNativePointer);
-
- public static native String SSL_SESSION_cipher(long sslSessionNativePointer);
-
- public static native void SSL_SESSION_free(long sslSessionNativePointer);
-
- public static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);
-
- public static native long d2i_SSL_SESSION(byte[] data);
-
- /**
- * A collection of callbacks from the native OpenSSL code that are
- * related to the SSL handshake initiated by SSL_do_handshake.
- */
- public interface SSLHandshakeCallbacks {
- /**
- * Verify that we trust the certificate chain is trusted.
- *
- * @param asn1DerEncodedCertificateChain A chain of ASN.1 DER encoded certificates
- * @param authMethod auth algorithm name
- *
- * @throws CertificateException if the certificate is untrusted
- */
- public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain, String authMethod)
- throws CertificateException;
-
- /**
- * Called on an SSL client when the server requests (or
- * requires a certificate). The client can respond by using
- * SSL_use_certificate and SSL_use_PrivateKey to set a
- * certificate if has an appropriate one available, similar to
- * how the server provides its certificate.
- *
- * @param keyTypes key types supported by the server,
- * convertible to strings with #keyType
- * @param asn1DerEncodedX500Principals CAs known to the server
- */
- public void clientCertificateRequested(byte[] keyTypes,
- byte[][] asn1DerEncodedX500Principals)
- throws CertificateEncodingException, SSLException;
-
- /**
- * Called when SSL handshake is completed. Note that this can
- * be after SSL_do_handshake returns when handshake cutthrough
- * is enabled.
- */
- public void handshakeCompleted();
- }
-
- public static native long ERR_peek_last_error();
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java b/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java
deleted file mode 100644
index 26971d5..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLBIOInputStream.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Provides an interface to OpenSSL's BIO system directly from a Java
- * InputStream. It allows an OpenSSL API to read directly from something more
- * flexible interface than a byte array.
- */
-public class OpenSSLBIOInputStream extends FilterInputStream {
- private long ctx;
-
- public OpenSSLBIOInputStream(InputStream is) {
- super(is);
-
- ctx = NativeCrypto.create_BIO_InputStream(this);
- }
-
- public long getBioContext() {
- return ctx;
- }
-
- /**
- * Similar to a {@code readLine} method, but matches what OpenSSL expects
- * from a {@code BIO_gets} method.
- */
- public int gets(byte[] buffer) throws IOException {
- if (buffer == null || buffer.length == 0) {
- return 0;
- }
-
- int offset = 0;
- int inputByte = 0;
- while (offset < buffer.length) {
- inputByte = read();
- if (inputByte == -1) {
- // EOF
- break;
- }
- if (inputByte == '\n') {
- if (offset == 0) {
- // If we haven't read anything yet, ignore CRLF.
- continue;
- } else {
- break;
- }
- }
-
- buffer[offset++] = (byte) inputByte;
- }
-
- return offset;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
deleted file mode 100644
index 7acccc7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipher.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-import org.conscrypt.util.EmptyArray;
-
-public abstract class OpenSSLCipher extends CipherSpi {
-
- /**
- * Modes that a block cipher may support.
- */
- protected static enum Mode {
- CBC,
- CFB, CFB1, CFB8, CFB128,
- CTR,
- CTS,
- ECB,
- OFB, OFB64, OFB128,
- PCBC,
- }
-
- /**
- * Paddings that a block cipher may support.
- */
- protected static enum Padding {
- NOPADDING,
- PKCS5PADDING,
- ISO10126PADDING,
- }
-
- /**
- * Native pointer for the OpenSSL EVP_CIPHER context.
- */
- private OpenSSLCipherContext cipherCtx = new OpenSSLCipherContext(
- NativeCrypto.EVP_CIPHER_CTX_new());
-
- /**
- * The current cipher mode.
- */
- private Mode mode = Mode.ECB;
-
- /**
- * The current cipher padding.
- */
- private Padding padding = Padding.PKCS5PADDING;
-
- /**
- * The Initial Vector (IV) used for the current cipher.
- */
- private byte[] iv;
-
- /**
- * Current cipher mode: encrypting or decrypting.
- */
- private boolean encrypting;
-
- /**
- * The block size of the current cipher.
- */
- private int blockSize;
-
- /**
- * The block size of the current mode.
- */
- private int modeBlockSize;
-
- /**
- * Whether the cipher has processed any data yet. OpenSSL doesn't like
- * calling "doFinal()" in decryption mode without processing any updates.
- */
- private boolean calledUpdate;
-
- protected OpenSSLCipher() {
- }
-
- protected OpenSSLCipher(Mode mode, Padding padding) {
- this.mode = mode;
- this.padding = padding;
- blockSize = getCipherBlockSize();
- }
-
- /**
- * Returns the standard name for the particular algorithm.
- */
- protected abstract String getBaseCipherName();
-
- /**
- * Returns the OpenSSL cipher name for the particular {@code keySize} and
- * cipher {@code mode}.
- */
- protected abstract String getCipherName(int keySize, Mode mode);
-
- /**
- * Checks whether the cipher supports this particular {@code keySize} (in
- * bytes) and throws {@code InvalidKeyException} if it doesn't.
- */
- protected abstract void checkSupportedKeySize(int keySize) throws InvalidKeyException;
-
- /**
- * Checks whether the cipher supports this particular cipher {@code mode}
- * and throws {@code NoSuchAlgorithmException} if it doesn't.
- */
- protected abstract void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException;
-
- /**
- * Checks whether the cipher supports this particular cipher {@code padding}
- * and throws {@code NoSuchPaddingException} if it doesn't.
- */
- protected abstract void checkSupportedPadding(Padding padding) throws NoSuchPaddingException;
-
- protected abstract int getCipherBlockSize();
-
- protected boolean supportsVariableSizeKey() {
- return false;
- }
-
- @Override
- protected void engineSetMode(String modeStr) throws NoSuchAlgorithmException {
- final Mode mode;
- try {
- mode = Mode.valueOf(modeStr.toUpperCase(Locale.US));
- } catch (IllegalArgumentException e) {
- NoSuchAlgorithmException newE = new NoSuchAlgorithmException("No such mode: "
- + modeStr);
- newE.initCause(e);
- throw newE;
- }
- checkSupportedMode(mode);
- this.mode = mode;
- }
-
- @Override
- protected void engineSetPadding(String paddingStr) throws NoSuchPaddingException {
- final String paddingStrUpper = paddingStr.toUpperCase(Locale.US);
- final Padding padding;
- try {
- padding = Padding.valueOf(paddingStrUpper);
- } catch (IllegalArgumentException e) {
- NoSuchPaddingException newE = new NoSuchPaddingException("No such padding: "
- + paddingStr);
- newE.initCause(e);
- throw newE;
- }
- checkSupportedPadding(padding);
- this.padding = padding;
- }
-
- @Override
- protected int engineGetBlockSize() {
- return blockSize;
- }
-
- /**
- * The size of output if {@code doFinal()} is called with this
- * {@code inputLen}. If padding is enabled and the size of the input puts it
- * right at the block size, it will add another block for the padding.
- */
- private int getOutputSize(int inputLen) {
- if (modeBlockSize == 1) {
- return inputLen;
- } else {
- final int buffered = NativeCrypto.get_EVP_CIPHER_CTX_buf_len(cipherCtx.getContext());
- if (padding == Padding.NOPADDING) {
- return buffered + inputLen;
- } else {
- final int totalLen = inputLen + buffered + modeBlockSize;
- return totalLen - (totalLen % modeBlockSize);
- }
- }
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- return getOutputSize(inputLen);
- }
-
- @Override
- protected byte[] engineGetIV() {
- return iv;
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- if (iv != null && iv.length > 0) {
- try {
- AlgorithmParameters params = AlgorithmParameters.getInstance(getBaseCipherName());
- params.init(iv);
- return params;
- } catch (NoSuchAlgorithmException e) {
- return null;
- } catch (IOException e) {
- return null;
- }
- }
- return null;
- }
-
- private void engineInitInternal(int opmode, Key key, byte[] iv, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
- encrypting = true;
- } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
- encrypting = false;
- } else {
- throw new InvalidParameterException("Unsupported opmode " + opmode);
- }
-
- if (!(key instanceof SecretKey)) {
- throw new InvalidKeyException("Only SecretKey is supported");
- }
-
- final byte[] encodedKey = key.getEncoded();
- if (encodedKey == null) {
- throw new InvalidKeyException("key.getEncoded() == null");
- }
-
- checkSupportedKeySize(encodedKey.length);
-
- final long cipherType = NativeCrypto.EVP_get_cipherbyname(getCipherName(encodedKey.length,
- mode));
- if (cipherType == 0) {
- throw new InvalidAlgorithmParameterException("Cannot find name for key length = "
- + (encodedKey.length * 8) + " and mode = " + mode);
- }
-
- final int ivLength = NativeCrypto.EVP_CIPHER_iv_length(cipherType);
- if (iv == null && ivLength != 0) {
- iv = new byte[ivLength];
- if (encrypting) {
- if (random == null) {
- random = new SecureRandom();
- }
- random.nextBytes(iv);
- }
- } else if (iv != null && iv.length != ivLength) {
- throw new InvalidAlgorithmParameterException("expected IV length of " + ivLength);
- }
-
- this.iv = iv;
-
- if (supportsVariableSizeKey()) {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), cipherType, null, null,
- encrypting);
- NativeCrypto.EVP_CIPHER_CTX_set_key_length(cipherCtx.getContext(), encodedKey.length);
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), 0, encodedKey, iv, encrypting);
- } else {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), cipherType, encodedKey, iv,
- encrypting);
- }
-
- // OpenSSL only supports PKCS5 Padding.
- NativeCrypto.EVP_CIPHER_CTX_set_padding(cipherCtx.getContext(),
- padding == Padding.PKCS5PADDING);
- modeBlockSize = NativeCrypto.EVP_CIPHER_CTX_block_size(cipherCtx.getContext());
- calledUpdate = false;
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- try {
- engineInitInternal(opmode, key, null, random);
- } catch (InvalidAlgorithmParameterException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- final byte[] iv;
- if (params instanceof IvParameterSpec) {
- IvParameterSpec ivParams = (IvParameterSpec) params;
- iv = ivParams.getIV();
- } else {
- iv = null;
- }
-
- engineInitInternal(opmode, key, iv, random);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- final AlgorithmParameterSpec spec;
- try {
- spec = params.getParameterSpec(IvParameterSpec.class);
- } catch (InvalidParameterSpecException e) {
- throw new InvalidAlgorithmParameterException(e);
- }
-
- engineInit(opmode, key, spec, random);
- }
-
- private final int updateInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset, int maximumLen) throws ShortBufferException {
- final int intialOutputOffset = outputOffset;
-
- final int bytesLeft = output.length - outputOffset;
- if (bytesLeft < maximumLen) {
- throw new ShortBufferException("output buffer too small during update: " + bytesLeft
- + " < " + maximumLen);
- }
-
- outputOffset += NativeCrypto.EVP_CipherUpdate(cipherCtx.getContext(), output, outputOffset,
- input, inputOffset, inputLen);
-
- calledUpdate = true;
-
- return outputOffset - intialOutputOffset;
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- final int maximumLen = getOutputSize(inputLen);
-
- /* See how large our output buffer would need to be. */
- final byte[] output;
- if (maximumLen > 0) {
- output = new byte[maximumLen];
- } else {
- output = EmptyArray.BYTE;
- }
-
- final int bytesWritten;
- try {
- bytesWritten = updateInternal(input, inputOffset, inputLen, output, 0, maximumLen);
- } catch (ShortBufferException e) {
- /* This shouldn't happen. */
- throw new RuntimeException("calculated buffer size was wrong: " + maximumLen);
- }
-
- if (output.length == bytesWritten) {
- return output;
- } else if (bytesWritten == 0) {
- return EmptyArray.BYTE;
- } else {
- return Arrays.copyOfRange(output, 0, bytesWritten);
- }
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- final int maximumLen = getOutputSize(inputLen);
- return updateInternal(input, inputOffset, inputLen, output, outputOffset, maximumLen);
- }
-
- /**
- * Reset this Cipher instance state to process a new chunk of data.
- */
- private void reset() {
- NativeCrypto.EVP_CipherInit_ex(cipherCtx.getContext(), 0, null, null, encrypting);
- calledUpdate = false;
- }
-
- private int doFinalInternal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset, int maximumLen) throws IllegalBlockSizeException,
- BadPaddingException, ShortBufferException {
- /* Remember this so we can tell how many characters were written. */
- final int initialOutputOffset = outputOffset;
-
- if (inputLen > 0) {
- final int updateBytesWritten = updateInternal(input, inputOffset, inputLen, output,
- outputOffset, maximumLen);
- outputOffset += updateBytesWritten;
- maximumLen -= updateBytesWritten;
- }
-
- /*
- * If we're decrypting and haven't had any input, we should return null.
- * Otherwise OpenSSL will complain if we call final.
- */
- if (!encrypting && !calledUpdate) {
- return 0;
- }
-
- /* Allow OpenSSL to pad if necessary and clean up state. */
- final int bytesLeft = output.length - outputOffset;
- final int writtenBytes;
- if (bytesLeft >= maximumLen) {
- writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx.getContext(), output,
- outputOffset);
- } else {
- final byte[] lastBlock = new byte[maximumLen];
- writtenBytes = NativeCrypto.EVP_CipherFinal_ex(cipherCtx.getContext(), lastBlock, 0);
- if (writtenBytes > bytesLeft) {
- throw new ShortBufferException("buffer is too short: " + writtenBytes + " > "
- + bytesLeft);
- } else if (writtenBytes > 0) {
- System.arraycopy(lastBlock, 0, output, outputOffset, writtenBytes);
- }
- }
- outputOffset += writtenBytes;
-
- reset();
-
- return outputOffset - initialOutputOffset;
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- /*
- * Other implementations return null if we've never called update()
- * while decrypting.
- */
- if (!encrypting && !calledUpdate && inputLen == 0) {
- reset();
- return null;
- }
-
- final int maximumLen = getOutputSize(inputLen);
- /* Assume that we'll output exactly on a byte boundary. */
- final byte[] output = new byte[maximumLen];
- final int bytesWritten;
- try {
- bytesWritten = doFinalInternal(input, inputOffset, inputLen, output, 0, maximumLen);
- } catch (ShortBufferException e) {
- /* This should not happen since we sized our own buffer. */
- throw new RuntimeException("our calculated buffer was too small", e);
- }
-
- if (bytesWritten == output.length) {
- return output;
- } else if (bytesWritten == 0) {
- return EmptyArray.BYTE;
- } else {
- return Arrays.copyOfRange(output, 0, bytesWritten);
- }
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- if (output == null) {
- throw new NullPointerException("output == null");
- }
-
- final int maximumLen = getOutputSize(inputLen);
- return doFinalInternal(input, inputOffset, inputLen, output, outputOffset, maximumLen);
- }
-
- @Override
- protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
- try {
- byte[] encoded = key.getEncoded();
- return engineDoFinal(encoded, 0, encoded.length);
- } catch (BadPaddingException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
-
- @Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
- throws InvalidKeyException, NoSuchAlgorithmException {
- try {
- byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- if (wrappedKeyType == Cipher.PUBLIC_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.SECRET_KEY) {
- return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
- } else {
- throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
- }
- } catch (IllegalBlockSizeException e) {
- throw new InvalidKeyException(e);
- } catch (BadPaddingException e) {
- throw new InvalidKeyException(e);
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public static class AES extends OpenSSLCipher {
- private static final int AES_BLOCK_SIZE = 16;
-
- protected AES(Mode mode, Padding padding) {
- super(mode, padding);
- }
-
- public static class CBC extends AES {
- public CBC(Padding padding) {
- super(Mode.CBC, padding);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CBC {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CFB extends AES {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CTR extends AES {
- public CTR(Padding padding) {
- super(Mode.CTR, padding);
- }
-
- public static class NoPadding extends CTR {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CTR {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class ECB extends AES {
- public ECB(Padding padding) {
- super(Mode.ECB, padding);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends ECB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class OFB extends AES {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- @Override
- protected void checkSupportedKeySize(int keyLength) throws InvalidKeyException {
- switch (keyLength) {
- case 16: // AES 128
- case 24: // AES 192
- case 32: // AES 256
- return;
- default:
- throw new InvalidKeyException("Unsupported key size: " + keyLength + " bytes");
- }
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- switch (mode) {
- case CBC:
- case CFB:
- case CFB1:
- case CFB8:
- case CFB128:
- case CTR:
- case ECB:
- case OFB:
- return;
- default:
- throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
- }
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- switch (padding) {
- case NOPADDING:
- case PKCS5PADDING:
- return;
- default:
- throw new NoSuchPaddingException("Unsupported padding " + padding.toString());
- }
- }
-
- @Override
- protected String getBaseCipherName() {
- return "AES";
- }
-
- @Override
- protected String getCipherName(int keyLength, Mode mode) {
- return "aes-" + (keyLength * 8) + "-" + mode.toString().toLowerCase(Locale.US);
- }
-
- @Override
- protected int getCipherBlockSize() {
- return AES_BLOCK_SIZE;
- }
- }
-
- public static class DESEDE extends OpenSSLCipher {
- private static int DES_BLOCK_SIZE = 8;
-
- public DESEDE(Mode mode, Padding padding) {
- super(mode, padding);
- }
-
- public static class CBC extends DESEDE {
- public CBC(Padding padding) {
- super(Mode.CBC, padding);
- }
-
- public static class NoPadding extends CBC {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CBC {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class CFB extends DESEDE {
- public CFB(Padding padding) {
- super(Mode.CFB, padding);
- }
-
- public static class NoPadding extends CFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends CFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class ECB extends DESEDE {
- public ECB(Padding padding) {
- super(Mode.ECB, padding);
- }
-
- public static class NoPadding extends ECB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends ECB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- public static class OFB extends DESEDE {
- public OFB(Padding padding) {
- super(Mode.OFB, padding);
- }
-
- public static class NoPadding extends OFB {
- public NoPadding() {
- super(Padding.NOPADDING);
- }
- }
-
- public static class PKCS5Padding extends OFB {
- public PKCS5Padding() {
- super(Padding.PKCS5PADDING);
- }
- }
- }
-
- @Override
- protected String getBaseCipherName() {
- return "DESede";
- }
-
- @Override
- protected String getCipherName(int keySize, Mode mode) {
- final String baseCipherName;
- if (keySize == 16) {
- baseCipherName = "des-ede";
- } else {
- baseCipherName = "des-ede3";
- }
-
- if (mode == Mode.ECB) {
- return baseCipherName;
- } else {
- return baseCipherName + "-" + mode.toString().toLowerCase(Locale.US);
- }
- }
-
- @Override
- protected void checkSupportedKeySize(int keySize) throws InvalidKeyException {
- if (keySize != 16 && keySize != 24) {
- throw new InvalidKeyException("key size must be 128 or 192 bits");
- }
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- switch (mode) {
- case CBC:
- case CFB:
- case CFB1:
- case CFB8:
- case ECB:
- case OFB:
- return;
- default:
- throw new NoSuchAlgorithmException("Unsupported mode " + mode.toString());
- }
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- switch (padding) {
- case NOPADDING:
- case PKCS5PADDING:
- return;
- default:
- throw new NoSuchPaddingException("Unsupported padding " + padding.toString());
- }
- }
-
- @Override
- protected int getCipherBlockSize() {
- return DES_BLOCK_SIZE;
- }
- }
-
- public static class ARC4 extends OpenSSLCipher {
- public ARC4() {
- }
-
- @Override
- protected String getBaseCipherName() {
- return "ARCFOUR";
- }
-
- @Override
- protected String getCipherName(int keySize, Mode mode) {
- return "rc4";
- }
-
- @Override
- protected void checkSupportedKeySize(int keySize) throws InvalidKeyException {
- }
-
- @Override
- protected void checkSupportedMode(Mode mode) throws NoSuchAlgorithmException {
- throw new NoSuchAlgorithmException("ARC4 does not support modes");
- }
-
- @Override
- protected void checkSupportedPadding(Padding padding) throws NoSuchPaddingException {
- throw new NoSuchPaddingException("ARC4 does not support padding");
- }
-
- @Override
- protected int getCipherBlockSize() {
- return 0;
- }
-
- @Override
- protected boolean supportsVariableSizeKey() {
- return true;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java
deleted file mode 100644
index ffbcad4..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipherContext.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-class OpenSSLCipherContext {
- private final long context;
-
- OpenSSLCipherContext(long ctx) {
- if (ctx == 0) {
- throw new NullPointerException("ctx == 0");
- }
-
- this.context = ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(context);
- } finally {
- super.finalize();
- }
- }
-
- long getContext() {
- return context;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java b/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java
deleted file mode 100644
index 9e2f426..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLCipherRSA.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.SignatureException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.CipherSpi;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-import org.conscrypt.util.EmptyArray;
-
-public abstract class OpenSSLCipherRSA extends CipherSpi {
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Current key type: private or public.
- */
- private boolean usingPrivateKey;
-
- /**
- * Current cipher mode: encrypting or decrypting.
- */
- private boolean encrypting;
-
- /**
- * Buffer for operations
- */
- private byte[] buffer;
-
- /**
- * Current offset in the buffer.
- */
- private int bufferOffset;
-
- /**
- * Flag that indicates an exception should be thrown when the input is too
- * large during doFinal.
- */
- private boolean inputTooLarge;
-
- /**
- * Current padding mode
- */
- private int padding = NativeCrypto.RSA_PKCS1_PADDING;
-
- protected OpenSSLCipherRSA(int padding) {
- this.padding = padding;
- }
-
- @Override
- protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
- final String modeUpper = mode.toUpperCase(Locale.ROOT);
- if ("NONE".equals(modeUpper) || "ECB".equals(modeUpper)) {
- return;
- }
-
- throw new NoSuchAlgorithmException("mode not supported: " + mode);
- }
-
- @Override
- protected void engineSetPadding(String padding) throws NoSuchPaddingException {
- final String paddingUpper = padding.toUpperCase(Locale.ROOT);
- if ("PKCS1PADDING".equals(paddingUpper)) {
- this.padding = NativeCrypto.RSA_PKCS1_PADDING;
- return;
- }
- if ("NOPADDING".equals(paddingUpper)) {
- this.padding = NativeCrypto.RSA_NO_PADDING;
- return;
- }
-
- throw new NoSuchPaddingException("padding not supported: " + padding);
- }
-
- @Override
- protected int engineGetBlockSize() {
- if (encrypting) {
- return paddedBlockSizeBytes();
- }
- return keySizeBytes();
- }
-
- @Override
- protected int engineGetOutputSize(int inputLen) {
- if (encrypting) {
- return keySizeBytes();
- }
- return paddedBlockSizeBytes();
- }
-
- private int paddedBlockSizeBytes() {
- int paddedBlockSizeBytes = keySizeBytes();
- if (padding == NativeCrypto.RSA_PKCS1_PADDING) {
- paddedBlockSizeBytes--; // for 0 prefix
- paddedBlockSizeBytes -= 10; // PKCS1 padding header length
- }
- return paddedBlockSizeBytes;
- }
-
- private int keySizeBytes() {
- if (key == null) {
- throw new IllegalStateException("cipher is not initialized");
- }
- return NativeCrypto.RSA_size(this.key.getPkeyContext());
- }
-
- @Override
- protected byte[] engineGetIV() {
- return null;
- }
-
- @Override
- protected AlgorithmParameters engineGetParameters() {
- return null;
- }
-
- private void engineInitInternal(int opmode, Key key) throws InvalidKeyException {
- if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) {
- encrypting = true;
- } else if (opmode == Cipher.DECRYPT_MODE || opmode == Cipher.UNWRAP_MODE) {
- encrypting = false;
- } else {
- throw new InvalidParameterException("Unsupported opmode " + opmode);
- }
-
- if (key instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) key;
- usingPrivateKey = true;
- this.key = rsaPrivateKey.getOpenSSLKey();
- } else if (key instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) key;
- usingPrivateKey = true;
- this.key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (key instanceof RSAPrivateKey) {
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) key;
- usingPrivateKey = true;
- this.key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else if (key instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) key;
- usingPrivateKey = false;
- this.key = rsaPublicKey.getOpenSSLKey();
- } else if (key instanceof RSAPublicKey) {
- RSAPublicKey rsaPublicKey = (RSAPublicKey) key;
- usingPrivateKey = false;
- this.key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else {
- throw new InvalidKeyException("Need RSA private or public key");
- }
-
- buffer = new byte[NativeCrypto.RSA_size(this.key.getPkeyContext())];
- inputTooLarge = false;
- }
-
- @Override
- protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown param type: "
- + params.getClass().getName());
- }
-
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
- throws InvalidKeyException, InvalidAlgorithmParameterException {
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown param type: "
- + params.getClass().getName());
- }
-
- engineInitInternal(opmode, key);
- }
-
- @Override
- protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
- if (bufferOffset + inputLen > buffer.length) {
- inputTooLarge = true;
- return EmptyArray.BYTE;
- }
-
- System.arraycopy(input, inputOffset, buffer, bufferOffset, inputLen);
- bufferOffset += inputLen;
- return EmptyArray.BYTE;
- }
-
- @Override
- protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException {
- engineUpdate(input, inputOffset, inputLen);
- return 0;
- }
-
- @Override
- protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen)
- throws IllegalBlockSizeException, BadPaddingException {
- if (input != null) {
- engineUpdate(input, inputOffset, inputLen);
- }
-
- if (inputTooLarge) {
- throw new IllegalBlockSizeException("input must be under " + buffer.length + " bytes");
- }
-
- final byte[] tmpBuf;
- if (bufferOffset != buffer.length) {
- if (padding == NativeCrypto.RSA_NO_PADDING) {
- tmpBuf = new byte[buffer.length];
- System.arraycopy(buffer, 0, tmpBuf, buffer.length - bufferOffset, bufferOffset);
- } else {
- tmpBuf = Arrays.copyOf(buffer, bufferOffset);
- }
- } else {
- tmpBuf = buffer;
- }
-
- byte[] output = new byte[buffer.length];
- int resultSize;
- if (encrypting) {
- if (usingPrivateKey) {
- resultSize = NativeCrypto.RSA_private_encrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- } else {
- resultSize = NativeCrypto.RSA_public_encrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- }
- } else {
- try {
- if (usingPrivateKey) {
- resultSize = NativeCrypto.RSA_private_decrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- } else {
- resultSize = NativeCrypto.RSA_public_decrypt(tmpBuf.length, tmpBuf, output,
- key.getPkeyContext(), padding);
- }
- } catch (SignatureException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
- if (!encrypting && resultSize != output.length) {
- output = Arrays.copyOf(output, resultSize);
- }
-
- bufferOffset = 0;
- return output;
- }
-
- @Override
- protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
- int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
- BadPaddingException {
- byte[] b = engineDoFinal(input, inputOffset, inputLen);
-
- final int lastOffset = outputOffset + b.length;
- if (lastOffset > output.length) {
- throw new ShortBufferException("output buffer is too small " + output.length + " < "
- + lastOffset);
- }
-
- System.arraycopy(b, 0, output, outputOffset, b.length);
- return b.length;
- }
-
- @Override
- protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException {
- try {
- byte[] encoded = key.getEncoded();
- return engineDoFinal(encoded, 0, encoded.length);
- } catch (BadPaddingException e) {
- IllegalBlockSizeException newE = new IllegalBlockSizeException();
- newE.initCause(e);
- throw newE;
- }
- }
-
- @Override
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
- int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException {
- try {
- byte[] encoded = engineDoFinal(wrappedKey, 0, wrappedKey.length);
- if (wrappedKeyType == Cipher.PUBLIC_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePublic(new X509EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.PRIVATE_KEY) {
- KeyFactory keyFactory = KeyFactory.getInstance(wrappedKeyAlgorithm);
- return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
- } else if (wrappedKeyType == Cipher.SECRET_KEY) {
- return new SecretKeySpec(encoded, wrappedKeyAlgorithm);
- } else {
- throw new UnsupportedOperationException("wrappedKeyType == " + wrappedKeyType);
- }
- } catch (IllegalBlockSizeException e) {
- throw new InvalidKeyException(e);
- } catch (BadPaddingException e) {
- throw new InvalidKeyException(e);
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public static class PKCS1 extends OpenSSLCipherRSA {
- public PKCS1() {
- super(NativeCrypto.RSA_PKCS1_PADDING);
- }
- }
-
- public static class Raw extends OpenSSLCipherRSA {
- public Raw() {
- super(NativeCrypto.RSA_NO_PADDING);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java
deleted file mode 100644
index 6b0e5f9..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLContextImpl.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * Overrides the original SSLContextImpl to provide OpenSSL-based
- * SSLSocketFactory and SSLServerSocketFactory instances.
- */
-public class OpenSSLContextImpl extends SSLContextImpl {
-
- public OpenSSLContextImpl() {}
-
- protected OpenSSLContextImpl(DefaultSSLContextImpl dummy)
- throws GeneralSecurityException, IOException {
- super(dummy);
- }
-
- @Override
- public SSLSocketFactory engineGetSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new OpenSSLSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLServerSocketFactory engineGetServerSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new OpenSSLServerSocketFactoryImpl(sslParameters);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java
deleted file mode 100644
index a9f7067..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyFactory.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLDSAKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof DSAPublicKeySpec) {
- return new OpenSSLDSAPublicKey((DSAPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_DSA);
- }
- throw new InvalidKeySpecException("Must use DSAPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof DSAPrivateKeySpec) {
- return new OpenSSLDSAPrivateKey((DSAPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_DSA);
- }
- throw new InvalidKeySpecException("Must use DSAPrivateKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"DSA".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be a DSA key");
- }
-
- if (key instanceof DSAPublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- DSAPublicKey dsaKey = (DSAPublicKey) key;
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PublicKey && DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- DSAPublicKey dsaKey =
- (DSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPublicKeySpec(dsaKey.getY(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof DSAPrivateKey
- && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- DSAPrivateKey dsaKey = (DSAPrivateKey) key;
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PrivateKey && DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- DSAPrivateKey dsaKey =
- (DSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- DSAParams params = dsaKey.getParams();
- return (T) new DSAPrivateKeySpec(dsaKey.getX(), params.getP(), params.getQ(),
- params.getG());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if ((key instanceof OpenSSLDSAPublicKey) || (key instanceof OpenSSLDSAPrivateKey)) {
- return key;
- } else if (key instanceof DSAPublicKey) {
- DSAPublicKey dsaKey = (DSAPublicKey) key;
-
- BigInteger y = dsaKey.getY();
-
- DSAParams params = dsaKey.getParams();
- BigInteger p = params.getP();
- BigInteger q = params.getQ();
- BigInteger g = params.getG();
-
- try {
- return engineGeneratePublic(new DSAPublicKeySpec(y, p, q, g));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof DSAPrivateKey) {
- DSAPrivateKey dsaKey = (DSAPrivateKey) key;
-
- BigInteger x = dsaKey.getX();
-
- DSAParams params = dsaKey.getParams();
- BigInteger p = params.getP();
- BigInteger q = params.getQ();
- BigInteger g = params.getG();
-
- try {
- return engineGeneratePrivate(new DSAPrivateKeySpec(x, p, q, g));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be DSA public or private key; was "
- + key.getClass().getName());
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java
deleted file mode 100644
index 3428fcc..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAKeyPairGenerator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGeneratorSpi;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
-
-public class OpenSSLDSAKeyPairGenerator extends KeyPairGeneratorSpi {
-
- private int primeBits = 1024;
-
- private SecureRandom random = null;
-
- private byte[] g;
-
- private byte[] p;
-
- private byte[] q;
-
- @Override
- public KeyPair generateKeyPair() {
- final byte[] seed;
- if (random == null) {
- seed = null;
- } else {
- seed = new byte[20];
- random.nextBytes(seed);
- }
-
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.DSA_generate_key(primeBits, seed, g, p,
- q));
-
- final OpenSSLDSAPrivateKey privKey = new OpenSSLDSAPrivateKey(key);
- final OpenSSLDSAPublicKey pubKey = new OpenSSLDSAPublicKey(key);
-
- return new KeyPair(pubKey, privKey);
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- primeBits = keysize;
- this.random = random;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- this.random = random;
-
- if (params instanceof DSAParameterSpec) {
- DSAParameterSpec dsaParams = (DSAParameterSpec) params;
-
- BigInteger gInt = dsaParams.getG();
- if (gInt != null) {
- g = gInt.toByteArray();
- }
-
- BigInteger pInt = dsaParams.getP();
- if (pInt != null) {
- p = pInt.toByteArray();
- }
-
- BigInteger qInt = dsaParams.getQ();
- if (qInt != null) {
- q = qInt.toByteArray();
- }
- } else if (params != null) {
- throw new InvalidAlgorithmParameterException("Params must be DSAParameterSpec");
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java
deleted file mode 100644
index fd0edf7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAParams.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.interfaces.DSAParams;
-import java.security.spec.AlgorithmParameterSpec;
-
-public class OpenSSLDSAParams implements DSAParams, AlgorithmParameterSpec {
-
- private OpenSSLKey key;
-
- private boolean fetchedParams;
-
- private BigInteger g;
-
- private BigInteger p;
-
- private BigInteger q;
-
- private BigInteger y;
-
- private BigInteger x;
-
- OpenSSLDSAParams(OpenSSLKey key) {
- this.key = key;
- }
-
- OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- private synchronized final void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
-
- byte[][] params = NativeCrypto.get_DSA_params(key.getPkeyContext());
- if (params[0] != null) {
- g = new BigInteger(params[0]);
- }
- if (params[1] != null) {
- p = new BigInteger(params[1]);
- }
- if (params[2] != null) {
- q = new BigInteger(params[2]);
- }
- if (params[3] != null) {
- y = new BigInteger(params[3]);
- }
- if (params[4] != null) {
- x = new BigInteger(params[4]);
- }
-
- fetchedParams = true;
- }
-
- @Override
- public BigInteger getG() {
- ensureReadParams();
- return g;
- }
-
- @Override
- public BigInteger getP() {
- ensureReadParams();
- return p;
- }
-
- @Override
- public BigInteger getQ() {
- ensureReadParams();
- return q;
- }
-
- boolean hasParams() {
- ensureReadParams();
- return (g != null) && (p != null) && (q != null);
- }
-
- BigInteger getY() {
- ensureReadParams();
- return y;
- }
-
- BigInteger getX() {
- ensureReadParams();
- return x;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAParams) {
- OpenSSLDSAParams other = (OpenSSLDSAParams) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key == other.getOpenSSLKey()) {
- return true;
- }
- }
-
- if (!(o instanceof DSAParams)) {
- return false;
- }
-
- ensureReadParams();
-
- DSAParams other = (DSAParams) o;
- return g.equals(other.getG()) && p.equals(other.getP()) && q.equals(other.getQ());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return g.hashCode() ^ p.hashCode() ^ q.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLDSAParams{");
- sb.append("G=");
- sb.append(g.toString(16));
- sb.append(",P=");
- sb.append(p.toString(16));
- sb.append(",Q=");
- sb.append(q.toString(16));
- sb.append('}');
-
- return sb.toString();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java
deleted file mode 100644
index 0fc4db7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPrivateKey.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-public class OpenSSLDSAPrivateKey implements DSAPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 6524734576187424628L;
-
- private transient OpenSSLKey key;
-
- private transient OpenSSLDSAParams params;
-
- OpenSSLDSAPrivateKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLDSAPrivateKey(DSAPrivateKeySpec dsaKeySpec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaKeySpec.getP().toByteArray(),
- dsaKeySpec.getQ().toByteArray(),
- dsaKeySpec.getG().toByteArray(),
- null,
- dsaKeySpec.getX().toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- private void ensureReadParams() {
- if (params == null) {
- params = new OpenSSLDSAParams(key);
- }
- }
-
- static OpenSSLKey getInstance(DSAPrivateKey dsaPrivateKey) throws InvalidKeyException {
- try {
- DSAParams dsaParams = dsaPrivateKey.getParams();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaParams.getP().toByteArray(),
- dsaParams.getQ().toByteArray(),
- dsaParams.getG().toByteArray(),
- null,
- dsaPrivateKey.getX().toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public DSAParams getParams() {
- ensureReadParams();
- return params;
- }
-
- @Override
- public String getAlgorithm() {
- return "DSA";
- }
-
- @Override
- public String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- @Override
- public BigInteger getX() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private key value X cannot be extracted");
- }
-
- ensureReadParams();
- return params.getX();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAPrivateKey) {
- OpenSSLDSAPrivateKey other = (OpenSSLDSAPrivateKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof DSAPrivateKey)) {
- return false;
- }
-
- ensureReadParams();
-
- final BigInteger x = params.getX();
- if (x == null) {
- /*
- * If our X is null, we can't tell if these two private keys are
- * equivalent. This usually happens if this key is ENGINE-based. If
- * the other key was ENGINE-based, we should have caught it in the
- * OpenSSLDSAPrivateKey case.
- */
- return false;
- }
-
- final DSAPrivateKey other = (DSAPrivateKey) o;
- return x.equals(other.getX()) && params.equals(other.getParams());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- int hash = 1;
-
- final BigInteger x = getX();
- if (x != null) {
- hash = hash * 3 + x.hashCode();
- }
-
- hash = hash * 7 + params.hashCode();
-
- return hash;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLDSAPrivateKey{");
-
- if (key.isEngineBased()) {
- sb.append("key=");
- sb.append(key);
- sb.append('}');
- return sb.toString();
- }
-
- ensureReadParams();
- sb.append("X=");
- sb.append(params.getX().toString(16));
- sb.append(',');
- sb.append("params=");
- sb.append(params.toString());
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- final BigInteger g = (BigInteger) stream.readObject();
- final BigInteger p = (BigInteger) stream.readObject();
- final BigInteger q = (BigInteger) stream.readObject();
- final BigInteger x = (BigInteger) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- p.toByteArray(),
- q.toByteArray(),
- g.toByteArray(),
- null,
- x.toByteArray()));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
-
- ensureReadParams();
- stream.writeObject(params.getG());
- stream.writeObject(params.getP());
- stream.writeObject(params.getQ());
- stream.writeObject(params.getX());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java
deleted file mode 100644
index 1c0bf74..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDSAPublicKey.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-
-public class OpenSSLDSAPublicKey implements DSAPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 5238609500353792232L;
-
- private transient OpenSSLKey key;
-
- private transient OpenSSLDSAParams params;
-
- OpenSSLDSAPublicKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLDSAPublicKey(DSAPublicKeySpec dsaKeySpec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaKeySpec.getP().toByteArray(),
- dsaKeySpec.getQ().toByteArray(),
- dsaKeySpec.getG().toByteArray(),
- dsaKeySpec.getY().toByteArray(),
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- private void ensureReadParams() {
- if (params == null) {
- params = new OpenSSLDSAParams(key);
- }
- }
-
- static OpenSSLKey getInstance(DSAPublicKey dsaPublicKey) throws InvalidKeyException {
- try {
- final DSAParams dsaParams = dsaPublicKey.getParams();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- dsaParams.getP().toByteArray(),
- dsaParams.getQ().toByteArray(),
- dsaParams.getG().toByteArray(),
- dsaPublicKey.getY().toByteArray(),
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public DSAParams getParams() {
- ensureReadParams();
-
- /*
- * DSA keys can lack parameters if they're part of a certificate
- * chain. In this case, we just return null.
- */
- if (!params.hasParams()) {
- return null;
- }
-
- return params;
- }
-
- @Override
- public String getAlgorithm() {
- return "DSA";
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- @Override
- public BigInteger getY() {
- ensureReadParams();
- return params.getY();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLDSAPublicKey) {
- OpenSSLDSAPublicKey other = (OpenSSLDSAPublicKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof DSAPublicKey)) {
- return false;
- }
-
- ensureReadParams();
-
- DSAPublicKey other = (DSAPublicKey) o;
- return params.getY().equals(other.getY()) && params.equals(other.getParams());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return params.getY().hashCode() ^ params.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLDSAPublicKey{");
- sb.append("Y=");
- sb.append(params.getY().toString(16));
- sb.append(',');
- sb.append("params=");
- sb.append(params.toString());
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- final BigInteger g = (BigInteger) stream.readObject();
- final BigInteger p = (BigInteger) stream.readObject();
- final BigInteger q = (BigInteger) stream.readObject();
- final BigInteger y = (BigInteger) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA(
- p.toByteArray(),
- q.toByteArray(),
- g.toByteArray(),
- y.toByteArray(),
- null));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
- stream.defaultWriteObject();
-
- ensureReadParams();
- stream.writeObject(params.getG());
- stream.writeObject(params.getP());
- stream.writeObject(params.getQ());
- stream.writeObject(params.getY());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java
deleted file mode 100644
index b11a862..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLDigestContext.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-public class OpenSSLDigestContext {
- private final long context;
-
- public OpenSSLDigestContext(long ctx) {
- if (ctx == 0) {
- throw new NullPointerException("ctx == 0");
- }
-
- this.context = ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.EVP_MD_CTX_destroy(context);
- } finally {
- super.finalize();
- }
- }
-
- long getContext() {
- return context;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java b/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java
deleted file mode 100644
index 0d8729c..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECDHKeyAgreement.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import javax.crypto.KeyAgreementSpi;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Elliptic Curve Diffie-Hellman key agreement backed by the OpenSSL engine.
- */
-public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi {
-
- /** OpenSSL handle of the private key. Only available after the engine has been initialized. */
- private OpenSSLKey mOpenSslPrivateKey;
-
- /**
- * Expected length (in bytes) of the agreed key ({@link #mResult}). Only available after the
- * engine has been initialized.
- */
- private int mExpectedResultLength;
-
- /** Agreed key. Only available after {@link #engineDoPhase(Key, boolean)} completes. */
- private byte[] mResult;
-
- @Override
- public Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException {
- if (mOpenSslPrivateKey == null) {
- throw new IllegalStateException("Not initialized");
- }
- if (!lastPhase) {
- throw new IllegalStateException("ECDH only has one phase");
- }
-
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if (!(key instanceof PublicKey)) {
- throw new InvalidKeyException("Not a public key: " + key.getClass());
- }
- OpenSSLKey openSslPublicKey = translateKeyToEcOpenSSLKey(key);
-
- byte[] buffer = new byte[mExpectedResultLength];
- int actualResultLength = NativeCrypto.ECDH_compute_key(
- buffer,
- 0,
- openSslPublicKey.getPkeyContext(),
- mOpenSslPrivateKey.getPkeyContext());
- byte[] result;
- if (actualResultLength == -1) {
- throw new RuntimeException("Engine returned " + actualResultLength);
- } else if (actualResultLength == mExpectedResultLength) {
- // The output is as long as expected -- use the whole buffer
- result = buffer;
- } else if (actualResultLength < mExpectedResultLength) {
- // The output is shorter than expected -- use only what's produced by the engine
- result = new byte[actualResultLength];
- System.arraycopy(buffer, 0, mResult, 0, mResult.length);
- } else {
- // The output is longer than expected
- throw new RuntimeException("Engine produced a longer than expected result. Expected: "
- + mExpectedResultLength + ", actual: " + actualResultLength);
- }
- mResult = result;
-
- return null; // No intermediate key
- }
-
- @Override
- protected int engineGenerateSecret(byte[] sharedSecret, int offset)
- throws ShortBufferException {
- checkCompleted();
- int available = sharedSecret.length - offset;
- if (mResult.length > available) {
- throw new ShortBufferException(
- "Needed: " + mResult.length + ", available: " + available);
- }
-
- System.arraycopy(mResult, 0, sharedSecret, offset, mResult.length);
- return mResult.length;
- }
-
- @Override
- protected byte[] engineGenerateSecret() {
- checkCompleted();
- return mResult;
- }
-
- @Override
- protected SecretKey engineGenerateSecret(String algorithm) {
- checkCompleted();
- return new SecretKeySpec(engineGenerateSecret(), algorithm);
- }
-
- @Override
- protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if (!(key instanceof PrivateKey)) {
- throw new InvalidKeyException("Not a private key: " + key.getClass());
- }
-
- OpenSSLKey openSslKey = translateKeyToEcOpenSSLKey(key);
- int fieldSizeBits = NativeCrypto.EC_GROUP_get_degree(NativeCrypto.EC_KEY_get0_group(
- openSslKey.getPkeyContext()));
- mExpectedResultLength = (fieldSizeBits + 7) / 8;
- mOpenSslPrivateKey = openSslKey;
- }
-
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params,
- SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
- // ECDH doesn't need an AlgorithmParameterSpec
- if (params != null) {
- throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
- }
- engineInit(key, random);
- }
-
- private void checkCompleted() {
- if (mResult == null) {
- throw new IllegalStateException("Key agreement not completed");
- }
- }
-
- private static OpenSSLKey translateKeyToEcOpenSSLKey(Key key) throws InvalidKeyException {
- try {
- return ((OpenSSLKeyHolder) KeyFactory.getInstance(
- "EC", OpenSSLProvider.PROVIDER_NAME).translateKey(key)).getOpenSSLKey();
- } catch (Exception e) {
- throw new InvalidKeyException("Failed to translate key to OpenSSL EC key", e);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java
deleted file mode 100644
index f7f52a6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECGroupContext.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidParameterException;
-import java.security.spec.ECField;
-import java.security.spec.ECFieldF2m;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.EllipticCurve;
-
-public final class OpenSSLECGroupContext {
- private final long groupCtx;
-
- public OpenSSLECGroupContext(long groupCtx) {
- this.groupCtx = groupCtx;
- }
-
- public static OpenSSLECGroupContext getCurveByName(String curveName) {
- // Workaround for OpenSSL not supporting SECG names for NIST P-192 and P-256
- // (aka ANSI X9.62 prime192v1 and prime256v1) curve names.
- if ("secp256r1".equals(curveName)) {
- curveName = "prime256v1";
- } else if ("secp192r1".equals(curveName)) {
- curveName = "prime192v1";
- }
-
- final long ctx = NativeCrypto.EC_GROUP_new_by_curve_name(curveName);
- if (ctx == 0) {
- return null;
- }
-
- NativeCrypto.EC_GROUP_set_point_conversion_form(ctx,
- NativeCrypto.POINT_CONVERSION_UNCOMPRESSED);
- NativeCrypto.EC_GROUP_set_asn1_flag(ctx, NativeCrypto.OPENSSL_EC_NAMED_CURVE);
-
- return new OpenSSLECGroupContext(ctx);
- }
-
- public static OpenSSLECGroupContext getInstance(int type, BigInteger p, BigInteger a,
- BigInteger b, BigInteger x, BigInteger y, BigInteger n, BigInteger h) {
- final long ctx = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(), a.toByteArray(),
- b.toByteArray());
- if (ctx == 0) {
- return null;
- }
-
- NativeCrypto.EC_GROUP_set_point_conversion_form(ctx,
- NativeCrypto.POINT_CONVERSION_UNCOMPRESSED);
-
- OpenSSLECGroupContext group = new OpenSSLECGroupContext(ctx);
-
- OpenSSLECPointContext generator = new OpenSSLECPointContext(group,
- NativeCrypto.EC_POINT_new(ctx));
-
- NativeCrypto.EC_POINT_set_affine_coordinates(ctx, generator.getContext(),
- x.toByteArray(), y.toByteArray());
-
- NativeCrypto.EC_GROUP_set_generator(ctx, generator.getContext(), n.toByteArray(),
- h.toByteArray());
-
- return group;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (groupCtx != 0) {
- NativeCrypto.EC_GROUP_clear_free(groupCtx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof OpenSSLECGroupContext)) {
- return false;
- }
-
- final OpenSSLECGroupContext other = (OpenSSLECGroupContext) o;
- return NativeCrypto.EC_GROUP_cmp(groupCtx, other.groupCtx);
- }
-
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return super.hashCode();
- }
-
- public long getContext() {
- return groupCtx;
- }
-
- public static OpenSSLECGroupContext getInstance(ECParameterSpec params)
- throws InvalidAlgorithmParameterException {
- final String curveName = params.getCurveName();
- if (curveName != null) {
- return OpenSSLECGroupContext.getCurveByName(curveName);
- }
-
- final EllipticCurve curve = params.getCurve();
- final ECField field = curve.getField();
-
- final int type;
- final BigInteger p;
- if (field instanceof ECFieldFp) {
- type = NativeCrypto.EC_CURVE_GFP;
- p = ((ECFieldFp) field).getP();
- } else if (field instanceof ECFieldF2m) {
- type = NativeCrypto.EC_CURVE_GF2M;
- p = ((ECFieldF2m) field).getReductionPolynomial();
- } else {
- throw new InvalidParameterException("unhandled field class "
- + field.getClass().getName());
- }
-
- final ECPoint generator = params.getGenerator();
- return OpenSSLECGroupContext.getInstance(type, p, curve.getA(), curve.getB(),
- generator.getAffineX(), generator.getAffineY(), params.getOrder(),
- BigInteger.valueOf(params.getCofactor()));
- }
-
- public ECParameterSpec getECParameterSpec() {
- final String curveName = NativeCrypto.EC_GROUP_get_curve_name(groupCtx);
-
- final byte[][] curveParams = NativeCrypto.EC_GROUP_get_curve(groupCtx);
- final BigInteger p = new BigInteger(curveParams[0]);
- final BigInteger a = new BigInteger(curveParams[1]);
- final BigInteger b = new BigInteger(curveParams[2]);
-
- final ECField field;
- final int type = NativeCrypto.get_EC_GROUP_type(groupCtx);
- if (type == NativeCrypto.EC_CURVE_GFP) {
- field = new ECFieldFp(p);
- } else if (type == NativeCrypto.EC_CURVE_GF2M) {
- field = new ECFieldF2m(p.bitLength() - 1, p);
- } else {
- throw new RuntimeException("unknown curve type " + type);
- }
-
- final EllipticCurve curve = new EllipticCurve(field, a, b);
-
- final OpenSSLECPointContext generatorCtx = new OpenSSLECPointContext(this,
- NativeCrypto.EC_GROUP_get_generator(groupCtx));
- final ECPoint generator = generatorCtx.getECPoint();
-
- final BigInteger order = new BigInteger(NativeCrypto.EC_GROUP_get_order(groupCtx));
- final BigInteger cofactor = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(groupCtx));
-
- return new ECParameterSpec(curve, generator, order, cofactor.intValue(), curveName);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java
deleted file mode 100644
index b39a611..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyFactory.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLECKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof ECPublicKeySpec) {
- return new OpenSSLECPublicKey((ECPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_EC);
- }
- throw new InvalidKeySpecException("Must use ECPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof ECPrivateKeySpec) {
- return new OpenSSLECPrivateKey((ECPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_EC);
- }
- throw new InvalidKeySpecException("Must use ECPrivateKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"EC".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be an EC key");
- }
-
- if (key instanceof ECPublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
- ECPublicKey ecKey = (ECPublicKey) key;
- return (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
- } else if (key instanceof PublicKey && ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- ECPublicKey ecKey = (ECPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- return (T) new ECPublicKeySpec(ecKey.getW(), ecKey.getParams());
- } else if (key instanceof ECPrivateKey
- && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- ECPrivateKey ecKey = (ECPrivateKey) key;
- return (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
- } else if (key instanceof PrivateKey && ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- ECPrivateKey ecKey =
- (ECPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- return (T) new ECPrivateKeySpec(ecKey.getS(), ecKey.getParams());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
- if ((key instanceof OpenSSLECPublicKey) || (key instanceof OpenSSLECPrivateKey)) {
- return key;
- } else if (key instanceof ECPublicKey) {
- ECPublicKey ecKey = (ECPublicKey) key;
-
- ECPoint w = ecKey.getW();
-
- ECParameterSpec params = ecKey.getParams();
-
- try {
- return engineGeneratePublic(new ECPublicKeySpec(w, params));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof ECPrivateKey) {
- ECPrivateKey ecKey = (ECPrivateKey) key;
-
- BigInteger s = ecKey.getS();
-
- ECParameterSpec params = ecKey.getParams();
-
- try {
- return engineGeneratePrivate(new ECPrivateKeySpec(s, params));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be EC public or private key; was "
- + key.getClass().getName());
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java
deleted file mode 100644
index 21c8984..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECKeyPairGenerator.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.HashMap;
-import java.util.Map;
-
-public final class OpenSSLECKeyPairGenerator extends KeyPairGenerator {
- private static final String ALGORITHM = "EC";
-
- private static final int DEFAULT_KEY_SIZE = 192;
-
- private static final Map<Integer, String> SIZE_TO_CURVE_NAME = new HashMap<Integer, String>();
-
- static {
- /* NIST curves */
- SIZE_TO_CURVE_NAME.put(192, "prime192v1");
- SIZE_TO_CURVE_NAME.put(224, "secp224r1");
- SIZE_TO_CURVE_NAME.put(256, "prime256v1");
- SIZE_TO_CURVE_NAME.put(384, "secp384r1");
- SIZE_TO_CURVE_NAME.put(521, "secp521r1");
- }
-
- private OpenSSLECGroupContext group;
-
- public OpenSSLECKeyPairGenerator() {
- super(ALGORITHM);
- }
-
- @Override
- public KeyPair generateKeyPair() {
- if (group == null) {
- final String curveName = SIZE_TO_CURVE_NAME.get(DEFAULT_KEY_SIZE);
- group = OpenSSLECGroupContext.getCurveByName(curveName);
- }
-
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group.getContext()));
- return new KeyPair(new OpenSSLECPublicKey(group, key), new OpenSSLECPrivateKey(group, key));
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- final String name = SIZE_TO_CURVE_NAME.get(keysize);
- if (name == null) {
- throw new InvalidParameterException("unknown key size " + keysize);
- }
-
- /*
- * Store the group in a temporary variable until we know this is a valid
- * group.
- */
- final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext.getCurveByName(name);
- if (possibleGroup == null) {
- throw new InvalidParameterException("unknown curve " + name);
- }
-
- group = possibleGroup;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec param, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- if (param instanceof ECParameterSpec) {
- ECParameterSpec ecParam = (ECParameterSpec) param;
-
- group = OpenSSLECGroupContext.getInstance(ecParam);
- } else if (param instanceof ECGenParameterSpec) {
- ECGenParameterSpec ecParam = (ECGenParameterSpec) param;
-
- final String curveName = ecParam.getName();
-
- /*
- * Store the group in a temporary variable until we know this is a
- * valid group.
- */
- final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext
- .getCurveByName(curveName);
- if (possibleGroup == null) {
- throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName);
- }
-
- group = possibleGroup;
- } else {
- throw new InvalidAlgorithmParameterException(
- "parameter must be ECParameterSpec or ECGenParameterSpec");
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java
deleted file mode 100644
index 49bdaf1..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPointContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.spec.ECPoint;
-
-final class OpenSSLECPointContext {
- private final OpenSSLECGroupContext group;
- private final long pointCtx;
-
- OpenSSLECPointContext(OpenSSLECGroupContext group, long pointCtx) {
- this.group = group;
- this.pointCtx = pointCtx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (pointCtx != 0) {
- NativeCrypto.EC_POINT_clear_free(pointCtx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof OpenSSLECPointContext)) {
- return false;
- }
-
- final OpenSSLECPointContext other = (OpenSSLECPointContext) o;
- if (!NativeCrypto.EC_GROUP_cmp(group.getContext(), other.group.getContext())) {
- return false;
- }
-
- return NativeCrypto.EC_POINT_cmp(group.getContext(), pointCtx, other.pointCtx);
- }
-
- public ECPoint getECPoint() {
- final byte[][] generatorCoords = NativeCrypto.EC_POINT_get_affine_coordinates(
- group.getContext(), pointCtx);
- final BigInteger x = new BigInteger(generatorCoords[0]);
- final BigInteger y = new BigInteger(generatorCoords[1]);
- return new ECPoint(x, y);
- }
-
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return super.hashCode();
- }
-
- public long getContext() {
- return pointCtx;
- }
-
- public static OpenSSLECPointContext getInstance(int curveType, OpenSSLECGroupContext group,
- ECPoint javaPoint) {
- OpenSSLECPointContext point = new OpenSSLECPointContext(group,
- NativeCrypto.EC_POINT_new(group.getContext()));
- NativeCrypto.EC_POINT_set_affine_coordinates(group.getContext(),
- point.getContext(), javaPoint.getAffineX().toByteArray(),
- javaPoint.getAffineY().toByteArray());
- return point;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java
deleted file mode 100644
index 4010ec5..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPrivateKey.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.ECPrivateKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-public final class OpenSSLECPrivateKey implements ECPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = -4036633595001083922L;
-
- private static final String ALGORITHM = "EC";
-
- protected transient OpenSSLKey key;
-
- protected transient OpenSSLECGroupContext group;
-
- public OpenSSLECPrivateKey(OpenSSLECGroupContext group, OpenSSLKey key) {
- this.group = group;
- this.key = key;
- }
-
- public OpenSSLECPrivateKey(OpenSSLKey key) {
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- this.key = key;
- }
-
- public OpenSSLECPrivateKey(ECPrivateKeySpec ecKeySpec) throws InvalidKeySpecException {
- try {
- group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
- final BigInteger privKey = ecKeySpec.getS();
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(), 0,
- privKey.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public static OpenSSLKey getInstance(ECPrivateKey ecPrivateKey) throws InvalidKeyException {
- try {
- OpenSSLECGroupContext group = OpenSSLECGroupContext.getInstance(ecPrivateKey
- .getParams());
- final BigInteger privKey = ecPrivateKey.getS();
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(), 0,
- privKey.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return ALGORITHM;
- }
-
- @Override
- public String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- @Override
- public ECParameterSpec getParams() {
- return group.getECParameterSpec();
- }
-
- @Override
- public BigInteger getS() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private key value S cannot be extracted");
- }
-
- return getPrivateKey();
- }
-
- private BigInteger getPrivateKey() {
- return new BigInteger(NativeCrypto.EC_KEY_get_private_key(key.getPkeyContext()));
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLECPrivateKey) {
- OpenSSLECPrivateKey other = (OpenSSLECPrivateKey) o;
- return key.equals(other.key);
- }
-
- if (!(o instanceof ECPrivateKey)) {
- return false;
- }
-
- final ECPrivateKey other = (ECPrivateKey) o;
- if (!getPrivateKey().equals(other.getS())) {
- return false;
- }
-
- final ECParameterSpec spec = getParams();
- final ECParameterSpec otherSpec = other.getParams();
-
- return spec.getCurve().equals(otherSpec.getCurve())
- && spec.getGenerator().equals(otherSpec.getGenerator())
- && spec.getOrder().equals(otherSpec.getOrder())
- && spec.getCofactor() == otherSpec.getCofactor();
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext()));
- }
-
- @Override
- public String toString() {
- return NativeCrypto.EVP_PKEY_print_private(key.getPkeyContext());
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- byte[] encoded = (byte[]) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(encoded));
-
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (key.isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- stream.writeObject(getEncoded());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java
deleted file mode 100644
index 8f3a0c6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLECPublicKey.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-public final class OpenSSLECPublicKey implements ECPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 3215842926808298020L;
-
- private static final String ALGORITHM = "EC";
-
- protected transient OpenSSLKey key;
-
- protected transient OpenSSLECGroupContext group;
-
- public OpenSSLECPublicKey(OpenSSLECGroupContext group, OpenSSLKey key) {
- this.group = group;
- this.key = key;
- }
-
- public OpenSSLECPublicKey(OpenSSLKey key) {
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- this.group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- this.key = key;
- }
-
- public OpenSSLECPublicKey(ECPublicKeySpec ecKeySpec) throws InvalidKeySpecException {
- try {
- group = OpenSSLECGroupContext.getInstance(ecKeySpec.getParams());
- OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(
- NativeCrypto.get_EC_GROUP_type(group.getContext()), group, ecKeySpec.getW());
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(),
- pubKey.getContext(), null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public static OpenSSLKey getInstance(ECPublicKey ecPublicKey) throws InvalidKeyException {
- try {
- OpenSSLECGroupContext group = OpenSSLECGroupContext
- .getInstance(ecPublicKey.getParams());
- OpenSSLECPointContext pubKey = OpenSSLECPointContext.getInstance(
- NativeCrypto.get_EC_GROUP_type(group.getContext()), group, ecPublicKey.getW());
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_EC_KEY(group.getContext(),
- pubKey.getContext(), null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return ALGORITHM;
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- @Override
- public ECParameterSpec getParams() {
- return group.getECParameterSpec();
- }
-
- private ECPoint getPublicKey() {
- final OpenSSLECPointContext pubKey = new OpenSSLECPointContext(group,
- NativeCrypto.EC_KEY_get_public_key(key.getPkeyContext()));
-
- return pubKey.getECPoint();
- }
-
- @Override
- public ECPoint getW() {
- return getPublicKey();
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLECPrivateKey) {
- OpenSSLECPrivateKey other = (OpenSSLECPrivateKey) o;
- return key.equals(other.key);
- }
-
- if (!(o instanceof ECPublicKey)) {
- return false;
- }
-
- final ECPublicKey other = (ECPublicKey) o;
- if (!getPublicKey().equals(other.getW())) {
- return false;
- }
-
- final ECParameterSpec spec = getParams();
- final ECParameterSpec otherSpec = other.getParams();
-
- return spec.getCurve().equals(otherSpec.getCurve())
- && spec.getGenerator().equals(otherSpec.getGenerator())
- && spec.getOrder().equals(otherSpec.getOrder())
- && spec.getCofactor() == otherSpec.getCofactor();
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(NativeCrypto.i2d_PUBKEY(key.getPkeyContext()));
- }
-
- @Override
- public String toString() {
- return NativeCrypto.EVP_PKEY_print_public(key.getPkeyContext());
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- byte[] encoded = (byte[]) stream.readObject();
-
- key = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(encoded));
-
- final long origGroup = NativeCrypto.EC_KEY_get0_group(key.getPkeyContext());
- group = new OpenSSLECGroupContext(NativeCrypto.EC_GROUP_dup(origGroup));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (key.isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- stream.writeObject(getEncoded());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java b/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java
deleted file mode 100644
index 380e73f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLEngine.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import javax.crypto.SecretKey;
-
-public class OpenSSLEngine {
- static {
- NativeCrypto.ENGINE_load_dynamic();
- }
-
- private static final Object mLoadingLock = new Object();
-
- /** The ENGINE's native handle. */
- private final long ctx;
-
- public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
- if (engine == null) {
- throw new NullPointerException("engine == null");
- }
-
- final long engineCtx;
- synchronized (mLoadingLock) {
- engineCtx = NativeCrypto.ENGINE_by_id(engine);
- if (engineCtx == 0) {
- throw new IllegalArgumentException("Unknown ENGINE id: " + engine);
- }
-
- NativeCrypto.ENGINE_add(engineCtx);
- }
-
- return new OpenSSLEngine(engineCtx);
- }
-
- private OpenSSLEngine(long engineCtx) {
- ctx = engineCtx;
-
- if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
- NativeCrypto.ENGINE_free(engineCtx);
- throw new IllegalArgumentException("Could not initialize engine");
- }
- }
-
- public PrivateKey getPrivateKeyById(String id) throws InvalidKeyException {
- if (id == null) {
- throw new NullPointerException("id == null");
- }
-
- final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
- if (keyRef == 0) {
- return null;
- }
-
- OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
- try {
- return pkey.getPrivateKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- public SecretKey getSecretKeyById(String id, String algorithm) throws InvalidKeyException {
- if (id == null) {
- throw new NullPointerException("id == null");
- }
-
- final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
- if (keyRef == 0) {
- return null;
- }
-
- OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
- try {
- return pkey.getSecretKey(algorithm);
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeyException(e);
- }
- }
-
- long getEngineContext() {
- return ctx;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- NativeCrypto.ENGINE_finish(ctx);
- NativeCrypto.ENGINE_free(ctx);
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof OpenSSLEngine)) {
- return false;
- }
-
- OpenSSLEngine other = (OpenSSLEngine) o;
-
- if (other.getEngineContext() == ctx) {
- return true;
- }
-
- final String id = NativeCrypto.ENGINE_get_id(ctx);
- if (id == null) {
- return false;
- }
-
- return id.equals(NativeCrypto.ENGINE_get_id(other.getEngineContext()));
- }
-
- @Override
- public int hashCode() {
- return (int) ctx;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLKey.java
deleted file mode 100644
index fa9a258..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLKey.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import javax.crypto.SecretKey;
-
-public class OpenSSLKey {
- private final long ctx;
-
- private final OpenSSLEngine engine;
-
- private final String alias;
-
- public OpenSSLKey(long ctx) {
- this.ctx = ctx;
- engine = null;
- alias = null;
- }
-
- public OpenSSLKey(long ctx, OpenSSLEngine engine, String alias) {
- this.ctx = ctx;
- this.engine = engine;
- this.alias = alias;
- }
-
- /**
- * Returns the raw pointer to the EVP_PKEY context for use in JNI calls. The
- * life cycle of this native pointer is managed by the {@code OpenSSLKey}
- * instance and must not be destroyed or freed by users of this API.
- */
- public long getPkeyContext() {
- return ctx;
- }
-
- OpenSSLEngine getEngine() {
- return engine;
- }
-
- boolean isEngineBased() {
- return engine != null;
- }
-
- public String getAlias() {
- return alias;
- }
-
- public static OpenSSLKey fromPrivateKey(PrivateKey key) throws InvalidKeyException {
- if (key instanceof OpenSSLKeyHolder) {
- return ((OpenSSLKeyHolder) key).getOpenSSLKey();
- }
-
- if ("PKCS#8".equals(key.getFormat())) {
- return new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(key.getEncoded()));
- } else {
- throw new InvalidKeyException("Unknown key format " + key.getFormat());
- }
- }
-
- public PublicKey getPublicKey() throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_RSA:
- return new OpenSSLRSAPublicKey(this);
- case NativeCrypto.EVP_PKEY_DSA:
- return new OpenSSLDSAPublicKey(this);
- case NativeCrypto.EVP_PKEY_EC:
- return new OpenSSLECPublicKey(this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- static PublicKey getPublicKey(X509EncodedKeySpec keySpec, int type)
- throws InvalidKeySpecException {
- X509EncodedKeySpec x509KeySpec = (X509EncodedKeySpec) keySpec;
-
- final OpenSSLKey key;
- try {
- key = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(x509KeySpec.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
-
- if (NativeCrypto.EVP_PKEY_type(key.getPkeyContext()) != type) {
- throw new InvalidKeySpecException("Unexpected key type");
- }
-
- try {
- return key.getPublicKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_RSA:
- return new OpenSSLRSAPrivateKey(this);
- case NativeCrypto.EVP_PKEY_DSA:
- return new OpenSSLDSAPrivateKey(this);
- case NativeCrypto.EVP_PKEY_EC:
- return new OpenSSLECPrivateKey(this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- static PrivateKey getPrivateKey(PKCS8EncodedKeySpec keySpec, int type)
- throws InvalidKeySpecException {
- PKCS8EncodedKeySpec pkcs8KeySpec = (PKCS8EncodedKeySpec) keySpec;
-
- final OpenSSLKey key;
- try {
- key = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(pkcs8KeySpec.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
-
- if (NativeCrypto.EVP_PKEY_type(key.getPkeyContext()) != type) {
- throw new InvalidKeySpecException("Unexpected key type");
- }
-
- try {
- return key.getPrivateKey();
- } catch (NoSuchAlgorithmException e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- public SecretKey getSecretKey(String algorithm) throws NoSuchAlgorithmException {
- switch (NativeCrypto.EVP_PKEY_type(ctx)) {
- case NativeCrypto.EVP_PKEY_HMAC:
- case NativeCrypto.EVP_PKEY_CMAC:
- return new OpenSSLSecretKey(algorithm, this);
- default:
- throw new NoSuchAlgorithmException("unknown PKEY type");
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof OpenSSLKey)) {
- return false;
- }
-
- OpenSSLKey other = (OpenSSLKey) o;
- if (ctx == other.getPkeyContext()) {
- return true;
- }
-
- /*
- * ENGINE-based keys must be checked in a special way.
- */
- if (engine == null) {
- if (other.getEngine() != null) {
- return false;
- }
- } else if (!engine.equals(other.getEngine())) {
- return false;
- } else {
- if (alias != null) {
- return alias.equals(other.getAlias());
- } else if (other.getAlias() != null) {
- return false;
- }
- }
-
- return NativeCrypto.EVP_PKEY_cmp(ctx, other.getPkeyContext()) == 1;
- }
-
- @Override
- public int hashCode() {
- int hash = 1;
- hash = hash * 17 + (int) ctx;
- hash = hash * 31 + (int) (engine == null ? 0 : engine.getEngineContext());
- return hash;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java b/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java
deleted file mode 100644
index 09af21c..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLKeyHolder.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-public interface OpenSSLKeyHolder {
- public OpenSSLKey getOpenSSLKey();
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLMac.java b/crypto/src/main/java/org/conscrypt/OpenSSLMac.java
deleted file mode 100644
index 824e6b9..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLMac.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.MacSpi;
-import javax.crypto.SecretKey;
-
-public abstract class OpenSSLMac extends MacSpi {
- private final OpenSSLDigestContext ctx = new OpenSSLDigestContext(
- NativeCrypto.EVP_MD_CTX_create());
-
- /**
- * Holds the EVP_MD for the hashing algorithm, e.g.
- * EVP_get_digestbyname("sha1");
- */
- private final long evp_md;
-
- /**
- * The key type of the secret key.
- */
- private final int evp_pkey_type;
-
- /**
- * The secret key used in this keyed MAC.
- */
- private OpenSSLKey macKey;
-
- /**
- * Holds the output size of the message digest.
- */
- private final int size;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- private OpenSSLMac(long evp_md, int size, int evp_pkey_type) {
- this.evp_md = evp_md;
- this.size = size;
- this.evp_pkey_type = evp_pkey_type;
- }
-
- @Override
- protected int engineGetMacLength() {
- return size;
- }
-
- @Override
- protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException,
- InvalidAlgorithmParameterException {
- if (!(key instanceof SecretKey)) {
- throw new InvalidKeyException("key must be a SecretKey");
- }
-
- if (params != null) {
- throw new InvalidAlgorithmParameterException("unknown parameter type");
- }
-
- if (key instanceof OpenSSLKeyHolder) {
- macKey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- } else {
- final byte[] keyBytes = key.getEncoded();
- if (keyBytes == null) {
- throw new InvalidKeyException("key cannot be encoded");
- }
-
- macKey = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(evp_pkey_type, keyBytes));
- }
-
- NativeCrypto.EVP_MD_CTX_init(ctx.getContext());
-
- reset();
- }
-
- private void reset() {
- NativeCrypto.EVP_DigestSignInit(ctx.getContext(), evp_md, macKey.getPkeyContext());
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- NativeCrypto.EVP_DigestUpdate(ctx.getContext(), input, offset, len);
- }
-
- @Override
- protected byte[] engineDoFinal() {
- final byte[] output = NativeCrypto.EVP_DigestSignFinal(ctx.getContext());
- reset();
- return output;
- }
-
- @Override
- protected void engineReset() {
- reset();
- }
-
- public static class HmacMD5 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacMD5() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA1 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA1() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA256 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA256() throws NoSuchAlgorithmException {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA384 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA384() throws NoSuchAlgorithmException {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-
- public static class HmacSHA512 extends OpenSSLMac {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
-
- public HmacSHA512() {
- super(EVP_MD, SIZE, NativeCrypto.EVP_PKEY_HMAC);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java b/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java
deleted file mode 100644
index 763ff65..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLMessageDigestJDK.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Implements the JDK MessageDigest interface using OpenSSL's EVP API.
- */
-public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable {
-
- /**
- * Holds a pointer to the native message digest context.
- */
- private long ctx;
-
- /**
- * Holds the EVP_MD for the hashing algorithm, e.g. EVP_get_digestbyname("sha1");
- */
- private final long evp_md;
-
- /**
- * Holds the output size of the message digest.
- */
- private final int size;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- /**
- * Creates a new OpenSSLMessageDigest instance for the given algorithm
- * name.
- */
- private OpenSSLMessageDigestJDK(String algorithm, long evp_md, int size)
- throws NoSuchAlgorithmException {
- super(algorithm);
- this.evp_md = evp_md;
- this.size = size;
- }
-
- @Override
- protected void engineReset() {
- free();
- }
-
- @Override
- protected int engineGetDigestLength() {
- return size;
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- NativeCrypto.EVP_DigestUpdate(getCtx(), input, offset, len);
- }
-
- @Override
- protected byte[] engineDigest() {
- byte[] result = new byte[size];
- NativeCrypto.EVP_DigestFinal(getCtx(), result, 0);
- ctx = 0; // EVP_DigestFinal frees the context as a side effect
- return result;
- }
-
- public Object clone() throws CloneNotSupportedException {
- OpenSSLMessageDigestJDK d = (OpenSSLMessageDigestJDK) super.clone();
- d.ctx = NativeCrypto.EVP_MD_CTX_copy(getCtx());
- return d;
- }
-
- private long getCtx() {
- if (ctx == 0) {
- ctx = NativeCrypto.EVP_DigestInit(evp_md);
- }
- return ctx;
- }
-
- private void free() {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- ctx = 0;
- }
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- free();
- } finally {
- super.finalize();
- }
- }
-
- public static class MD5 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public MD5() throws NoSuchAlgorithmException {
- super("MD5",EVP_MD, SIZE);
- }
- }
-
- public static class SHA1 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA1() throws NoSuchAlgorithmException {
- super("SHA-1", EVP_MD, SIZE);
- }
- }
-
- public static class SHA256 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA256() throws NoSuchAlgorithmException {
- super("SHA-256", EVP_MD, SIZE);
- }
- }
-
- public static class SHA384 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA384() throws NoSuchAlgorithmException {
- super("SHA-384", EVP_MD, SIZE);
- }
- }
-
- public static class SHA512 extends OpenSSLMessageDigestJDK {
- private static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
- private static final int SIZE = NativeCrypto.EVP_MD_size(EVP_MD);
- public SHA512() throws NoSuchAlgorithmException {
- super("SHA-512", EVP_MD, SIZE);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java b/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
deleted file mode 100644
index 4055e50..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-
-/**
- * Provider that goes through OpenSSL for operations.
- * <p>
- * Every algorithm should have its IANA assigned OID as an alias. See the following URLs for each type:
- * <ul>
- * <li><a href="http://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml">Hash functions</a></li>
- * <li><a href="http://www.iana.org/assignments/dssc/dssc.xml">Signature algorithms</a></li>
- * <li><a href="http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html">NIST cryptographic algorithms</a></li>
- * </ul>
- */
-public final class OpenSSLProvider extends Provider {
- private static final long serialVersionUID = 2996752495318905136L;
-
- public static final String PROVIDER_NAME = "AndroidOpenSSL";
-
- public OpenSSLProvider() {
- super(PROVIDER_NAME, 1.0, "Android's OpenSSL-backed security provider");
-
- // Make sure the platform is initialized.
- Platform.setup();
-
- final String prefix = getClass().getPackage().getName() + ".";
-
- /* === SSL Contexts === */
- final String classOpenSSLContextImpl = prefix + "OpenSSLContextImpl";
- put("SSLContext.SSL", classOpenSSLContextImpl);
- put("SSLContext.SSLv3", classOpenSSLContextImpl);
- put("SSLContext.TLS", classOpenSSLContextImpl);
- put("SSLContext.TLSv1", classOpenSSLContextImpl);
- put("SSLContext.TLSv1.1", classOpenSSLContextImpl);
- put("SSLContext.TLSv1.2", classOpenSSLContextImpl);
- put("SSLContext.Default", prefix + "DefaultSSLContextImpl");
-
- /* === Message Digests === */
- put("MessageDigest.SHA-1", prefix + "OpenSSLMessageDigestJDK$SHA1");
- put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
- put("Alg.Alias.MessageDigest.SHA", "SHA-1");
- put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA-1");
-
- put("MessageDigest.SHA-256", prefix + "OpenSSLMessageDigestJDK$SHA256");
- put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
-
- put("MessageDigest.SHA-384", prefix + "OpenSSLMessageDigestJDK$SHA384");
- put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
-
- put("MessageDigest.SHA-512", prefix + "OpenSSLMessageDigestJDK$SHA512");
- put("Alg.Alias.MessageDigest.SHA512", "SHA-512");
- put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
-
- // iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) md5(5)
- put("MessageDigest.MD5", prefix + "OpenSSLMessageDigestJDK$MD5");
- put("Alg.Alias.MessageDigest.1.2.840.113549.2.5", "MD5");
-
- /* == KeyPairGenerators == */
- put("KeyPairGenerator.RSA", prefix + "OpenSSLRSAKeyPairGenerator");
- put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1.1", "RSA");
-
- put("KeyPairGenerator.DSA", prefix + "OpenSSLDSAKeyPairGenerator");
-
- put("KeyPairGenerator.EC", prefix + "OpenSSLECKeyPairGenerator");
-
- /* == KeyFactory == */
- put("KeyFactory.RSA", prefix + "OpenSSLRSAKeyFactory");
- put("Alg.Alias.KeyFactory.1.2.840.113549.1.1.1", "RSA");
-
- put("KeyFactory.DSA", prefix + "OpenSSLDSAKeyFactory");
-
- put("KeyFactory.EC", prefix + "OpenSSLECKeyFactory");
-
- /* == KeyAgreement == */
- put("KeyAgreement.ECDH", prefix + "OpenSSLECDHKeyAgreement");
-
- /* == Signatures == */
- put("Signature.MD5WithRSA", prefix + "OpenSSLSignature$MD5RSA");
- put("Alg.Alias.Signature.MD5WithRSAEncryption", "MD5WithRSA");
- put("Alg.Alias.Signature.MD5/RSA", "MD5WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5WithRSA");
-
- put("Signature.SHA1WithRSA", prefix + "OpenSSLSignature$SHA1RSA");
- put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1WithRSA");
- put("Alg.Alias.Signature.SHA1/RSA", "SHA1WithRSA");
- put("Alg.Alias.Signature.SHA-1/RSA", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1WithRSA");
- put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1WithRSA");
-
- put("Signature.SHA256WithRSA", prefix + "OpenSSLSignature$SHA256RSA");
- put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1",
- "SHA256WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11",
- "SHA256WithRSA");
-
- put("Signature.SHA384WithRSA", prefix + "OpenSSLSignature$SHA384RSA");
- put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1",
- "SHA384WithRSA");
-
- put("Signature.SHA512WithRSA", prefix + "OpenSSLSignature$SHA512RSA");
- put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512WithRSA");
- put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512WithRSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1",
- "SHA512WithRSA");
-
- put("Signature.SHA1withDSA", prefix + "OpenSSLSignature$SHA1DSA");
- put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
- put("Alg.Alias.Signature.DSA", "SHA1withDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.1", "SHA1withDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10040.4.3", "SHA1withDSA");
- put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA");
- put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
-
- put("Signature.NONEwithRSA", prefix + "OpenSSLSignatureRawRSA");
-
- put("Signature.ECDSA", prefix + "OpenSSLSignature$SHA1ECDSA");
- put("Alg.Alias.Signature.SHA1withECDSA", "ECDSA");
- put("Alg.Alias.Signature.ECDSAwithSHA1", "ECDSA");
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA1(1)
- put("Alg.Alias.Signature.1.2.840.10045.4.1", "ECDSA");
- put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.10045.2.1", "ECDSA");
-
- // iso(1) member-body(2) us(840) ansi-x962(10045) signatures(4) ecdsa-with-SHA2(3)
- put("Signature.SHA256withECDSA", prefix + "OpenSSLSignature$SHA256ECDSA");
- // ecdsa-with-SHA256(2)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.2", "SHA256withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.10045.2.1", "SHA256withECDSA");
-
- put("Signature.SHA384withECDSA", prefix + "OpenSSLSignature$SHA384ECDSA");
- // ecdsa-with-SHA384(3)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.3", "SHA384withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.10045.2.1", "SHA384withECDSA");
-
- put("Signature.SHA512withECDSA", prefix + "OpenSSLSignature$SHA512ECDSA");
- // ecdsa-with-SHA512(4)
- put("Alg.Alias.Signature.1.2.840.10045.4.3.4", "SHA512withECDSA");
- put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.10045.2.1", "SHA512withECDSA");
-
- /* === SecureRandom === */
- /*
- * We have to specify SHA1PRNG because various documentation mentions
- * that algorithm by name instead of just recommending calling
- * "new SecureRandom()"
- */
- put("SecureRandom.SHA1PRNG", prefix + "OpenSSLRandom");
- put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
-
- /* === Cipher === */
- put("Cipher.RSA/ECB/NoPadding", prefix + "OpenSSLCipherRSA$Raw");
- put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding");
- put("Cipher.RSA/ECB/PKCS1Padding", prefix + "OpenSSLCipherRSA$PKCS1");
- put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding");
-
- /*
- * OpenSSL only supports a subset of modes, so we'll name them
- * explicitly here.
- */
- put("Cipher.AES/ECB/NoPadding", prefix + "OpenSSLCipher$AES$ECB$NoPadding");
- put("Cipher.AES/ECB/PKCS5Padding", prefix + "OpenSSLCipher$AES$ECB$PKCS5Padding");
- put("Cipher.AES/CBC/NoPadding", prefix + "OpenSSLCipher$AES$CBC$NoPadding");
- put("Cipher.AES/CBC/PKCS5Padding", prefix + "OpenSSLCipher$AES$CBC$PKCS5Padding");
- put("Cipher.AES/CFB/NoPadding", prefix + "OpenSSLCipher$AES$CFB$NoPadding");
- put("Cipher.AES/CFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$CFB$PKCS5Padding");
- put("Cipher.AES/CTR/NoPadding", prefix + "OpenSSLCipher$AES$CTR$NoPadding");
- put("Cipher.AES/CTR/PKCS5Padding", prefix + "OpenSSLCipher$AES$CTR$PKCS5Padding");
- put("Cipher.AES/OFB/NoPadding", prefix + "OpenSSLCipher$AES$OFB$NoPadding");
- put("Cipher.AES/OFB/PKCS5Padding", prefix + "OpenSSLCipher$AES$OFB$PKCS5Padding");
-
- put("Cipher.DESEDE/CBC/NoPadding", prefix + "OpenSSLCipher$DESEDE$CBC$NoPadding");
- put("Cipher.DESEDE/CBC/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CBC$PKCS5Padding");
- put("Cipher.DESEDE/CFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$CFB$NoPadding");
- put("Cipher.DESEDE/CFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$CFB$PKCS5Padding");
- put("Cipher.DESEDE/ECB/NoPadding", prefix + "OpenSSLCipher$DESEDE$ECB$NoPadding");
- put("Cipher.DESEDE/ECB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$ECB$PKCS5Padding");
- put("Cipher.DESEDE/OFB/NoPadding", prefix + "OpenSSLCipher$DESEDE$OFB$NoPadding");
- put("Cipher.DESEDE/OFB/PKCS5Padding", prefix + "OpenSSLCipher$DESEDE$OFB$PKCS5Padding");
-
- put("Cipher.ARC4", prefix + "OpenSSLCipher$ARC4");
-
- /* === Mac === */
-
- put("Mac.HmacMD5", prefix + "OpenSSLMac$HmacMD5");
-
- // PKCS#2 - iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2)
- // http://www.oid-info.com/get/1.2.840.113549.2
-
- // HMAC-SHA-1 PRF (7)
- put("Mac.HmacSHA1", prefix + "OpenSSLMac$HmacSHA1");
- put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1");
- put("Alg.Alias.Mac.HMAC/SHA1", "HmacSHA1");
-
- // id-hmacWithSHA256 (9)
- put("Mac.HmacSHA256", prefix + "OpenSSLMac$HmacSHA256");
- put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC-SHA256", "HmacSHA256");
- put("Alg.Alias.Mac.HMAC/SHA256", "HmacSHA256");
-
- // id-hmacWithSHA384 (10)
- put("Mac.HmacSHA384", prefix + "OpenSSLMac$HmacSHA384");
- put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC-SHA384", "HmacSHA384");
- put("Alg.Alias.Mac.HMAC/SHA384", "HmacSHA384");
-
- // id-hmacWithSHA384 (11)
- put("Mac.HmacSHA512", prefix + "OpenSSLMac$HmacSHA512");
- put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512");
- put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512");
-
- /* === Certificate === */
-
- put("CertificateFactory.X509", prefix + "OpenSSLX509CertificateFactory");
- put("Alg.Alias.CertificateFactory.X.509", "X509");
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java
deleted file mode 100644
index c785ac6..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyFactory.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactorySpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.RSAPrivateCrtKeySpec;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-
-public class OpenSSLRSAKeyFactory extends KeyFactorySpi {
-
- @Override
- protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof RSAPublicKeySpec) {
- return new OpenSSLRSAPublicKey((RSAPublicKeySpec) keySpec);
- } else if (keySpec instanceof X509EncodedKeySpec) {
- return OpenSSLKey.getPublicKey((X509EncodedKeySpec) keySpec, NativeCrypto.EVP_PKEY_RSA);
- }
- throw new InvalidKeySpecException("Must use RSAPublicKeySpec or X509EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException {
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (keySpec instanceof RSAPrivateCrtKeySpec) {
- return new OpenSSLRSAPrivateCrtKey((RSAPrivateCrtKeySpec) keySpec);
- } else if (keySpec instanceof RSAPrivateKeySpec) {
- return new OpenSSLRSAPrivateKey((RSAPrivateKeySpec) keySpec);
- } else if (keySpec instanceof PKCS8EncodedKeySpec) {
- return OpenSSLKey.getPrivateKey((PKCS8EncodedKeySpec) keySpec,
- NativeCrypto.EVP_PKEY_RSA);
- }
- throw new InvalidKeySpecException("Must use RSAPublicKeySpec or PKCS8EncodedKeySpec; was "
- + keySpec.getClass().getName());
- }
-
- @Override
- protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
- throws InvalidKeySpecException {
- if (key == null) {
- throw new InvalidKeySpecException("key == null");
- }
-
- if (keySpec == null) {
- throw new InvalidKeySpecException("keySpec == null");
- }
-
- if (!"RSA".equals(key.getAlgorithm())) {
- throw new InvalidKeySpecException("Key must be a RSA key");
- }
-
- if (key instanceof RSAPublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPublicKey rsaKey = (RSAPublicKey) key;
- return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
- } else if (key instanceof PublicKey && RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid X.509 encoding");
- }
- RSAPublicKey rsaKey =
- (RSAPublicKey) engineGeneratePublic(new X509EncodedKeySpec(encoded));
- return (T) new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent());
- } else if (key instanceof RSAPrivateCrtKey
- && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent(),
- rsaKey.getPrivateExponent(), rsaKey.getPrimeP(), rsaKey.getPrimeQ(),
- rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(),
- rsaKey.getCrtCoefficient());
- } else if (key instanceof RSAPrivateCrtKey
- && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof RSAPrivateKey
- && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- RSAPrivateKey rsaKey = (RSAPrivateKey) key;
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof PrivateKey
- && RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- RSAPrivateKey privKey =
- (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- if (privKey instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) privKey;
- return (T) new RSAPrivateCrtKeySpec(rsaKey.getModulus(),
- rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(),
- rsaKey.getPrimeP(), rsaKey.getPrimeQ(), rsaKey.getPrimeExponentP(),
- rsaKey.getPrimeExponentQ(), rsaKey.getCrtCoefficient());
- } else {
- throw new InvalidKeySpecException("Encoded key is not an RSAPrivateCrtKey");
- }
- } else if (key instanceof PrivateKey && RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat()) || encoded == null) {
- throw new InvalidKeySpecException("Not a valid PKCS#8 encoding");
- }
- RSAPrivateKey rsaKey =
- (RSAPrivateKey) engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- return (T) new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
- } else if (key instanceof PrivateKey
- && PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"PKCS#8".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be PKCS#8; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new PKCS8EncodedKeySpec(encoded);
- } else if (key instanceof PublicKey && X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
- final byte[] encoded = key.getEncoded();
- if (!"X.509".equals(key.getFormat())) {
- throw new InvalidKeySpecException("Encoding type must be X.509; was "
- + key.getFormat());
- } else if (encoded == null) {
- throw new InvalidKeySpecException("Key is not encodable");
- }
- return (T) new X509EncodedKeySpec(encoded);
- } else {
- throw new InvalidKeySpecException("Unsupported key type and key spec combination; key="
- + key.getClass().getName() + ", keySpec=" + keySpec.getName());
- }
- }
-
- @Override
- protected Key engineTranslateKey(Key key) throws InvalidKeyException {
- if (key == null) {
- throw new InvalidKeyException("key == null");
- }
-
- if ((key instanceof OpenSSLRSAPublicKey) || (key instanceof OpenSSLRSAPrivateKey)) {
- return key;
- } else if (key instanceof RSAPublicKey) {
- RSAPublicKey rsaKey = (RSAPublicKey) key;
-
- try {
- return engineGeneratePublic(new RSAPublicKeySpec(rsaKey.getModulus(),
- rsaKey.getPublicExponent()));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
- BigInteger modulus = rsaKey.getModulus();
- BigInteger publicExponent = rsaKey.getPublicExponent();
- BigInteger privateExponent = rsaKey.getPrivateExponent();
- BigInteger primeP = rsaKey.getPrimeP();
- BigInteger primeQ = rsaKey.getPrimeQ();
- BigInteger primeExponentP = rsaKey.getPrimeExponentP();
- BigInteger primeExponentQ = rsaKey.getPrimeExponentQ();
- BigInteger crtCoefficient = rsaKey.getCrtCoefficient();
-
- try {
- return engineGeneratePrivate(new RSAPrivateCrtKeySpec(modulus, publicExponent,
- privateExponent, primeP, primeQ, primeExponentP, primeExponentQ,
- crtCoefficient));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if (key instanceof RSAPrivateKey) {
- RSAPrivateKey rsaKey = (RSAPrivateKey) key;
- BigInteger modulus = rsaKey.getModulus();
- BigInteger privateExponent = rsaKey.getPrivateExponent();
-
- try {
- return engineGeneratePrivate(new RSAPrivateKeySpec(modulus, privateExponent));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PrivateKey) && ("PKCS#8".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePrivate(new PKCS8EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else if ((key instanceof PublicKey) && ("X.509".equals(key.getFormat()))) {
- byte[] encoded = key.getEncoded();
- if (encoded == null) {
- throw new InvalidKeyException("Key does not support encoding");
- }
- try {
- return engineGeneratePublic(new X509EncodedKeySpec(encoded));
- } catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e);
- }
- } else {
- throw new InvalidKeyException("Key must be an RSA public or private key; was "
- + key.getClass().getName());
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
deleted file mode 100644
index a00219f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAKeyPairGenerator.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPair;
-import java.security.KeyPairGeneratorSpi;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-
-public class OpenSSLRSAKeyPairGenerator extends KeyPairGeneratorSpi {
- /**
- * Default modulus size is 0x10001 (65537)
- */
- private byte[] publicExponent = new byte[] {
- 0x01, 0x00, 0x01
- };
-
- /**
- * Default RSA key size 2048 bits.
- */
- private int modulusBits = 2048;
-
- @Override
- public KeyPair generateKeyPair() {
- final OpenSSLKey key = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(modulusBits,
- publicExponent));
-
- PrivateKey privKey = OpenSSLRSAPrivateKey.getInstance(key);
- PublicKey pubKey = new OpenSSLRSAPublicKey(key);
-
- return new KeyPair(pubKey, privKey);
- }
-
- @Override
- public void initialize(int keysize, SecureRandom random) {
- this.modulusBits = keysize;
- }
-
- @Override
- public void initialize(AlgorithmParameterSpec params, SecureRandom random)
- throws InvalidAlgorithmParameterException {
- if (!(params instanceof RSAKeyGenParameterSpec)) {
- throw new InvalidAlgorithmParameterException("Only RSAKeyGenParameterSpec supported");
- }
-
- RSAKeyGenParameterSpec spec = (RSAKeyGenParameterSpec) params;
-
- final BigInteger publicExponent = spec.getPublicExponent();
- if (publicExponent != null) {
- this.publicExponent = publicExponent.toByteArray();
- }
-
- this.modulusBits = spec.getKeysize();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
deleted file mode 100644
index 1cbf5de..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPrivateCrtKeySpec;
-
-public class OpenSSLRSAPrivateCrtKey extends OpenSSLRSAPrivateKey implements RSAPrivateCrtKey {
- private static final long serialVersionUID = 3785291944868707197L;
-
- private BigInteger publicExponent;
-
- private BigInteger primeP;
-
- private BigInteger primeQ;
-
- private BigInteger primeExponentP;
-
- private BigInteger primeExponentQ;
-
- private BigInteger crtCoefficient;
-
- OpenSSLRSAPrivateCrtKey(OpenSSLKey key) {
- super(key);
- }
-
- OpenSSLRSAPrivateCrtKey(OpenSSLKey key, byte[][] params) {
- super(key, params);
- }
-
- public OpenSSLRSAPrivateCrtKey(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
- super(init(rsaKeySpec));
- }
-
- private static OpenSSLKey init(RSAPrivateCrtKeySpec rsaKeySpec) throws InvalidKeySpecException {
- BigInteger modulus = rsaKeySpec.getModulus();
- BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeySpecException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeySpecException("privateExponent == null");
- }
-
- try {
- /*
- * OpenSSL uses the public modulus to do RSA blinding. If
- * the public modulus is not available, the call to
- * EVP_PKEY_new_RSA will turn off blinding for this key
- * instance.
- */
- final BigInteger publicExponent = rsaKeySpec.getPublicExponent();
- final BigInteger primeP = rsaKeySpec.getPrimeP();
- final BigInteger primeQ = rsaKeySpec.getPrimeQ();
- final BigInteger primeExponentP = rsaKeySpec.getPrimeExponentP();
- final BigInteger primeExponentQ = rsaKeySpec.getPrimeExponentQ();
- final BigInteger crtCoefficient = rsaKeySpec.getCrtCoefficient();
-
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLKey getInstance(RSAPrivateCrtKey rsaPrivateKey) throws InvalidKeyException {
- BigInteger modulus = rsaPrivateKey.getModulus();
- BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeyException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeyException("privateExponent == null");
- }
-
- try {
- /*
- * OpenSSL uses the public modulus to do RSA blinding. If
- * the public modulus is not available, the call to
- * EVP_PKEY_new_RSA will turn off blinding for this key
- * instance.
- */
- final BigInteger publicExponent = rsaPrivateKey.getPublicExponent();
- final BigInteger primeP = rsaPrivateKey.getPrimeP();
- final BigInteger primeQ = rsaPrivateKey.getPrimeQ();
- final BigInteger primeExponentP = rsaPrivateKey.getPrimeExponentP();
- final BigInteger primeExponentQ = rsaPrivateKey.getPrimeExponentQ();
- final BigInteger crtCoefficient = rsaPrivateKey.getCrtCoefficient();
-
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- synchronized void readParams(byte[][] params) {
- super.readParams(params);
- // params[0] read in super.readParams
- if (params[1] != null) {
- publicExponent = new BigInteger(params[1]);
- }
- // params[2] read in super.readParams
- if (params[3] != null) {
- primeP = new BigInteger(params[3]);
- }
- if (params[4] != null) {
- primeQ = new BigInteger(params[4]);
- }
- if (params[5] != null) {
- primeExponentP = new BigInteger(params[5]);
- }
- if (params[6] != null) {
- primeExponentQ = new BigInteger(params[6]);
- }
- if (params[7] != null) {
- crtCoefficient = new BigInteger(params[7]);
- }
- }
-
- @Override
- public BigInteger getPublicExponent() {
- ensureReadParams();
- return publicExponent;
- }
-
- @Override
- public BigInteger getPrimeP() {
- ensureReadParams();
- return primeP;
- }
-
- @Override
- public BigInteger getPrimeQ() {
- ensureReadParams();
- return primeQ;
- }
-
- @Override
- public BigInteger getPrimeExponentP() {
- ensureReadParams();
- return primeExponentP;
- }
-
- @Override
- public BigInteger getPrimeExponentQ() {
- ensureReadParams();
- return primeExponentQ;
- }
-
- @Override
- public BigInteger getCrtCoefficient() {
- ensureReadParams();
- return crtCoefficient;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
- return getOpenSSLKey().equals(other.getOpenSSLKey());
- }
-
- if (o instanceof RSAPrivateCrtKey) {
- ensureReadParams();
- RSAPrivateCrtKey other = (RSAPrivateCrtKey) o;
-
- if (getOpenSSLKey().isEngineBased()) {
- return getModulus().equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent());
- } else {
- return getModulus().equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent())
- && getPrivateExponent().equals(other.getPrivateExponent())
- && primeP.equals(other.getPrimeP()) && primeQ.equals(other.getPrimeQ())
- && primeExponentP.equals(other.getPrimeExponentP())
- && primeExponentQ.equals(other.getPrimeExponentQ())
- && crtCoefficient.equals(other.getCrtCoefficient());
- }
- } else if (o instanceof RSAPrivateKey) {
- ensureReadParams();
- RSAPrivateKey other = (RSAPrivateKey) o;
-
- if (getOpenSSLKey().isEngineBased()) {
- return getModulus().equals(other.getModulus());
- } else {
- return getModulus().equals(other.getModulus())
- && getPrivateExponent().equals(other.getPrivateExponent());
- }
- }
-
- return false;
- }
-
- @Override
- public final int hashCode() {
- int hashCode = super.hashCode();
- if (publicExponent != null) {
- hashCode ^= publicExponent.hashCode();
- }
- return hashCode;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateCrtKey{");
-
- final boolean engineBased = getOpenSSLKey().isEngineBased();
- if (engineBased) {
- sb.append("key=");
- sb.append(getOpenSSLKey());
- sb.append('}');
- }
-
- ensureReadParams();
- sb.append("modulus=");
- sb.append(getModulus().toString(16));
- sb.append(',');
-
- if (publicExponent != null) {
- sb.append("publicExponent=");
- sb.append(publicExponent.toString(16));
- sb.append(',');
- }
-
- if (!engineBased) {
- sb.append("privateExponent=");
- sb.append(getPrivateExponent().toString(16));
- sb.append(',');
- }
-
- if (primeP != null) {
- sb.append("primeP=");
- sb.append(primeP.toString(16));
- sb.append(',');
- }
-
- if (primeQ != null) {
- sb.append("primeQ=");
- sb.append(primeQ.toString(16));
- sb.append(',');
- }
-
- if (primeExponentP != null) {
- sb.append("primeExponentP=");
- sb.append(primeExponentP.toString(16));
- sb.append(',');
- }
-
- if (primeExponentQ != null) {
- sb.append("primeExponentQ=");
- sb.append(primeExponentQ.toString(16));
- sb.append(',');
- }
-
- if (crtCoefficient != null) {
- sb.append("crtCoefficient=");
- sb.append(crtCoefficient.toString(16));
- sb.append(',');
- }
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent == null ? null : publicExponent.toByteArray(),
- privateExponent.toByteArray(),
- primeP == null ? null : primeP.toByteArray(),
- primeQ == null ? null : primeQ.toByteArray(),
- primeExponentP == null ? null : primeExponentP.toByteArray(),
- primeExponentQ == null ? null : primeExponentQ.toByteArray(),
- crtCoefficient == null ? null : crtCoefficient.toByteArray()));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
deleted file mode 100644
index 20db293..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPrivateKeySpec;
-
-public class OpenSSLRSAPrivateKey implements RSAPrivateKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 4872170254439578735L;
-
- protected transient OpenSSLKey key;
-
- protected transient boolean fetchedParams;
-
- protected BigInteger modulus;
-
- protected BigInteger privateExponent;
-
- OpenSSLRSAPrivateKey(OpenSSLKey key) {
- this.key = key;
- }
-
- OpenSSLRSAPrivateKey(OpenSSLKey key, byte[][] params) {
- this(key);
- readParams(params);
- fetchedParams = true;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- public OpenSSLRSAPrivateKey(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
- this(init(rsaKeySpec));
- }
-
- private static OpenSSLKey init(RSAPrivateKeySpec rsaKeySpec) throws InvalidKeySpecException {
- final BigInteger modulus = rsaKeySpec.getModulus();
- final BigInteger privateExponent = rsaKeySpec.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeySpecException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeySpecException("privateExponent == null");
- }
-
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLRSAPrivateKey getInstance(OpenSSLKey key) {
- byte[][] params = NativeCrypto.get_RSA_private_params(key.getPkeyContext());
- if (params[1] != null) {
- return new OpenSSLRSAPrivateCrtKey(key, params);
- }
- return new OpenSSLRSAPrivateKey(key, params);
- }
-
- static OpenSSLKey getInstance(RSAPrivateKey rsaPrivateKey) throws InvalidKeyException {
- final BigInteger modulus = rsaPrivateKey.getModulus();
- final BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
-
- if (modulus == null) {
- throw new InvalidKeyException("modulus == null");
- } else if (privateExponent == null) {
- throw new InvalidKeyException("privateExponent == null");
- }
-
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- synchronized final void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
- readParams(NativeCrypto.get_RSA_private_params(key.getPkeyContext()));
- fetchedParams = true;
- }
-
- void readParams(byte[][] params) {
- if (params[0] == null) {
- throw new NullPointerException("modulus == null");
- } else if (params[2] == null && !key.isEngineBased()) {
- throw new NullPointerException("privateExponent == null");
- }
-
- modulus = new BigInteger(params[0]);
-
- // ENGINE-based keys are not guaranteed to have a private exponent.
- if (params[2] != null) {
- privateExponent = new BigInteger(params[2]);
- }
- }
-
- @Override
- public final BigInteger getPrivateExponent() {
- if (key.isEngineBased()) {
- throw new UnsupportedOperationException("private exponent cannot be extracted");
- }
-
- ensureReadParams();
- return privateExponent;
- }
-
- @Override
- public final BigInteger getModulus() {
- ensureReadParams();
- return modulus;
- }
-
- @Override
- public final byte[] getEncoded() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext());
- }
-
- public final String getFormat() {
- /*
- * If we're using an OpenSSL ENGINE, there's no guarantee we can export
- * the key. Returning {@code null} tells the caller that there's no
- * encoded format.
- */
- if (key.isEngineBased()) {
- return null;
- }
-
- return "PKCS#8";
- }
-
- @Override
- public final String getAlgorithm() {
- return "RSA";
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey other = (OpenSSLRSAPrivateKey) o;
- return key.equals(other.getOpenSSLKey());
- }
-
- if (o instanceof RSAPrivateKey) {
- ensureReadParams();
- RSAPrivateKey other = (RSAPrivateKey) o;
-
- return modulus.equals(other.getModulus())
- && privateExponent.equals(other.getPrivateExponent());
- }
-
- return false;
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
- int hash = 1;
-
- hash = hash * 3 + modulus.hashCode();
- if (privateExponent != null) {
- hash = hash * 7 + privateExponent.hashCode();
- }
-
- return hash;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPrivateKey{");
-
- final boolean engineBased = key.isEngineBased();
- if (engineBased) {
- sb.append("key=");
- sb.append(key);
- sb.append('}');
- }
-
- ensureReadParams();
- sb.append("modulus=");
- sb.append(modulus.toString(16));
- sb.append(',');
-
- if (!engineBased) {
- sb.append("privateExponent=");
- sb.append(privateExponent.toString(16));
- sb.append(',');
- }
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- null,
- privateExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java
deleted file mode 100644
index 4bbd7e3..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRSAPublicKey.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.RSAPublicKeySpec;
-
-public class OpenSSLRSAPublicKey implements RSAPublicKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 123125005824688292L;
-
- private transient OpenSSLKey key;
-
- private BigInteger publicExponent;
-
- private BigInteger modulus;
-
- private transient boolean fetchedParams;
-
- OpenSSLRSAPublicKey(OpenSSLKey key) {
- this.key = key;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- OpenSSLRSAPublicKey(RSAPublicKeySpec spec) throws InvalidKeySpecException {
- try {
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- spec.getModulus().toByteArray(),
- spec.getPublicExponent().toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeySpecException(e);
- }
- }
-
- static OpenSSLKey getInstance(RSAPublicKey rsaPublicKey) throws InvalidKeyException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- rsaPublicKey.getModulus().toByteArray(),
- rsaPublicKey.getPublicExponent().toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return "RSA";
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return NativeCrypto.i2d_PUBKEY(key.getPkeyContext());
- }
-
- private void ensureReadParams() {
- if (fetchedParams) {
- return;
- }
-
- byte[][] params = NativeCrypto.get_RSA_public_params(key.getPkeyContext());
- modulus = new BigInteger(params[0]);
- publicExponent = new BigInteger(params[1]);
-
- fetchedParams = true;
- }
-
- @Override
- public BigInteger getModulus() {
- ensureReadParams();
- return modulus;
- }
-
- @Override
- public BigInteger getPublicExponent() {
- ensureReadParams();
- return publicExponent;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (o instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey other = (OpenSSLRSAPublicKey) o;
-
- /*
- * We can shortcut the true case, but it still may be equivalent but
- * different copies.
- */
- if (key.equals(other.getOpenSSLKey())) {
- return true;
- }
- }
-
- if (!(o instanceof RSAPublicKey)) {
- return false;
- }
-
- ensureReadParams();
-
- RSAPublicKey other = (RSAPublicKey) o;
- return modulus.equals(other.getModulus())
- && publicExponent.equals(other.getPublicExponent());
- }
-
- @Override
- public int hashCode() {
- ensureReadParams();
-
- return modulus.hashCode() ^ publicExponent.hashCode();
- }
-
- @Override
- public String toString() {
- ensureReadParams();
-
- final StringBuilder sb = new StringBuilder("OpenSSLRSAPublicKey{");
- sb.append("modulus=");
- sb.append(modulus.toString(16));
- sb.append(',');
- sb.append("publicExponent=");
- sb.append(publicExponent.toString(16));
- sb.append('}');
-
- return sb.toString();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_RSA(
- modulus.toByteArray(),
- publicExponent.toByteArray(),
- null,
- null,
- null,
- null,
- null,
- null));
- fetchedParams = true;
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- ensureReadParams();
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java b/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java
deleted file mode 100644
index 1683bb8..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLRandom.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.Serializable;
-import java.security.SecureRandomSpi;
-
-public class OpenSSLRandom extends SecureRandomSpi implements Serializable {
- private static final long serialVersionUID = 8506210602917522860L;
-
- @Override
- protected void engineSetSeed(byte[] seed) {
- NativeCrypto.RAND_seed(seed);
- }
-
- @Override
- protected void engineNextBytes(byte[] bytes) {
- NativeCrypto.RAND_bytes(bytes);
- }
-
- @Override
- protected byte[] engineGenerateSeed(int numBytes) {
- byte[] output = new byte[numBytes];
- NativeCrypto.RAND_bytes(output);
- return output;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java b/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java
deleted file mode 100644
index 193356e..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSecretKey.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.security.InvalidKeyException;
-import java.util.Arrays;
-
-import javax.crypto.SecretKey;
-
-public class OpenSSLSecretKey implements SecretKey, OpenSSLKeyHolder {
- private static final long serialVersionUID = 1831053062911514589L;
-
- private final String algorithm;
- private final int type;
- private final byte[] encoded;
-
- private transient OpenSSLKey key;
-
- public OpenSSLSecretKey(String algorithm, byte[] encoded) {
- this.algorithm = algorithm;
- this.encoded = encoded;
-
- type = NativeCrypto.EVP_PKEY_HMAC;
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
- }
-
- public OpenSSLSecretKey(String algorithm, OpenSSLKey key) {
- this.algorithm = algorithm;
- this.key = key;
-
- type = NativeCrypto.EVP_PKEY_type(key.getPkeyContext());
- encoded = null;
- }
-
- public static OpenSSLKey getInstance(SecretKey key) throws InvalidKeyException {
- try {
- return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(NativeCrypto.EVP_PKEY_HMAC,
- key.getEncoded()));
- } catch (Exception e) {
- throw new InvalidKeyException(e);
- }
- }
-
- @Override
- public String getAlgorithm() {
- return algorithm;
- }
-
- @Override
- public String getFormat() {
- if (key.isEngineBased()) {
- return null;
- }
-
- return "RAW";
- }
-
- @Override
- public byte[] getEncoded() {
- if (key.isEngineBased()) {
- return null;
- }
-
- return encoded;
- }
-
- @Override
- public OpenSSLKey getOpenSSLKey() {
- return key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof SecretKey)) {
- return false;
- }
-
- SecretKey other = (SecretKey) o;
- if (!algorithm.equals(other.getAlgorithm())) {
- return false;
- }
-
- if (o instanceof OpenSSLSecretKey) {
- OpenSSLSecretKey otherOpenSSL = (OpenSSLSecretKey) o;
- return key.equals(otherOpenSSL.getOpenSSLKey());
- } else if (key.isEngineBased()) {
- return false;
- }
-
- if (!getFormat().equals(other.getFormat())) {
- return false;
- }
-
- return Arrays.equals(encoded, other.getEncoded());
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
-
- key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
- }
-
- private void writeObject(ObjectOutputStream stream) throws IOException {
- if (getOpenSSLKey().isEngineBased()) {
- throw new NotSerializableException("engine-based keys can not be serialized");
- }
-
- stream.defaultWriteObject();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
deleted file mode 100644
index d14e921..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketFactoryImpl.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.security.KeyManagementException;
-
-public class OpenSSLServerSocketFactoryImpl extends javax.net.ssl.SSLServerSocketFactory {
-
- private SSLParametersImpl sslParameters;
- private IOException instantiationException;
-
- public OpenSSLServerSocketFactoryImpl() {
- try {
- this.sslParameters = SSLParametersImpl.getDefault();
- this.sslParameters.setUseClientMode(false);
- } catch (KeyManagementException e) {
- instantiationException =
- new IOException("Delayed instantiation exception:");
- instantiationException.initCause(e);
- }
- }
-
- public OpenSSLServerSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = (SSLParametersImpl) sslParameters.clone();
- this.sslParameters.setUseClientMode(false);
- }
-
- public String[] getDefaultCipherSuites() {
- return NativeCrypto.getDefaultCipherSuites();
- }
-
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- public ServerSocket createServerSocket() throws IOException {
- return new OpenSSLServerSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port) throws IOException {
- return new OpenSSLServerSocketImpl(port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port, int backlog)
- throws IOException {
- return new OpenSSLServerSocketImpl(port,
- backlog,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public ServerSocket createServerSocket(int port,
- int backlog,
- InetAddress iAddress) throws IOException {
- return new OpenSSLServerSocketImpl(port,
- backlog,
- iAddress,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
deleted file mode 100644
index adcfa1d..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLServerSocketImpl.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.security.PrivateKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-import javax.net.ssl.SSLException;
-
-/**
- * OpenSSL-based implementation of server sockets.
- */
-public class OpenSSLServerSocketImpl extends javax.net.ssl.SSLServerSocket {
- private final SSLParametersImpl sslParameters;
- private String[] enabledProtocols = NativeCrypto.getSupportedProtocols();
- private String[] enabledCipherSuites = NativeCrypto.getDefaultCipherSuites();
- private boolean channelIdEnabled;
-
- protected OpenSSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(port);
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port, int backlog, SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog);
- this.sslParameters = sslParameters;
- }
-
- protected OpenSSLServerSocketImpl(int port,
- int backlog,
- InetAddress iAddress,
- SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog, iAddress);
- this.sslParameters = sslParameters;
- }
-
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * The names of the protocols' versions that may be used on this SSL
- * connection.
- * @return an array of protocols names
- */
- @Override
- public String[] getSupportedProtocols() {
- return NativeCrypto.getSupportedProtocols();
- }
-
- /**
- * The names of the protocols' versions that in use on this SSL connection.
- *
- * @return an array of protocols names
- */
- @Override
- public String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- /**
- * This method enables the protocols' versions listed by
- * getSupportedProtocols().
- *
- * @param protocols names of all the protocols to enable.
- *
- * @throws IllegalArgumentException when one or more of the names in the
- * array are not supported, or when the array is null.
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- @Override
- public String[] getEnabledCipherSuites() {
- return enabledCipherSuites.clone();
- }
-
- /**
- * Enables/disables the TLS Channel ID extension for this server socket.
- */
- public void setChannelIdEnabled(boolean enabled) {
- channelIdEnabled = enabled;
- }
-
- /**
- * Checks whether the TLS Channel ID extension is enabled for this server socket.
- */
- public boolean isChannelIdEnabled() {
- return channelIdEnabled;
- }
-
- /**
- * This method enables the cipher suites listed by
- * getSupportedCipherSuites().
- *
- * @param suites the names of all the cipher suites to enable
- * @throws IllegalArgumentException when one or more of the ciphers in array
- * suites are not supported, or when the array is null.
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
- }
-
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- @Override
- public void setUseClientMode(boolean mode) {
- sslParameters.setUseClientMode(mode);
- }
-
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- @Override
- public Socket accept() throws IOException {
-
- if (!sslParameters.getUseClientMode()) {
- checkEnabledCipherSuites();
- }
-
- OpenSSLSocketImpl socket = new OpenSSLSocketImpl(sslParameters,
- enabledProtocols.clone(),
- enabledCipherSuites.clone());
- socket.setChannelIdEnabled(channelIdEnabled);
- implAccept(socket);
- return socket;
- }
-
- /**
- * Check if any of the enabled cipher suites has a chance to work.
- * Not 100% accurate, just a useful diagnostic that the RI does.
- */
- private void checkEnabledCipherSuites() throws SSLException {
- /* Loop over all enabled cipher suites. If we find a problem,
- * we just continue to the next one. If we find one that could
- * work, we return. This basically makes sure the caller has
- * configured some appropriate certificate/key unless
- * an anonymous cipher is picked.
- */
- for (String enabledCipherSuite : enabledCipherSuites) {
- if (enabledCipherSuite.equals(NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
- || enabledCipherSuite.equals(NativeCrypto.TLS_FALLBACK_SCSV)) {
- continue;
- }
- String keyType = CipherSuite.getByName(enabledCipherSuite).getServerKeyType();
- if (keyType == null) {
- // anonymous always work
- return;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_RSA)
- || keyType.equals(CipherSuite.KEY_TYPE_DH_RSA)) {
- if (checkForPrivateKey(keyType, RSAPrivateKey.class)) {
- return;
- }
- continue;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_DSA)
- || keyType.equals(CipherSuite.KEY_TYPE_DH_DSA)) {
- if (checkForPrivateKey(keyType, DSAPrivateKey.class)) {
- return;
- }
- continue;
- }
- if (keyType.equals(CipherSuite.KEY_TYPE_EC)
- || keyType.equals(CipherSuite.KEY_TYPE_EC_RSA)
- || keyType.equals(CipherSuite.KEY_TYPE_EC_EC)) {
- if (checkForPrivateKey(keyType, ECPrivateKey.class)) {
- return;
- }
- continue;
- }
- throw new IllegalStateException("Unknown key type " + keyType);
- }
- throw new SSLException("Could not find any key store entries "
- + "to support the enabled cipher suites.");
- }
-
- private boolean checkForPrivateKey(String keyType, Class<?> keyClass) {
- String alias = sslParameters.getKeyManager().chooseServerAlias(keyType, null, null);
- if (alias == null) {
- return false;
- }
- PrivateKey key = sslParameters.getKeyManager().getPrivateKey(alias);
- return (key != null && keyClass.isAssignableFrom(key.getClass()));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
deleted file mode 100644
index 3b7328d..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.Principal;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
-import javax.security.cert.CertificateException;
-
-/**
- * Implementation of the class OpenSSLSessionImpl
- * based on OpenSSL.
- */
-public class OpenSSLSessionImpl implements SSLSession {
-
- private long creationTime = 0;
- long lastAccessedTime = 0;
- final X509Certificate[] localCertificates;
- final X509Certificate[] peerCertificates;
-
- private boolean isValid = true;
- private final Map<String, Object> values = new HashMap<String, Object>();
- private volatile javax.security.cert.X509Certificate[] peerCertificateChain;
- protected long sslSessionNativePointer;
- private String peerHost;
- private int peerPort = -1;
- private String cipherSuite;
- private String protocol;
- private AbstractSessionContext sessionContext;
- private byte[] id;
-
- /**
- * Class constructor creates an SSL session context given the appropriate
- * SSL parameters.
- */
- protected OpenSSLSessionImpl(long sslSessionNativePointer, X509Certificate[] localCertificates,
- X509Certificate[] peerCertificates, String peerHost, int peerPort,
- AbstractSessionContext sessionContext) {
- this.sslSessionNativePointer = sslSessionNativePointer;
- this.localCertificates = localCertificates;
- this.peerCertificates = peerCertificates;
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- this.sessionContext = sessionContext;
- }
-
- /**
- * Constructs a session from a byte[] containing DER data. This
- * allows loading the saved session.
- * @throws IOException
- */
- OpenSSLSessionImpl(byte[] derData,
- String peerHost, int peerPort,
- X509Certificate[] peerCertificates,
- AbstractSessionContext sessionContext)
- throws IOException {
- this(NativeCrypto.d2i_SSL_SESSION(derData),
- null,
- peerCertificates,
- peerHost,
- peerPort,
- sessionContext);
- // TODO move this check into native code so we can throw an error with more information
- if (this.sslSessionNativePointer == 0) {
- throw new IOException("Invalid session data");
- }
- }
-
- /**
- * Gets the identifier of the actual SSL session
- * @return array of sessions' identifiers.
- */
- public byte[] getId() {
- if (id == null) {
- resetId();
- }
- return id;
- }
-
- /**
- * Reset the id field to the current value found in the native
- * SSL_SESSION. It can change during the lifetime of the session
- * because while a session is created during initial handshake,
- * with handshake_cutthrough, the SSL_do_handshake may return
- * before we have read the session ticket from the server side and
- * therefore have computed no id based on the SHA of the ticket.
- */
- void resetId() {
- id = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
- }
-
- /**
- * Get the session object in DER format. This allows saving the session
- * data or sharing it with other processes.
- */
- byte[] getEncoded() {
- return NativeCrypto.i2d_SSL_SESSION(sslSessionNativePointer);
- }
-
- /**
- * Gets the creation time of the SSL session.
- * @return the session's creation time in milliseconds since the epoch
- */
- public long getCreationTime() {
- if (creationTime == 0) {
- creationTime = NativeCrypto.SSL_SESSION_get_time(sslSessionNativePointer);
- }
- return creationTime;
- }
-
- /**
- * Returns the last time this concrete SSL session was accessed. Accessing
- * here is to mean that a new connection with the same SSL context data was
- * established.
- *
- * @return the session's last access time in milliseconds since the epoch
- */
- public long getLastAccessedTime() {
- return (lastAccessedTime == 0) ? getCreationTime() : lastAccessedTime;
- }
-
- /**
- * Returns the largest buffer size for the application's data bound to this
- * concrete SSL session.
- * @return the largest buffer size
- */
- public int getApplicationBufferSize() {
- return SSLRecordProtocol.MAX_DATA_LENGTH;
- }
-
- /**
- * Returns the largest SSL/TLS packet size one can expect for this concrete
- * SSL session.
- * @return the largest packet size
- */
- public int getPacketBufferSize() {
- return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
- }
-
- /**
- * Returns the principal (subject) of this concrete SSL session used in the
- * handshaking phase of the connection.
- * @return a X509 certificate or null if no principal was defined
- */
- public Principal getLocalPrincipal() {
- if (localCertificates != null && localCertificates.length > 0) {
- return localCertificates[0].getSubjectX500Principal();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the certificate(s) of the principal (subject) of this concrete SSL
- * session used in the handshaking phase of the connection. The OpenSSL
- * native method supports only RSA certificates.
- * @return an array of certificates (the local one first and then eventually
- * that of the certification authority) or null if no certificate
- * were used during the handshaking phase.
- */
- public Certificate[] getLocalCertificates() {
- return localCertificates;
- }
-
- /**
- * Returns the certificate(s) of the peer in this SSL session
- * used in the handshaking phase of the connection.
- * Please notice hat this method is superseded by
- * <code>getPeerCertificates()</code>.
- * @return an array of X509 certificates (the peer's one first and then
- * eventually that of the certification authority) or null if no
- * certificate were used during the SSL connection.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer could not
- * be verified.
- */
- public javax.security.cert.X509Certificate[] getPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- javax.security.cert.X509Certificate[] result = peerCertificateChain;
- if (result == null) {
- // single-check idiom
- peerCertificateChain = result = createPeerCertificateChain();
- }
- return result;
- }
-
- /**
- * Provide a value to initialize the volatile peerCertificateChain
- * field based on the native SSL_SESSION
- */
- private javax.security.cert.X509Certificate[] createPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- try {
- javax.security.cert.X509Certificate[] chain
- = new javax.security.cert.X509Certificate[peerCertificates.length];
-
- for (int i = 0; i < peerCertificates.length; i++) {
- byte[] encoded = peerCertificates[i].getEncoded();
- chain[i] = javax.security.cert.X509Certificate.getInstance(encoded);
- }
- return chain;
- } catch (CertificateEncodingException e) {
- SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
- exception.initCause(exception);
- throw exception;
- } catch (CertificateException e) {
- SSLPeerUnverifiedException exception = new SSLPeerUnverifiedException(e.getMessage());
- exception.initCause(exception);
- throw exception;
- }
- }
-
- /**
- * Return the identity of the peer in this SSL session
- * determined via certificate(s).
- * @return an array of X509 certificates (the peer's one first and then
- * eventually that of the certification authority) or null if no
- * certificate were used during the SSL connection.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer could not
- * be verified.
- */
- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- return peerCertificates;
- }
-
- /**
- * Throw SSLPeerUnverifiedException on null or empty peerCertificates array
- */
- private void checkPeerCertificatesPresent() throws SSLPeerUnverifiedException {
- if (peerCertificates == null || peerCertificates.length == 0) {
- throw new SSLPeerUnverifiedException("No peer certificates");
- }
- }
-
- /**
- * The identity of the principal that was used by the peer during the SSL
- * handshake phase is returned by this method.
- * @return a X500Principal of the last certificate for X509-based
- * cipher suites.
- * @throws SSLPeerUnverifiedException if either a non-X.509 certificate
- * was used (i.e. Kerberos certificates) or the peer does not exist.
- *
- */
- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
- checkPeerCertificatesPresent();
- return peerCertificates[0].getSubjectX500Principal();
- }
-
- /**
- * The peer's host name used in this SSL session is returned. It is the host
- * name of the client for the server; and that of the server for the client.
- * It is not a reliable way to get a fully qualified host name: it is mainly
- * used internally to implement links for a temporary cache of SSL sessions.
- *
- * @return the host name of the peer, or null if no information is
- * available.
- *
- */
- public String getPeerHost() {
- return peerHost;
- }
-
- /**
- * Returns the peer's port number for the actual SSL session. It is the port
- * number of the client for the server; and that of the server for the
- * client. It is not a reliable way to get a peer's port number: it is
- * mainly used internally to implement links for a temporary cache of SSL
- * sessions.
- * @return the peer's port number, or -1 if no one is available.
- *
- */
- public int getPeerPort() {
- return peerPort;
- }
-
- /**
- * Returns a string identifier of the crypto tools used in the actual SSL
- * session. For example AES_256_WITH_MD5.
- */
- public String getCipherSuite() {
- if (cipherSuite == null) {
- String name = NativeCrypto.SSL_SESSION_cipher(sslSessionNativePointer);
- cipherSuite = NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.get(name);
- if (cipherSuite == null) {
- cipherSuite = name;
- }
- }
- return cipherSuite;
- }
-
- /**
- * Returns the standard version name of the SSL protocol used in all
- * connections pertaining to this SSL session.
- */
- public String getProtocol() {
- if (protocol == null) {
- protocol = NativeCrypto.SSL_SESSION_get_version(sslSessionNativePointer);
- }
- return protocol;
- }
-
- /**
- * Returns the context to which the actual SSL session is bound. A SSL
- * context consists of (1) a possible delegate, (2) a provider and (3) a
- * protocol.
- * @return the SSL context used for this session, or null if it is
- * unavailable.
- */
- public SSLSessionContext getSessionContext() {
- return sessionContext;
- }
-
- /**
- * Returns a boolean flag signaling whether a SSL session is valid
- * and available for resuming or joining or not.
- *
- * @return true if this session may be resumed.
- */
- public boolean isValid() {
- SSLSessionContext context = sessionContext;
- if (isValid
- && context != null
- && context.getSessionTimeout() != 0
- && getCreationTime() + (context.getSessionTimeout() * 1000)
- < System.currentTimeMillis()) {
- isValid = false;
- }
- return isValid;
- }
-
- /**
- * It invalidates a SSL session forbidding any resumption.
- */
- public void invalidate() {
- isValid = false;
- sessionContext = null;
- }
-
- /**
- * Returns the object which is bound to the the input parameter name.
- * This name is a sort of link to the data of the SSL session's application
- * layer, if any exists.
- *
- * @param name the name of the binding to find.
- * @return the value bound to that name, or null if the binding does not
- * exist.
- * @throws IllegalArgumentException if the argument is null.
- */
- public Object getValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- return values.get(name);
- }
-
- /**
- * Returns an array with the names (sort of links) of all the data
- * objects of the application layer bound into the SSL session.
- *
- * @return a non-null (possibly empty) array of names of the data objects
- * bound to this SSL session.
- */
- public String[] getValueNames() {
- return values.keySet().toArray(new String[values.size()]);
- }
-
- /**
- * A link (name) with the specified value object of the SSL session's
- * application layer data is created or replaced. If the new (or existing)
- * value object implements the <code>SSLSessionBindingListener</code>
- * interface, that object will be notified in due course.
- *
- * @param name the name of the link (no null are
- * accepted!)
- * @param value data object that shall be bound to
- * name.
- * @throws IllegalArgumentException if one or both argument(s) is null.
- */
- public void putValue(String name, Object value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("name == null || value == null");
- }
- Object old = values.put(name, value);
- if (value instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) value)
- .valueBound(new SSLSessionBindingEvent(this, name));
- }
- if (old instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) old)
- .valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- /**
- * Removes a link (name) with the specified value object of the SSL
- * session's application layer data.
- *
- * <p>If the value object implements the <code>SSLSessionBindingListener</code>
- * interface, the object will receive a <code>valueUnbound</code> notification.
- *
- * @param name the name of the link (no null are
- * accepted!)
- * @throws IllegalArgumentException if the argument is null.
- */
- public void removeValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- Object old = values.remove(name);
- if (old instanceof SSLSessionBindingListener) {
- SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
- listener.valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java b/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java
deleted file mode 100644
index 8576010..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSignature.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * Implements the subset of the JDK Signature interface needed for
- * signature verification using OpenSSL.
- */
-public class OpenSSLSignature extends Signature {
- private static enum EngineType {
- RSA, DSA, EC,
- };
-
- /**
- * Holds a pointer to the native message digest context.
- */
- private long ctx;
-
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Holds the type of the Java algorithm.
- */
- private final EngineType engineType;
-
- /**
- * Holds the OpenSSL name of the algorithm (lower case, no dashes).
- */
- private final String evpAlgorithm;
-
- /**
- * Holds a dummy buffer for writing single bytes to the digest.
- */
- private final byte[] singleByte = new byte[1];
-
- /**
- * Creates a new OpenSSLSignature instance for the given algorithm name.
- *
- * @param algorithm OpenSSL name of the algorithm, e.g. "RSA-SHA1".
- */
- private OpenSSLSignature(String algorithm, EngineType engineType)
- throws NoSuchAlgorithmException {
- super(algorithm);
-
- // We don't support MD2
- if ("RSA-MD2".equals(algorithm)) {
- throw new NoSuchAlgorithmException(algorithm);
- }
-
- this.engineType = engineType;
- this.evpAlgorithm = algorithm;
- }
-
- @Override
- protected void engineUpdate(byte input) {
- singleByte[0] = input;
- engineUpdate(singleByte, 0, 1);
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- if (state == SIGN) {
- if (ctx == 0) {
- try {
- ctx = NativeCrypto.EVP_SignInit(evpAlgorithm);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- NativeCrypto.EVP_SignUpdate(ctx, input, offset, len);
- } else {
- if (ctx == 0) {
- try {
- ctx = NativeCrypto.EVP_VerifyInit(evpAlgorithm);
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- NativeCrypto.EVP_VerifyUpdate(ctx, input, offset, len);
- }
- }
-
- @Override
- protected Object engineGetParameter(String param) throws InvalidParameterException {
- return null;
- }
-
- private void checkEngineType(OpenSSLKey pkey) throws InvalidKeyException {
- final int pkeyType = NativeCrypto.EVP_PKEY_type(pkey.getPkeyContext());
-
- switch (engineType) {
- case RSA:
- if (pkeyType != NativeCrypto.EVP_PKEY_RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
- break;
- case DSA:
- if (pkeyType != NativeCrypto.EVP_PKEY_DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
- break;
- case EC:
- if (pkeyType != NativeCrypto.EVP_PKEY_EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
- break;
- default:
- throw new InvalidKeyException("Need DSA or RSA or EC private key");
- }
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
- destroyContextIfExists();
-
- if (privateKey instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) privateKey).getOpenSSLKey();
- checkEngineType(pkey);
- key = pkey;
- } else if (privateKey instanceof RSAPrivateCrtKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
- key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof RSAPrivateKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
- key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof DSAPrivateKey) {
- if (engineType != EngineType.DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
-
- DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
- key = OpenSSLDSAPrivateKey.getInstance(dsaPrivateKey);
- } else if (privateKey instanceof ECPrivateKey) {
- if (engineType != EngineType.EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
-
- ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
- key = OpenSSLECPrivateKey.getInstance(ecPrivateKey);
- } else {
- throw new InvalidKeyException("Need DSA or RSA or EC private key");
- }
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- // If we had an existing context, destroy it first.
- destroyContextIfExists();
-
- if (publicKey instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) publicKey).getOpenSSLKey();
- checkEngineType(pkey);
- key = pkey;
- } else if (publicKey instanceof RSAPublicKey) {
- if (engineType != EngineType.RSA) {
- throw new InvalidKeyException("Signature not initialized as RSA");
- }
-
- RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
- key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else if (publicKey instanceof DSAPublicKey) {
- if (engineType != EngineType.DSA) {
- throw new InvalidKeyException("Signature not initialized as DSA");
- }
-
- DSAPublicKey dsaPublicKey = (DSAPublicKey) publicKey;
- key = OpenSSLDSAPublicKey.getInstance(dsaPublicKey);
- } else if (publicKey instanceof ECPublicKey) {
- if (engineType != EngineType.EC) {
- throw new InvalidKeyException("Signature not initialized as EC");
- }
-
- ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
- key = OpenSSLECPublicKey.getInstance(ecPublicKey);
- } else {
- throw new InvalidKeyException("Need DSA or RSA or EC public key");
- }
- }
-
- @Override
- protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need DSA or RSA or EC private key");
- }
-
- try {
- byte[] buffer = new byte[NativeCrypto.EVP_PKEY_size(key.getPkeyContext())];
- int bytesWritten = NativeCrypto.EVP_SignFinal(ctx, buffer, 0, key.getPkeyContext());
-
- byte[] signature = new byte[bytesWritten];
- System.arraycopy(buffer, 0, signature, 0, bytesWritten);
-
- return signature;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- /*
- * Java expects the digest context to be reset completely after sign
- * calls.
- */
- destroyContextIfExists();
- }
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need DSA or RSA public key");
- }
-
- try {
- int result = NativeCrypto.EVP_VerifyFinal(ctx, sigBytes, 0, sigBytes.length,
- key.getPkeyContext());
- return result == 1;
- } catch (Exception ex) {
- return false;
- } finally {
- /*
- * Java expects the digest context to be reset completely after
- * verify calls.
- */
- destroyContextIfExists();
- }
- }
-
- private void destroyContextIfExists() {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- ctx = 0;
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (ctx != 0) {
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
- }
- } finally {
- super.finalize();
- }
- }
-
- public static final class MD5RSA extends OpenSSLSignature {
- public MD5RSA() throws NoSuchAlgorithmException {
- super("RSA-MD5", EngineType.RSA);
- }
- }
- public static final class SHA1RSA extends OpenSSLSignature {
- public SHA1RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA1", EngineType.RSA);
- }
- }
- public static final class SHA256RSA extends OpenSSLSignature {
- public SHA256RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA256", EngineType.RSA);
- }
- }
- public static final class SHA384RSA extends OpenSSLSignature {
- public SHA384RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA384", EngineType.RSA);
- }
- }
- public static final class SHA512RSA extends OpenSSLSignature {
- public SHA512RSA() throws NoSuchAlgorithmException {
- super("RSA-SHA512", EngineType.RSA);
- }
- }
- public static final class SHA1DSA extends OpenSSLSignature {
- public SHA1DSA() throws NoSuchAlgorithmException {
- super("DSA-SHA1", EngineType.DSA);
- }
- }
- public static final class SHA1ECDSA extends OpenSSLSignature {
- public SHA1ECDSA() throws NoSuchAlgorithmException {
- super("SHA1", EngineType.EC);
- }
- }
- public static final class SHA256ECDSA extends OpenSSLSignature {
- public SHA256ECDSA() throws NoSuchAlgorithmException {
- super("SHA256", EngineType.EC);
- }
- }
- public static final class SHA384ECDSA extends OpenSSLSignature {
- public SHA384ECDSA() throws NoSuchAlgorithmException {
- super("SHA384", EngineType.EC);
- }
- }
- public static final class SHA512ECDSA extends OpenSSLSignature {
- public SHA512ECDSA() throws NoSuchAlgorithmException {
- super("SHA512", EngineType.EC);
- }
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java b/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java
deleted file mode 100644
index 9c4e4ad..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSignatureRawRSA.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidKeyException;
-import java.security.InvalidParameterException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * Implements the JDK Signature interface needed for RAW RSA signature
- * generation and verification using OpenSSL.
- */
-public class OpenSSLSignatureRawRSA extends Signature {
- /**
- * The current OpenSSL key we're operating on.
- */
- private OpenSSLKey key;
-
- /**
- * Buffer to hold value to be signed or verified.
- */
- private byte[] inputBuffer;
-
- /**
- * Current offset in input buffer.
- */
- private int inputOffset;
-
- /**
- * Provides a flag to specify when the input is too long.
- */
- private boolean inputIsTooLong;
-
- /**
- * Creates a new OpenSSLSignature instance for the given algorithm name.
- */
- public OpenSSLSignatureRawRSA() throws NoSuchAlgorithmException {
- super("NONEwithRSA");
- }
-
- @Override
- protected void engineUpdate(byte input) {
- final int oldOffset = inputOffset++;
-
- if (inputOffset > inputBuffer.length) {
- inputIsTooLong = true;
- return;
- }
-
- inputBuffer[oldOffset] = input;
- }
-
- @Override
- protected void engineUpdate(byte[] input, int offset, int len) {
- final int oldOffset = inputOffset;
- inputOffset += len;
-
- if (inputOffset > inputBuffer.length) {
- inputIsTooLong = true;
- return;
- }
-
- System.arraycopy(input, offset, inputBuffer, oldOffset, len);
- }
-
- @Override
- protected Object engineGetParameter(String param) throws InvalidParameterException {
- return null;
- }
-
- @Override
- protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
- if (privateKey instanceof OpenSSLRSAPrivateKey) {
- OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) privateKey;
- key = rsaPrivateKey.getOpenSSLKey();
- } else if (privateKey instanceof RSAPrivateCrtKey) {
- RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
- key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
- } else if (privateKey instanceof RSAPrivateKey) {
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
- key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
- } else {
- throw new InvalidKeyException("Need RSA private key");
- }
-
- // Allocate buffer according to RSA modulus size.
- int maxSize = NativeCrypto.RSA_size(key.getPkeyContext());
- inputBuffer = new byte[maxSize];
- inputOffset = 0;
- }
-
- @Override
- protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
- if (publicKey instanceof OpenSSLRSAPublicKey) {
- OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) publicKey;
- key = rsaPublicKey.getOpenSSLKey();
- } else if (publicKey instanceof RSAPublicKey) {
- RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
- key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
- } else {
- throw new InvalidKeyException("Need RSA public key");
- }
-
- // Allocate buffer according to RSA modulus size.
- int maxSize = NativeCrypto.RSA_size(key.getPkeyContext());
- inputBuffer = new byte[maxSize];
- inputOffset = 0;
- }
-
- @Override
- protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
- }
-
- @Override
- protected byte[] engineSign() throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need RSA private key");
- }
-
- if (inputIsTooLong) {
- throw new SignatureException("input length " + inputOffset + " != "
- + inputBuffer.length + " (modulus size)");
- }
-
- byte[] outputBuffer = new byte[inputBuffer.length];
- try {
- NativeCrypto.RSA_private_encrypt(inputOffset, inputBuffer, outputBuffer,
- key.getPkeyContext(), NativeCrypto.RSA_PKCS1_PADDING);
- return outputBuffer;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- inputOffset = 0;
- }
- }
-
- @Override
- protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
- if (key == null) {
- // This can't actually happen, but you never know...
- throw new SignatureException("Need RSA public key");
- }
-
- if (inputIsTooLong) {
- return false;
- }
-
- byte[] outputBuffer = new byte[inputBuffer.length];
- try {
- final int resultSize;
- try {
- resultSize = NativeCrypto.RSA_public_decrypt(sigBytes.length, sigBytes,
- outputBuffer, key.getPkeyContext(), NativeCrypto.RSA_PKCS1_PADDING);
- } catch (SignatureException e) {
- throw e;
- } catch (Exception e) {
- return false;
- }
- /* Make this constant time by comparing every byte. */
- boolean matches = (resultSize == inputOffset);
- for (int i = 0; i < resultSize; i++) {
- if (inputBuffer[i] != outputBuffer[i]) {
- matches = false;
- }
- }
- return matches;
- } catch (Exception ex) {
- throw new SignatureException(ex);
- } finally {
- inputOffset = 0;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
deleted file mode 100644
index 72fd89f..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketFactoryImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-
-public class OpenSSLSocketFactoryImpl extends javax.net.ssl.SSLSocketFactory {
-
- private final SSLParametersImpl sslParameters;
- private final IOException instantiationException;
-
- public OpenSSLSocketFactoryImpl() {
- SSLParametersImpl sslParametersLocal = null;
- IOException instantiationExceptionLocal = null;
- try {
- sslParametersLocal = SSLParametersImpl.getDefault();
- } catch (KeyManagementException e) {
- instantiationExceptionLocal = new IOException("Delayed instantiation exception:");
- instantiationExceptionLocal.initCause(e);
- }
- this.sslParameters = sslParametersLocal;
- this.instantiationException = instantiationExceptionLocal;
- }
-
- public OpenSSLSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.instantiationException = null;
- }
-
- public String[] getDefaultCipherSuites() {
- return NativeCrypto.getDefaultCipherSuites();
- }
-
- public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- public Socket createSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new OpenSSLSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return new OpenSSLSocketImpl(host, port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException, UnknownHostException {
- return new OpenSSLSocketImpl(host,
- port,
- localHost,
- localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return new OpenSSLSocketImpl(host, port, (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(InetAddress address,
- int port,
- InetAddress localAddress,
- int localPort)
- throws IOException {
- return new OpenSSLSocketImpl(address,
- port,
- localAddress,
- localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- public Socket createSocket(Socket s, String host, int port, boolean autoClose)
- throws IOException {
- return new OpenSSLSocketImplWrapper(s,
- host,
- port,
- autoClose,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
deleted file mode 100644
index 4b705d7..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
+++ /dev/null
@@ -1,1137 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import dalvik.system.BlockGuard;
-import dalvik.system.CloseGuard;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-import java.security.InvalidKeyException;
-import java.security.PrivateKey;
-import java.security.SecureRandom;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLProtocolException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.X509TrustManager;
-import javax.security.auth.x500.X500Principal;
-import static libcore.io.OsConstants.*;
-import libcore.io.ErrnoException;
-import libcore.io.Libcore;
-import libcore.io.Streams;
-import libcore.io.StructTimeval;
-
-/**
- * Implementation of the class OpenSSLSocketImpl based on OpenSSL.
- * <p>
- * Extensions to SSLSocket include:
- * <ul>
- * <li>handshake timeout
- * <li>session tickets
- * <li>Server Name Indication
- * </ul>
- */
-public class OpenSSLSocketImpl
- extends javax.net.ssl.SSLSocket
- implements NativeCrypto.SSLHandshakeCallbacks {
-
- private long sslNativePointer;
- private InputStream is;
- private OutputStream os;
- private final Object handshakeLock = new Object();
- private final Object readLock = new Object();
- private final Object writeLock = new Object();
- private SSLParametersImpl sslParameters;
- private byte[] npnProtocols;
- private byte[] alpnProtocols;
- private String[] enabledProtocols;
- private String[] enabledCipherSuites;
- private boolean useSessionTickets;
- private String hostname;
- /** Whether the TLS Channel ID extension is enabled. This field is server-side only. */
- private boolean channelIdEnabled;
- /** Private key for the TLS Channel ID extension. This field is client-side only. */
- private OpenSSLKey channelIdPrivateKey;
- private OpenSSLSessionImpl sslSession;
- private final Socket socket;
- private boolean autoClose;
- private boolean handshakeStarted = false;
- private final CloseGuard guard = CloseGuard.get();
-
- /**
- * Not set to true until the update from native that tells us the
- * full handshake is complete, since SSL_do_handshake can return
- * before the handshake is completely done due to
- * handshake_cutthrough support.
- */
- private boolean handshakeCompleted = false;
-
- private ArrayList<HandshakeCompletedListener> listeners;
-
- /**
- * Local cache of timeout to avoid getsockopt on every read and
- * write for non-wrapped sockets. Note that
- * OpenSSLSocketImplWrapper overrides setSoTimeout and
- * getSoTimeout to delegate to the wrapped socket.
- */
- private int readTimeoutMilliseconds = 0;
- private int writeTimeoutMilliseconds = 0;
-
- private int handshakeTimeoutMilliseconds = -1; // -1 = same as timeout; 0 = infinite
- private String wrappedHost;
- private int wrappedPort;
-
- protected OpenSSLSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(SSLParametersImpl sslParameters,
- String[] enabledProtocols,
- String[] enabledCipherSuites) throws IOException {
- this.socket = this;
- init(sslParameters, enabledProtocols, enabledCipherSuites);
- }
-
- protected OpenSSLSocketImpl(String host, int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(host, port);
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(InetAddress address, int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(address, port);
- this.socket = this;
- init(sslParameters);
- }
-
-
- protected OpenSSLSocketImpl(String host, int port,
- InetAddress clientAddress, int clientPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port, clientAddress, clientPort);
- this.socket = this;
- init(sslParameters);
- }
-
- protected OpenSSLSocketImpl(InetAddress address, int port,
- InetAddress clientAddress, int clientPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(address, port, clientAddress, clientPort);
- this.socket = this;
- init(sslParameters);
- }
-
- /**
- * Create an SSL socket that wraps another socket. Invoked by
- * OpenSSLSocketImplWrapper constructor.
- */
- protected OpenSSLSocketImpl(Socket socket, String host, int port,
- boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
- this.socket = socket;
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.autoClose = autoClose;
- init(sslParameters);
-
- // this.timeout is not set intentionally.
- // OpenSSLSocketImplWrapper.getSoTimeout will delegate timeout
- // to wrapped socket
- }
-
- /**
- * Initialize the SSL socket and set the certificates for the
- * future handshaking.
- */
- private void init(SSLParametersImpl sslParameters) throws IOException {
- init(sslParameters,
- NativeCrypto.getDefaultProtocols(),
- NativeCrypto.getDefaultCipherSuites());
- }
-
- /**
- * Initialize the SSL socket and set the certificates for the
- * future handshaking.
- */
- private void init(SSLParametersImpl sslParameters,
- String[] enabledProtocols,
- String[] enabledCipherSuites) throws IOException {
- this.sslParameters = sslParameters;
- this.enabledProtocols = enabledProtocols;
- this.enabledCipherSuites = enabledCipherSuites;
- }
-
- /**
- * Gets the suitable session reference from the session cache container.
- */
- private OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext) {
- String hostName = getPeerHostName();
- int port = getPeerPort();
- if (hostName == null) {
- return null;
- }
- OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession(hostName, port);
- if (session == null) {
- return null;
- }
-
- String protocol = session.getProtocol();
- boolean protocolFound = false;
- for (String enabledProtocol : enabledProtocols) {
- if (protocol.equals(enabledProtocol)) {
- protocolFound = true;
- break;
- }
- }
- if (!protocolFound) {
- return null;
- }
-
- String cipherSuite = session.getCipherSuite();
- boolean cipherSuiteFound = false;
- for (String enabledCipherSuite : enabledCipherSuites) {
- if (cipherSuite.equals(enabledCipherSuite)) {
- cipherSuiteFound = true;
- break;
- }
- }
- if (!cipherSuiteFound) {
- return null;
- }
-
- return session;
- }
-
- private void checkOpen() throws SocketException {
- if (isClosed()) {
- throw new SocketException("Socket is closed");
- }
- }
-
- /**
- * 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);
- }
-
- // setup server certificates and private keys.
- // 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)
- || enabledCipherSuite.equals(NativeCrypto.TLS_FALLBACK_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);
- }
- }
-
- int 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();
- }
- }
- }
-
- private static byte[][] encodeIssuerX509Principals(X509Certificate[] certificates)
- throws CertificateEncodingException {
- byte[][] principalBytes = new byte[certificates.length][];
- for (int i = 0; i < certificates.length; i++) {
- principalBytes[i] = certificates[i].getIssuerX500Principal().getEncoded();
- }
- return principalBytes;
- }
-
- String getPeerHostName() {
- if (wrappedHost != null) {
- return wrappedHost;
- }
- InetAddress inetAddress = super.getInetAddress();
- if (inetAddress != null) {
- return inetAddress.getHostName();
- }
- return null;
- }
-
- int getPeerPort() {
- return wrappedHost == null ? super.getPort() : wrappedPort;
- }
-
- /**
- * Return a possibly null array of X509Certificates given the
- * possibly null array of DER encoded bytes.
- */
- private static X509Certificate[] createCertChain(byte[][] certificatesBytes) throws IOException {
- if (certificatesBytes == null) {
- return null;
- }
- X509Certificate[] certificates = new X509Certificate[certificatesBytes.length];
- for (int i = 0; i < certificatesBytes.length; i++) {
- certificates[i] = OpenSSLX509Certificate.fromX509Der(certificatesBytes[i]);
- }
- return certificates;
- }
-
- private void setCertificate(String alias) throws CertificateEncodingException, SSLException {
- if (alias == null) {
- return;
- }
- PrivateKey privateKey = sslParameters.getKeyManager().getPrivateKey(alias);
- if (privateKey == null) {
- return;
- }
- X509Certificate[] certificates = sslParameters.getKeyManager().getCertificateChain(alias);
- if (certificates == null) {
- return;
- }
-
- // Note that OpenSSL says to use SSL_use_certificate before SSL_use_PrivateKey.
-
- byte[][] certificateBytes = NativeCrypto.encodeCertificates(certificates);
- NativeCrypto.SSL_use_certificate(sslNativePointer, certificateBytes);
-
- try {
- final OpenSSLKey key = OpenSSLKey.fromPrivateKey(privateKey);
- NativeCrypto.SSL_use_PrivateKey(sslNativePointer, key.getPkeyContext());
- } catch (InvalidKeyException e) {
- throw new SSLException(e);
- }
-
- // checks the last installed private key and certificate,
- // so need to do this once per loop iteration
- NativeCrypto.SSL_check_private_key(sslNativePointer);
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / client_cert_cb
- public void clientCertificateRequested(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals)
- throws CertificateEncodingException, SSLException {
-
- String[] keyTypes = new String[keyTypeBytes.length];
- for (int i = 0; i < keyTypeBytes.length; i++) {
- keyTypes[i] = CipherSuite.getClientKeyType(keyTypeBytes[i]);
- }
-
- X500Principal[] issuers;
- if (asn1DerEncodedPrincipals == null) {
- issuers = null;
- } else {
- issuers = new X500Principal[asn1DerEncodedPrincipals.length];
- for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) {
- issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]);
- }
- }
- setCertificate(sslParameters.getKeyManager().chooseClientAlias(keyTypes, issuers, this));
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks / info_callback
- public void handshakeCompleted() {
- handshakeCompleted = true;
-
- // If sslSession is null, the handshake was completed during
- // the call to NativeCrypto.SSL_do_handshake and not during a
- // later read operation. That means we do not need to fix up
- // the SSLSession and session cache or notify
- // HandshakeCompletedListeners, it will be done in
- // startHandshake.
- if (sslSession == null) {
- return;
- }
-
- // reset session id from the native pointer and update the
- // appropriate cache.
- sslSession.resetId();
- AbstractSessionContext sessionContext =
- (sslParameters.getUseClientMode())
- ? sslParameters.getClientSessionContext()
- : sslParameters.getServerSessionContext();
- sessionContext.putSession(sslSession);
-
- // let listeners know we are finally done
- notifyHandshakeCompletedListeners();
- }
-
- private void notifyHandshakeCompletedListeners() {
- if (listeners != null && !listeners.isEmpty()) {
- // notify the listeners
- HandshakeCompletedEvent event =
- new HandshakeCompletedEvent(this, sslSession);
- for (HandshakeCompletedListener listener : listeners) {
- try {
- listener.handshakeCompleted(event);
- } catch (RuntimeException e) {
- // The RI runs the handlers in a separate thread,
- // which we do not. But we try to preserve their
- // behavior of logging a problem and not killing
- // the handshaking thread just because a listener
- // has a problem.
- Thread thread = Thread.currentThread();
- thread.getUncaughtExceptionHandler().uncaughtException(thread, e);
- }
- }
- }
- }
-
- @SuppressWarnings("unused") // used by NativeCrypto.SSLHandshakeCallbacks
- @Override public void verifyCertificateChain(byte[][] bytes, String authMethod)
- throws CertificateException {
- try {
- if (bytes == null || bytes.length == 0) {
- throw new SSLException("Peer sent no certificate");
- }
- X509Certificate[] peerCertificateChain = new X509Certificate[bytes.length];
- for (int i = 0; i < bytes.length; i++) {
- peerCertificateChain[i] = OpenSSLX509Certificate.fromX509Der(bytes[i]);
- }
- boolean client = sslParameters.getUseClientMode();
- if (client) {
- X509TrustManager x509tm = sslParameters.getTrustManager();
- if (x509tm instanceof TrustManagerImpl) {
- TrustManagerImpl tm = (TrustManagerImpl) x509tm;
- tm.checkServerTrusted(peerCertificateChain, authMethod, wrappedHost);
- } else {
- x509tm.checkServerTrusted(peerCertificateChain, authMethod);
- }
- } else {
- String authType = peerCertificateChain[0].getPublicKey().getAlgorithm();
- sslParameters.getTrustManager().checkClientTrusted(peerCertificateChain,
- authType);
- }
-
- } catch (CertificateException e) {
- throw e;
- } catch (Exception e) {
- throw new CertificateException(e);
- }
- }
-
- @Override public InputStream getInputStream() throws IOException {
- checkOpen();
- synchronized (this) {
- if (is == null) {
- is = new SSLInputStream();
- }
-
- return is;
- }
- }
-
- @Override public OutputStream getOutputStream() throws IOException {
- checkOpen();
- synchronized (this) {
- if (os == null) {
- os = new SSLOutputStream();
- }
-
- return os;
- }
- }
-
- /**
- * This inner class provides input data stream functionality
- * for the OpenSSL native implementation. It is used to
- * read data received via SSL protocol.
- */
- private class SSLInputStream extends InputStream {
- SSLInputStream() throws IOException {
- /*
- * Note: When startHandshake() throws an exception, no
- * SSLInputStream object will be created.
- */
- OpenSSLSocketImpl.this.startHandshake();
- }
-
- /**
- * Reads one byte. If there is no data in the underlying buffer,
- * this operation can block until the data will be
- * available.
- * @return read value.
- * @throws <code>IOException</code>
- */
- @Override
- public int read() throws IOException {
- return Streams.readSingleByte(this);
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.InputStream#read(byte[],int,int)
- */
- @Override
- public int read(byte[] buf, int offset, int byteCount) throws IOException {
- BlockGuard.getThreadPolicy().onNetwork();
- synchronized (readLock) {
- checkOpen();
- Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
- if (byteCount == 0) {
- return 0;
- }
- return NativeCrypto.SSL_read(sslNativePointer, socket.getFileDescriptor$(),
- OpenSSLSocketImpl.this, buf, offset, byteCount, getSoTimeout());
- }
- }
- }
-
- /**
- * This inner class provides output data stream functionality
- * for the OpenSSL native implementation. It is used to
- * write data according to the encryption parameters given in SSL context.
- */
- private class SSLOutputStream extends OutputStream {
- SSLOutputStream() throws IOException {
- /*
- * Note: When startHandshake() throws an exception, no
- * SSLOutputStream object will be created.
- */
- OpenSSLSocketImpl.this.startHandshake();
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.OutputStream#write(int)
- */
- @Override
- public void write(int oneByte) throws IOException {
- Streams.writeSingleByte(this, oneByte);
- }
-
- /**
- * Method acts as described in spec for superclass.
- * @see java.io.OutputStream#write(byte[],int,int)
- */
- @Override
- public void write(byte[] buf, int offset, int byteCount) throws IOException {
- BlockGuard.getThreadPolicy().onNetwork();
- synchronized (writeLock) {
- checkOpen();
- Arrays.checkOffsetAndCount(buf.length, offset, byteCount);
- if (byteCount == 0) {
- return;
- }
- NativeCrypto.SSL_write(sslNativePointer, socket.getFileDescriptor$(),
- OpenSSLSocketImpl.this, buf, offset, byteCount, writeTimeoutMilliseconds);
- }
- }
- }
-
-
- @Override public SSLSession getSession() {
- if (sslSession == null) {
- try {
- startHandshake();
- } catch (IOException e) {
- // return an invalid session with
- // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
- return SSLSessionImpl.getNullSession();
- }
- }
- return sslSession;
- }
-
- @Override public void addHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- listeners = new ArrayList<HandshakeCompletedListener>();
- }
- listeners.add(listener);
- }
-
- @Override public void removeHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- if (!listeners.remove(listener)) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- }
-
- @Override public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- @Override public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- @Override public String[] getSupportedCipherSuites() {
- return NativeCrypto.getSupportedCipherSuites();
- }
-
- @Override public String[] getEnabledCipherSuites() {
- return enabledCipherSuites.clone();
- }
-
- @Override public void setEnabledCipherSuites(String[] suites) {
- enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(suites);
- }
-
- @Override public String[] getSupportedProtocols() {
- return NativeCrypto.getSupportedProtocols();
- }
-
- @Override public String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- @Override public void setEnabledProtocols(String[] protocols) {
- enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols);
- }
-
- /**
- * This method enables session ticket support.
- *
- * @param useSessionTickets True to enable session tickets
- */
- public void setUseSessionTickets(boolean useSessionTickets) {
- this.useSessionTickets = useSessionTickets;
- }
-
- /**
- * This method enables Server Name Indication
- *
- * @param hostname the desired SNI hostname, or null to disable
- */
- public void setHostname(String hostname) {
- this.hostname = hostname;
- }
-
- /**
- * Enables/disables TLS Channel ID for this server socket.
- *
- * <p>This method needs to be invoked before the handshake starts.
- *
- * @throws IllegalStateException if this is a client socket or if the handshake has already
- * started.
-
- */
- public void setChannelIdEnabled(boolean enabled) {
- if (getUseClientMode()) {
- throw new IllegalStateException("Client mode");
- }
- if (handshakeStarted) {
- throw new IllegalStateException(
- "Could not enable/disable Channel ID after the initial handshake has"
- + " begun.");
- }
- this.channelIdEnabled = enabled;
- }
-
- /**
- * Gets the TLS Channel ID for this server socket. Channel ID is only available once the
- * handshake completes.
- *
- * @return channel ID or {@code null} if not available.
- *
- * @throws IllegalStateException if this is a client socket or if the handshake has not yet
- * completed.
- * @throws SSLException if channel ID is available but could not be obtained.
- */
- public byte[] getChannelId() throws SSLException {
- if (getUseClientMode()) {
- throw new IllegalStateException("Client mode");
- }
- if (!handshakeCompleted) {
- throw new IllegalStateException(
- "Channel ID is only available after handshake completes");
- }
- return NativeCrypto.SSL_get_tls_channel_id(sslNativePointer);
- }
-
- /**
- * Sets the {@link PrivateKey} to be used for TLS Channel ID by this client socket.
- *
- * <p>This method needs to be invoked before the handshake starts.
- *
- * @param privateKey private key (enables TLS Channel ID) or {@code null} for no key (disables
- * TLS Channel ID). The private key must be an Elliptic Curve (EC) key based on the NIST
- * P-256 curve (aka SECG secp256r1 or ANSI X9.62 prime256v1).
- *
- * @throws IllegalStateException if this is a server socket or if the handshake has already
- * started.
- */
- public void setChannelIdPrivateKey(PrivateKey privateKey) {
- if (!getUseClientMode()) {
- throw new IllegalStateException("Server mode");
- }
- if (handshakeStarted) {
- throw new IllegalStateException(
- "Could not change Channel ID private key after the initial handshake has"
- + " begun.");
- }
- if (privateKey == null) {
- this.channelIdEnabled = false;
- this.channelIdPrivateKey = null;
- } else {
- this.channelIdEnabled = true;
- try {
- this.channelIdPrivateKey = OpenSSLKey.fromPrivateKey(privateKey);
- } catch (InvalidKeyException e) {
- // Will have error in startHandshake
- }
- }
- }
-
- @Override public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- @Override public void setUseClientMode(boolean mode) {
- if (handshakeStarted) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- }
-
- @Override public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- @Override public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- @Override public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- @Override public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- @Override public void sendUrgentData(int data) throws IOException {
- throw new SocketException("Method sendUrgentData() is not supported.");
- }
-
- @Override public void setOOBInline(boolean on) throws SocketException {
- throw new SocketException("Methods sendUrgentData, setOOBInline are not supported.");
- }
-
- @Override public void setSoTimeout(int readTimeoutMilliseconds) throws SocketException {
- super.setSoTimeout(readTimeoutMilliseconds);
- this.readTimeoutMilliseconds = readTimeoutMilliseconds;
- }
-
- @Override public int getSoTimeout() throws SocketException {
- return readTimeoutMilliseconds;
- }
-
- /**
- * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
- */
- public void setSoWriteTimeout(int writeTimeoutMilliseconds) throws SocketException {
- this.writeTimeoutMilliseconds = writeTimeoutMilliseconds;
-
- StructTimeval tv = StructTimeval.fromMillis(writeTimeoutMilliseconds);
- try {
- Libcore.os.setsockoptTimeval(getFileDescriptor$(), SOL_SOCKET, SO_SNDTIMEO, tv);
- } catch (ErrnoException errnoException) {
- throw errnoException.rethrowAsSocketException();
- }
- }
-
- /**
- * Note write timeouts are not part of the javax.net.ssl.SSLSocket API
- */
- public int getSoWriteTimeout() throws SocketException {
- return writeTimeoutMilliseconds;
- }
-
- /**
- * Set the handshake timeout on this socket. This timeout is specified in
- * milliseconds and will be used only during the handshake process.
- */
- public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketException {
- this.handshakeTimeoutMilliseconds = handshakeTimeoutMilliseconds;
- }
-
- @Override public void close() throws IOException {
- // TODO: Close SSL sockets using a background thread so they close gracefully.
-
- synchronized (handshakeLock) {
- if (!handshakeStarted) {
- // prevent further attempts to start handshake
- handshakeStarted = true;
-
- synchronized (this) {
- free();
-
- if (socket != this) {
- if (autoClose && !socket.isClosed()) socket.close();
- } else {
- if (!super.isClosed()) super.close();
- }
- }
-
- return;
- }
- }
-
- synchronized (this) {
-
- // Interrupt any outstanding reads or writes before taking the writeLock and readLock
- NativeCrypto.SSL_interrupt(sslNativePointer);
-
- synchronized (writeLock) {
- synchronized (readLock) {
- // Shut down the SSL connection, per se.
- try {
- if (handshakeStarted) {
- BlockGuard.getThreadPolicy().onNetwork();
- NativeCrypto.SSL_shutdown(sslNativePointer, socket.getFileDescriptor$(),
- this);
- }
- } catch (IOException ignored) {
- /*
- * Note that although close() can throw
- * IOException, the RI does not throw if there
- * is problem sending a "close notify" which
- * can happen if the underlying socket is closed.
- */
- } finally {
- /*
- * Even if the above call failed, it is still safe to free
- * the native structs, and we need to do so lest we leak
- * memory.
- */
- free();
-
- if (socket != this) {
- if (autoClose && !socket.isClosed()) {
- socket.close();
- }
- } else {
- if (!super.isClosed()) {
- super.close();
- }
- }
- }
- }
- }
- }
- }
-
- private void free() {
- if (sslNativePointer == 0) {
- return;
- }
- NativeCrypto.SSL_free(sslNativePointer);
- sslNativePointer = 0;
- guard.close();
- }
-
- @Override protected void finalize() throws Throwable {
- try {
- /*
- * Just worry about our own state. Notably we do not try and
- * close anything. The SocketImpl, either our own
- * PlainSocketImpl, or the Socket we are wrapping, will do
- * that. This might mean we do not properly SSL_shutdown, but
- * if you want to do that, properly close the socket yourself.
- *
- * The reason why we don't try to SSL_shutdown, is that there
- * can be a race between finalizers where the PlainSocketImpl
- * finalizer runs first and closes the socket. However, in the
- * meanwhile, the underlying file descriptor could be reused
- * for another purpose. If we call SSL_shutdown, the
- * underlying socket BIOs still have the old file descriptor
- * and will write the close notify to some unsuspecting
- * reader.
- */
- if (guard != null) {
- guard.warnIfOpen();
- }
- free();
- } finally {
- super.finalize();
- }
- }
-
- @Override
- public FileDescriptor getFileDescriptor$() {
- if (socket == this) {
- return super.getFileDescriptor$();
- } else {
- return socket.getFileDescriptor$();
- }
- }
-
- /**
- * Returns the protocol agreed upon by client and server, or null if no
- * protocol was agreed upon.
- */
- public byte[] getNpnSelectedProtocol() {
- return NativeCrypto.SSL_get_npn_negotiated_protocol(sslNativePointer);
- }
-
- /**
- * Returns the protocol agreed upon by client and server, or {@code null} if
- * no protocol was agreed upon.
- */
- public byte[] getAlpnSelectedProtocol() {
- return NativeCrypto.SSL_get0_alpn_selected(sslNativePointer);
- }
-
- /**
- * Sets the list of protocols this peer is interested in. If null no
- * protocols will be used.
- *
- * @param npnProtocols a non-empty array of protocol names. From
- * SSL_select_next_proto, "vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length. A byte
- * string of length 0 is invalid. No byte string may be truncated.".
- */
- public void setNpnProtocols(byte[] npnProtocols) {
- if (npnProtocols != null && npnProtocols.length == 0) {
- throw new IllegalArgumentException("npnProtocols.length == 0");
- }
- this.npnProtocols = npnProtocols;
- }
-
- /**
- * Sets the list of protocols this peer is interested in. If the list is
- * {@code null}, no protocols will be used.
- *
- * @param alpnProtocols a non-empty array of protocol names. From
- * SSL_select_next_proto, "vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length.
- * A byte string of length 0 is invalid. No byte string may be
- * truncated.".
- */
- public void setAlpnProtocols(byte[] alpnProtocols) {
- if (alpnProtocols != null && alpnProtocols.length == 0) {
- throw new IllegalArgumentException("alpnProtocols.length == 0");
- }
- this.alpnProtocols = alpnProtocols;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java b/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
deleted file mode 100644
index b6f43fa..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLSocketImplWrapper.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * This class wraps the SSL functionality over an existing connected socket.
- */
-public class OpenSSLSocketImplWrapper extends OpenSSLSocketImpl {
-
- private Socket socket;
-
- protected OpenSSLSocketImplWrapper(Socket socket, String host, int port,
- boolean autoClose, SSLParametersImpl sslParameters) throws IOException {
- super(socket, host, port, autoClose, sslParameters);
- if (!socket.isConnected()) {
- throw new SocketException("Socket is not connected.");
- }
- this.socket = socket;
- }
-
- @Override
- public void connect(SocketAddress sockaddr, int timeout)
- throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void connect(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void bind(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public SocketAddress getRemoteSocketAddress() {
- return socket.getRemoteSocketAddress();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- return socket.getLocalSocketAddress();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- return socket.getLocalAddress();
- }
-
- @Override
- public InetAddress getInetAddress() {
- return socket.getInetAddress();
- }
-
- @Override
- public String toString() {
- return "SSL socket over " + socket.toString();
- }
-
- @Override
- public void setSoLinger(boolean on, int linger) throws SocketException {
- socket.setSoLinger(on, linger);
- }
-
- @Override
- public void setTcpNoDelay(boolean on) throws SocketException {
- socket.setTcpNoDelay(on);
- }
-
- @Override
- public void setReuseAddress(boolean on) throws SocketException {
- socket.setReuseAddress(on);
- }
-
- @Override
- public void setKeepAlive(boolean on) throws SocketException {
- socket.setKeepAlive(on);
- }
-
- @Override
- public void setTrafficClass(int tos) throws SocketException {
- socket.setTrafficClass(tos);
- }
-
- @Override
- public void setSoTimeout(int to) throws SocketException {
- socket.setSoTimeout(to);
- super.setSoTimeout(to);
- }
-
- @Override
- public void setSendBufferSize(int size) throws SocketException {
- socket.setSendBufferSize(size);
- }
-
- @Override
- public void setReceiveBufferSize(int size) throws SocketException {
- socket.setReceiveBufferSize(size);
- }
-
- @Override
- public boolean getTcpNoDelay() throws SocketException {
- return socket.getTcpNoDelay();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- return socket.getReuseAddress();
- }
-
- @Override
- public boolean getOOBInline() throws SocketException {
- return socket.getOOBInline();
- }
-
- @Override
- public boolean getKeepAlive() throws SocketException {
- return socket.getKeepAlive();
- }
-
- @Override
- public int getTrafficClass() throws SocketException {
- return socket.getTrafficClass();
- }
-
- @Override
- public int getSoTimeout() throws SocketException {
- return socket.getSoTimeout();
- }
-
- @Override
- public int getSoLinger() throws SocketException {
- return socket.getSoLinger();
- }
-
- @Override
- public int getSendBufferSize() throws SocketException {
- return socket.getSendBufferSize();
- }
-
- @Override
- public int getReceiveBufferSize() throws SocketException {
- return socket.getReceiveBufferSize();
- }
-
- @Override
- public boolean isConnected() {
- return socket.isConnected();
- }
-
- @Override
- public boolean isClosed() {
- return socket.isClosed();
- }
-
- @Override
- public boolean isBound() {
- return socket.isBound();
- }
-
- @Override
- public boolean isOutputShutdown() {
- return socket.isOutputShutdown();
- }
-
- @Override
- public boolean isInputShutdown() {
- return socket.isInputShutdown();
- }
-
- @Override
- public int getPort() {
- return socket.getPort();
- }
-
- @Override
- public int getLocalPort() {
- return socket.getLocalPort();
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java
deleted file mode 100644
index 56b99cc..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRL.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CRLException;
-import java.security.cert.Certificate;
-import java.security.cert.X509CRL;
-import java.security.cert.X509CRLEntry;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TimeZone;
-import javax.security.auth.x500.X500Principal;
-
-public class OpenSSLX509CRL extends X509CRL {
- private final long mContext;
-
- private OpenSSLX509CRL(long ctx) {
- mContext = ctx;
- }
-
- public static OpenSSLX509CRL fromX509DerInputStream(InputStream is) throws ParsingException {
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long crlCtx = NativeCrypto.d2i_X509_CRL_bio(bis.getBioContext());
- if (crlCtx == 0) {
- return null;
- }
- return new OpenSSLX509CRL(crlCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CRLS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509CRL(certRefs[i]));
- }
- return certs;
- }
-
- public static OpenSSLX509CRL fromX509PemInputStream(InputStream is) throws ParsingException {
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long crlCtx = NativeCrypto.PEM_read_bio_X509_CRL(bis.getBioContext());
- if (crlCtx == 0) {
- return null;
- }
- return new OpenSSLX509CRL(crlCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
- NativeCrypto.PKCS7_CRLS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509CRL> certs = new ArrayList<OpenSSLX509CRL>(certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509CRL(certRefs[i]));
- }
- return certs;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_CRL_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] nonCritOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((nonCritOids.length == 0)
- && (NativeCrypto.get_X509_CRL_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(nonCritOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- final String[] criticalOids =
- NativeCrypto.get_X509_CRL_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
- for (String oid : criticalOids) {
- final long extensionRef = NativeCrypto.X509_CRL_get_ext(mContext, oid);
- if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public byte[] getEncoded() throws CRLException {
- return NativeCrypto.i2d_X509_CRL(mContext);
- }
-
- private void verifyOpenSSL(OpenSSLKey pkey) throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- NativeCrypto.X509_CRL_verify(mContext, pkey.getPkeyContext());
- }
-
- private void verifyInternal(PublicKey key, String sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- String sigAlg = getSigAlgName();
- if (sigAlg == null) {
- sigAlg = getSigAlgOID();
- }
-
- final Signature sig;
- if (sigProvider == null) {
- sig = Signature.getInstance(sigAlg);
- } else {
- sig = Signature.getInstance(sigAlg, sigProvider);
- }
-
- sig.initVerify(key);
- sig.update(getTBSCertList());
- if (!sig.verify(getSignature())) {
- throw new SignatureException("signature did not verify");
- }
- }
-
- @Override
- public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- if (key instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- verifyOpenSSL(pkey);
- return;
- }
-
- verifyInternal(key, null);
- }
-
- @Override
- public void verify(PublicKey key, String sigProvider) throws CRLException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- verifyInternal(key, sigProvider);
- }
-
- @Override
- public int getVersion() {
- return (int) NativeCrypto.X509_CRL_get_version(mContext) + 1;
- }
-
- @Override
- public Principal getIssuerDN() {
- return getIssuerX500Principal();
- }
-
- @Override
- public X500Principal getIssuerX500Principal() {
- final byte[] issuer = NativeCrypto.X509_CRL_get_issuer_name(mContext);
- return new X500Principal(issuer);
- }
-
- @Override
- public Date getThisUpdate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_CRL_get_lastUpdate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public Date getNextUpdate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_CRL_get_nextUpdate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) {
- final long revokedRef = NativeCrypto.X509_CRL_get0_by_serial(mContext,
- serialNumber.toByteArray());
- if (revokedRef == 0) {
- return null;
- }
-
- return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(revokedRef));
- }
-
- @Override
- public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
- if (certificate instanceof OpenSSLX509Certificate) {
- OpenSSLX509Certificate osslCert = (OpenSSLX509Certificate) certificate;
- final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext,
- osslCert.getContext());
-
- if (x509RevokedRef == 0) {
- return null;
- }
-
- return new OpenSSLX509CRLEntry(NativeCrypto.X509_REVOKED_dup(x509RevokedRef));
- }
-
- return getRevokedCertificate(certificate.getSerialNumber());
- }
-
- @Override
- public Set<? extends X509CRLEntry> getRevokedCertificates() {
- final long[] entryRefs = NativeCrypto.X509_CRL_get_REVOKED(mContext);
- if (entryRefs == null || entryRefs.length == 0) {
- return null;
- }
-
- final Set<OpenSSLX509CRLEntry> crlSet = new HashSet<OpenSSLX509CRLEntry>();
- for (long entryRef : entryRefs) {
- crlSet.add(new OpenSSLX509CRLEntry(entryRef));
- }
-
- return crlSet;
- }
-
- @Override
- public byte[] getTBSCertList() throws CRLException {
- return NativeCrypto.get_X509_CRL_crl_enc(mContext);
- }
-
- @Override
- public byte[] getSignature() {
- return NativeCrypto.get_X509_CRL_signature(mContext);
- }
-
- @Override
- public String getSigAlgName() {
- return AlgNameMapper.map2AlgName(getSigAlgOID());
- }
-
- @Override
- public String getSigAlgOID() {
- return NativeCrypto.get_X509_CRL_sig_alg_oid(mContext);
- }
-
- @Override
- public byte[] getSigAlgParams() {
- return NativeCrypto.get_X509_CRL_sig_alg_parameter(mContext);
- }
-
- @Override
- public boolean isRevoked(Certificate cert) {
- if (!(cert instanceof X509Certificate)) {
- return false;
- }
-
- final OpenSSLX509Certificate osslCert;
- if (cert instanceof OpenSSLX509Certificate) {
- osslCert = (OpenSSLX509Certificate) cert;
- } else {
- try {
- osslCert = OpenSSLX509Certificate.fromX509DerInputStream(new ByteArrayInputStream(
- cert.getEncoded()));
- } catch (Exception e) {
- throw new RuntimeException("cannot convert certificate", e);
- }
- }
-
- final long x509RevokedRef = NativeCrypto.X509_CRL_get0_by_cert(mContext,
- osslCert.getContext());
-
- return x509RevokedRef != 0;
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- final long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_CRL_print(bioCtx, mContext);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mContext != 0) {
- NativeCrypto.X509_CRL_free(mContext);
- }
- } finally {
- super.finalize();
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
deleted file mode 100644
index 470cc98..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayOutputStream;
-import java.math.BigInteger;
-import java.security.cert.CRLException;
-import java.security.cert.X509CRLEntry;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.TimeZone;
-
-public class OpenSSLX509CRLEntry extends X509CRLEntry {
- private final long mContext;
-
- OpenSSLX509CRLEntry(long ctx) {
- mContext = ctx;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_REVOKED_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- final String[] criticalOids =
- NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL);
- for (String oid : criticalOids) {
- final long extensionRef = NativeCrypto.X509_REVOKED_get_ext(mContext, oid);
- if (NativeCrypto.X509_supported_extension(extensionRef) != 1) {
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public byte[] getEncoded() throws CRLException {
- return NativeCrypto.i2d_X509_REVOKED(mContext);
- }
-
- @Override
- public BigInteger getSerialNumber() {
- return new BigInteger(NativeCrypto.X509_REVOKED_get_serialNumber(mContext));
- }
-
- @Override
- public Date getRevocationDate() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.get_X509_REVOKED_revocationDate(mContext),
- calendar);
- return calendar.getTime();
- }
-
- @Override
- public boolean hasExtensions() {
- return (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length != 0)
- || (NativeCrypto.get_X509_REVOKED_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length != 0);
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_REVOKED_print(bioCtx, mContext);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java
deleted file mode 100644
index 57568b8..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertPath.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-public class OpenSSLX509CertPath extends CertPath {
- private static final byte[] PKCS7_MARKER = "-----BEGIN PKCS7".getBytes();
-
- private static final int PUSHBACK_SIZE = 64;
-
- /**
- * Supported encoding types for CerthPath. Used by the various APIs that
- * encode this into bytes such as {@link #getEncoded()}.
- */
- private enum Encoding {
- PKI_PATH("PkiPath"),
- PKCS7("PKCS7");
-
- private final String apiName;
-
- Encoding(String apiName) {
- this.apiName = apiName;
- }
-
- static Encoding findByApiName(String apiName) throws CertificateEncodingException {
- for (Encoding element : values()) {
- if (element.apiName.equals(apiName)) {
- return element;
- }
- }
-
- return null;
- }
- }
-
- /** Unmodifiable list of encodings for the API. */
- private static final List<String> ALL_ENCODINGS = Collections.unmodifiableList(Arrays
- .asList(new String[] {
- Encoding.PKI_PATH.apiName,
- Encoding.PKCS7.apiName,
- }));
-
- private static final Encoding DEFAULT_ENCODING = Encoding.PKI_PATH;
-
- private final List<? extends X509Certificate> mCertificates;
-
- static Iterator<String> getEncodingsIterator() {
- return ALL_ENCODINGS.iterator();
- }
-
- protected OpenSSLX509CertPath(List<? extends X509Certificate> certificates) {
- super("X.509");
-
- mCertificates = certificates;
- }
-
- @Override
- public List<? extends Certificate> getCertificates() {
- return Collections.unmodifiableList(mCertificates);
- }
-
- private byte[] getEncoded(Encoding encoding) throws CertificateEncodingException {
- final OpenSSLX509Certificate[] certs = new OpenSSLX509Certificate[mCertificates.size()];
- final long[] certRefs = new long[certs.length];
-
- for (int i = 0, j = certs.length - 1; j >= 0; i++, j--) {
- final X509Certificate cert = mCertificates.get(i);
-
- if (cert instanceof OpenSSLX509Certificate) {
- certs[j] = (OpenSSLX509Certificate) cert;
- } else {
- certs[j] = OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
- }
-
- certRefs[j] = certs[j].getContext();
- }
-
- switch (encoding) {
- case PKI_PATH:
- return NativeCrypto.ASN1_seq_pack_X509(certRefs);
- case PKCS7:
- return NativeCrypto.i2d_PKCS7(certRefs);
- default:
- throw new CertificateEncodingException("Unknown encoding");
- }
- }
-
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return getEncoded(DEFAULT_ENCODING);
- }
-
- @Override
- public byte[] getEncoded(String encoding) throws CertificateEncodingException {
- Encoding enc = Encoding.findByApiName(encoding);
- if (enc == null) {
- throw new CertificateEncodingException("Invalid encoding: " + encoding);
- }
-
- return getEncoded(enc);
- }
-
- @Override
- public Iterator<String> getEncodings() {
- return getEncodingsIterator();
- }
-
- 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);
- }
-
- 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);
- }
- }
-
- private static CertPath fromEncoding(InputStream inStream, Encoding encoding)
- throws CertificateException {
- switch (encoding) {
- case PKI_PATH:
- return fromPkiPathEncoding(inStream);
- case PKCS7:
- return fromPkcs7Encoding(inStream);
- default:
- throw new CertificateEncodingException("Unknown encoding");
- }
- }
-
- public static CertPath fromEncoding(InputStream inStream, String encoding)
- throws CertificateException {
- if (inStream == null) {
- throw new CertificateException("inStream == null");
- }
-
- Encoding enc = Encoding.findByApiName(encoding);
- if (enc == null) {
- throw new CertificateException("Invalid encoding: " + encoding);
- }
-
- return fromEncoding(inStream, enc);
- }
-
- public static CertPath fromEncoding(InputStream inStream) throws CertificateException {
- return fromEncoding(inStream, DEFAULT_ENCODING);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
deleted file mode 100644
index b1cd986..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509Certificate.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Principal;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.TimeZone;
-import javax.security.auth.x500.X500Principal;
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
-
-public class OpenSSLX509Certificate extends X509Certificate {
- private final long mContext;
-
- OpenSSLX509Certificate(long ctx) {
- mContext = ctx;
- }
-
- public static OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long certCtx = NativeCrypto.d2i_X509_bio(bis.getBioContext());
- if (certCtx == 0) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static OpenSSLX509Certificate fromX509Der(byte[] encoded) {
- final long certCtx = NativeCrypto.d2i_X509(encoded);
- if (certCtx == 0) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- }
-
- public static List<OpenSSLX509Certificate> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.d2i_PKCS7_bio(bis.getBioContext(), NativeCrypto.PKCS7_CERTS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- if (certRefs == null) {
- return Collections.emptyList();
- }
-
- final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
- certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509Certificate(certRefs[i]));
- }
- return certs;
- }
-
- public static OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- final OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- try {
- final long certCtx = NativeCrypto.PEM_read_bio_X509(bis.getBioContext());
- if (certCtx == 0L) {
- return null;
- }
- return new OpenSSLX509Certificate(certCtx);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
- }
-
- public static List<OpenSSLX509Certificate> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- @SuppressWarnings("resource")
- OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is);
-
- final long[] certRefs;
- try {
- certRefs = NativeCrypto.PEM_read_bio_PKCS7(bis.getBioContext(),
- NativeCrypto.PKCS7_CERTS);
- } catch (Exception e) {
- throw new ParsingException(e);
- } finally {
- NativeCrypto.BIO_free(bis.getBioContext());
- }
-
- final List<OpenSSLX509Certificate> certs = new ArrayList<OpenSSLX509Certificate>(
- certRefs.length);
- for (int i = 0; i < certRefs.length; i++) {
- if (certRefs[i] == 0) {
- continue;
- }
- certs.add(new OpenSSLX509Certificate(certRefs[i]));
- }
- return certs;
- }
-
- @Override
- public Set<String> getCriticalExtensionOIDs() {
- String[] critOids =
- NativeCrypto.get_X509_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no critical extensions, we'll check
- * non-critical extensions.
- */
- if ((critOids.length == 0)
- && (NativeCrypto.get_X509_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_NON_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(critOids));
- }
-
- @Override
- public byte[] getExtensionValue(String oid) {
- return NativeCrypto.X509_get_ext_oid(mContext, oid);
- }
-
- @Override
- public Set<String> getNonCriticalExtensionOIDs() {
- String[] nonCritOids =
- NativeCrypto.get_X509_ext_oids(mContext, NativeCrypto.EXTENSION_TYPE_NON_CRITICAL);
-
- /*
- * This API has a special case that if there are no extensions, we
- * should return null. So if we have no non-critical extensions, we'll
- * check critical extensions.
- */
- if ((nonCritOids.length == 0)
- && (NativeCrypto.get_X509_ext_oids(mContext,
- NativeCrypto.EXTENSION_TYPE_CRITICAL).length == 0)) {
- return null;
- }
-
- return new HashSet<String>(Arrays.asList(nonCritOids));
- }
-
- @Override
- public boolean hasUnsupportedCriticalExtension() {
- return (NativeCrypto.get_X509_ex_flags(mContext) & NativeCrypto.EXFLAG_CRITICAL) != 0;
- }
-
- @Override
- public void checkValidity() throws CertificateExpiredException,
- CertificateNotYetValidException {
- checkValidity(new Date());
- }
-
- @Override
- public void checkValidity(Date date) throws CertificateExpiredException,
- CertificateNotYetValidException {
- if (getNotBefore().compareTo(date) > 0) {
- throw new CertificateNotYetValidException();
- }
-
- if (getNotAfter().compareTo(date) < 0) {
- throw new CertificateExpiredException();
- }
- }
-
- @Override
- public int getVersion() {
- return (int) NativeCrypto.X509_get_version(mContext) + 1;
- }
-
- @Override
- public BigInteger getSerialNumber() {
- return new BigInteger(NativeCrypto.X509_get_serialNumber(mContext));
- }
-
- @Override
- public Principal getIssuerDN() {
- return getIssuerX500Principal();
- }
-
- @Override
- public Principal getSubjectDN() {
- return getSubjectX500Principal();
- }
-
- @Override
- public Date getNotBefore() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_get_notBefore(mContext), calendar);
- return calendar.getTime();
- }
-
- @Override
- public Date getNotAfter() {
- Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- calendar.set(Calendar.MILLISECOND, 0);
- NativeCrypto.ASN1_TIME_to_Calendar(NativeCrypto.X509_get_notAfter(mContext), calendar);
- return calendar.getTime();
- }
-
- @Override
- public byte[] getTBSCertificate() throws CertificateEncodingException {
- return NativeCrypto.get_X509_cert_info_enc(mContext);
- }
-
- @Override
- public byte[] getSignature() {
- return NativeCrypto.get_X509_signature(mContext);
- }
-
- @Override
- public String getSigAlgName() {
- return AlgNameMapper.map2AlgName(getSigAlgOID());
- }
-
- @Override
- public String getSigAlgOID() {
- return NativeCrypto.get_X509_sig_alg_oid(mContext);
- }
-
- @Override
- public byte[] getSigAlgParams() {
- return NativeCrypto.get_X509_sig_alg_parameter(mContext);
- }
-
- @Override
- public boolean[] getIssuerUniqueID() {
- return NativeCrypto.get_X509_issuerUID(mContext);
- }
-
- @Override
- public boolean[] getSubjectUniqueID() {
- return NativeCrypto.get_X509_subjectUID(mContext);
- }
-
- @Override
- public boolean[] getKeyUsage() {
- final boolean[] kusage = NativeCrypto.get_X509_ex_kusage(mContext);
- if (kusage == null) {
- return null;
- }
-
- if (kusage.length >= 9) {
- return kusage;
- }
-
- final boolean resized[] = new boolean[9];
- System.arraycopy(kusage, 0, resized, 0, kusage.length);
- return resized;
- }
-
- @Override
- public int getBasicConstraints() {
- if ((NativeCrypto.get_X509_ex_flags(mContext) & NativeCrypto.EXFLAG_CA) == 0) {
- return -1;
- }
-
- final int pathLen = NativeCrypto.get_X509_ex_pathlen(mContext);
- if (pathLen == -1) {
- return Integer.MAX_VALUE;
- }
-
- return pathLen;
- }
-
- @Override
- public byte[] getEncoded() throws CertificateEncodingException {
- return NativeCrypto.i2d_X509(mContext);
- }
-
- private void verifyOpenSSL(OpenSSLKey pkey) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- try {
- NativeCrypto.X509_verify(mContext, pkey.getPkeyContext());
- } catch (RuntimeException e) {
- throw new CertificateException(e);
- }
- }
-
- private void verifyInternal(PublicKey key, String sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- String sigAlg = getSigAlgName();
- if (sigAlg == null) {
- sigAlg = getSigAlgOID();
- }
-
- final Signature sig;
- if (sigProvider == null) {
- sig = Signature.getInstance(sigAlg);
- } else {
- sig = Signature.getInstance(sigAlg, sigProvider);
- }
-
- sig.initVerify(key);
- sig.update(getTBSCertificate());
- if (!sig.verify(getSignature())) {
- throw new SignatureException("signature did not verify");
- }
- }
-
- @Override
- public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException {
- if (key instanceof OpenSSLKeyHolder) {
- OpenSSLKey pkey = ((OpenSSLKeyHolder) key).getOpenSSLKey();
- verifyOpenSSL(pkey);
- return;
- }
-
- verifyInternal(key, null);
- }
-
- @Override
- public void verify(PublicKey key, String sigProvider) throws CertificateException,
- NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException,
- SignatureException {
- verifyInternal(key, sigProvider);
- }
-
- @Override
- public String toString() {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- long bioCtx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.X509_print_ex(bioCtx, mContext, 0, 0);
- return os.toString();
- } finally {
- NativeCrypto.BIO_free(bioCtx);
- }
- }
-
- @Override
- public PublicKey getPublicKey() {
- /* First try to generate the key from supported OpenSSL key types. */
- try {
- OpenSSLKey pkey = new OpenSSLKey(NativeCrypto.X509_get_pubkey(mContext));
- return pkey.getPublicKey();
- } catch (NoSuchAlgorithmException ignored) {
- }
-
- /* Try generating the key using other Java providers. */
- String oid = NativeCrypto.get_X509_pubkey_oid(mContext);
- byte[] encoded = NativeCrypto.i2d_X509_PUBKEY(mContext);
- try {
- KeyFactory kf = KeyFactory.getInstance(oid);
- return kf.generatePublic(new X509EncodedKeySpec(encoded));
- } catch (NoSuchAlgorithmException ignored) {
- } catch (InvalidKeySpecException ignored) {
- }
-
- /*
- * We couldn't find anything else, so just return a nearly-unusable
- * X.509-encoded key.
- */
- return new X509PublicKey(oid, encoded);
- }
-
- @Override
- public X500Principal getIssuerX500Principal() {
- final byte[] issuer = NativeCrypto.X509_get_issuer_name(mContext);
- return new X500Principal(issuer);
- }
-
- @Override
- public X500Principal getSubjectX500Principal() {
- final byte[] subject = NativeCrypto.X509_get_subject_name(mContext);
- return new X500Principal(subject);
- }
-
- @Override
- public List<String> getExtendedKeyUsage() throws CertificateParsingException {
- String[] extUsage = NativeCrypto.get_X509_ex_xkusage(mContext);
- if (extUsage == null) {
- return null;
- }
-
- return Arrays.asList(extUsage);
- }
-
- private static Collection<List<?>> alternativeNameArrayToList(Object[][] altNameArray) {
- if (altNameArray == null) {
- return null;
- }
-
- Collection<List<?>> coll = new ArrayList<List<?>>(altNameArray.length);
- for (int i = 0; i < altNameArray.length; i++) {
- coll.add(Collections.unmodifiableList(Arrays.asList(altNameArray[i])));
- }
-
- return Collections.unmodifiableCollection(coll);
- }
-
- @Override
- public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
- return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext,
- NativeCrypto.GN_STACK_SUBJECT_ALT_NAME));
- }
-
- @Override
- public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
- return alternativeNameArrayToList(NativeCrypto.get_X509_GENERAL_NAME_stack(mContext,
- NativeCrypto.GN_STACK_ISSUER_ALT_NAME));
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof OpenSSLX509Certificate) {
- OpenSSLX509Certificate o = (OpenSSLX509Certificate) other;
-
- return NativeCrypto.X509_cmp(mContext, o.mContext) == 0;
- }
-
- return super.equals(other);
- }
-
- @Override
- public int hashCode() {
- /* Make this faster since we might be in hash-based structures. */
- return NativeCrypto.get_X509_hashCode(mContext);
- }
-
- long getContext() {
- return mContext;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mContext != 0) {
- NativeCrypto.X509_free(mContext);
- }
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java b/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java
deleted file mode 100644
index 75fdedb..0000000
--- a/crypto/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.security.cert.CRL;
-import java.security.cert.CRLException;
-import java.security.cert.CertPath;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactorySpi;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-public class OpenSSLX509CertificateFactory extends CertificateFactorySpi {
- private static final byte[] PKCS7_MARKER = "-----BEGIN PKCS7".getBytes();
-
- private static final int PUSHBACK_SIZE = 64;
-
- static class ParsingException extends Exception {
- private static final long serialVersionUID = 8390802697728301325L;
-
- public ParsingException(String message) {
- super(message);
- }
-
- public ParsingException(Exception cause) {
- super(cause);
- }
-
- public ParsingException(String message, Exception cause) {
- super(message, cause);
- }
- }
-
- /**
- * The code for X509 Certificates and CRL is pretty much the same. We use
- * this abstract class to share the code between them. This makes it ugly,
- * but it's already written in this language anyway.
- */
- private static abstract class Parser<T> {
- public T generateItem(InputStream inStream) throws ParsingException {
- if (inStream == null) {
- throw new ParsingException("inStream == null");
- }
-
- final boolean markable = inStream.markSupported();
- if (markable) {
- inStream.mark(PKCS7_MARKER.length);
- }
-
- 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 (buffer[0] == '-') {
- if (len == PKCS7_MARKER.length && Arrays.equals(PKCS7_MARKER, buffer)) {
- List<? extends T> items = fromPkcs7PemInputStream(pbis);
- if (items.size() == 0) {
- return null;
- }
- items.get(0);
- } else {
- return fromX509PemInputStream(pbis);
- }
- }
-
- /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
- if (buffer[4] == 0x06) {
- List<? extends T> certs = fromPkcs7DerInputStream(pbis);
- if (certs.size() == 0) {
- return null;
- }
- return certs.get(0);
- } else {
- return fromX509DerInputStream(pbis);
- }
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new ParsingException(e);
- }
- }
-
- public Collection<? extends T> generateItems(InputStream inStream)
- throws ParsingException {
- if (inStream == null) {
- throw new ParsingException("inStream == null");
- }
- try {
- if (inStream.available() == 0) {
- return Collections.emptyList();
- }
- } catch (IOException e) {
- throw new ParsingException("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 fromPkcs7PemInputStream(pbis);
- }
-
- /* PKCS#7 bags have a byte 0x06 at position 4 in the stream. */
- if (buffer[4] == 0x06) {
- return fromPkcs7DerInputStream(pbis);
- }
- } catch (Exception e) {
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
- throw new ParsingException(e);
- }
-
- /*
- * It wasn't, so just try to keep grabbing certificates until we
- * can't anymore.
- */
- final List<T> coll = new ArrayList<T>();
- T c = null;
- do {
- /*
- * If this stream supports marking, try to mark here in case
- * there is an error during certificate generation.
- */
- if (markable) {
- inStream.mark(PUSHBACK_SIZE);
- }
-
- try {
- c = generateItem(pbis);
- coll.add(c);
- } catch (ParsingException e) {
- /*
- * If this stream supports marking, attempt to reset it to
- * the mark before the failure.
- */
- if (markable) {
- try {
- inStream.reset();
- } catch (IOException ignored) {
- }
- }
-
- c = null;
- }
- } while (c != null);
-
- return coll;
- }
-
- protected abstract T fromX509PemInputStream(InputStream pbis) throws ParsingException;
-
- protected abstract T fromX509DerInputStream(InputStream pbis) throws ParsingException;
-
- protected abstract List<? extends T> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException;
-
- protected abstract List<? extends T> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException;
- }
-
- private Parser<OpenSSLX509Certificate> certificateParser =
- new Parser<OpenSSLX509Certificate>() {
- @Override
- public OpenSSLX509Certificate fromX509PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509Certificate.fromX509PemInputStream(is);
- }
-
- @Override
- public OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509Certificate.fromX509DerInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509Certificate>
- fromPkcs7PemInputStream(InputStream is) throws ParsingException {
- return OpenSSLX509Certificate.fromPkcs7PemInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509Certificate>
- fromPkcs7DerInputStream(InputStream is) throws ParsingException {
- return OpenSSLX509Certificate.fromPkcs7DerInputStream(is);
- }
- };
-
- private Parser<OpenSSLX509CRL> crlParser =
- new Parser<OpenSSLX509CRL>() {
- @Override
- public OpenSSLX509CRL fromX509PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromX509PemInputStream(is);
- }
-
- @Override
- public OpenSSLX509CRL fromX509DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromX509DerInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromPkcs7PemInputStream(is);
- }
-
- @Override
- public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
- throws ParsingException {
- return OpenSSLX509CRL.fromPkcs7DerInputStream(is);
- }
- };
-
- @Override
- public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException {
- try {
- return certificateParser.generateItem(inStream);
- } catch (ParsingException e) {
- throw new CertificateException(e);
- }
- }
-
- @Override
- public Collection<? extends Certificate> engineGenerateCertificates(
- InputStream inStream) throws CertificateException {
- try {
- return certificateParser.generateItems(inStream);
- } catch (ParsingException e) {
- throw new CertificateException(e);
- }
- }
-
- @Override
- public CRL engineGenerateCRL(InputStream inStream) throws CRLException {
- try {
- return crlParser.generateItem(inStream);
- } catch (ParsingException e) {
- throw new CRLException(e);
- }
- }
-
- @Override
- public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException {
- if (inStream == null) {
- return Collections.emptyList();
- }
-
- try {
- return crlParser.generateItems(inStream);
- } catch (ParsingException e) {
- throw new CRLException(e);
- }
- }
-
- @Override
- public Iterator<String> engineGetCertPathEncodings() {
- return OpenSSLX509CertPath.getEncodingsIterator();
- }
-
- @Override
- public CertPath engineGenerateCertPath(InputStream inStream) throws CertificateException {
- return OpenSSLX509CertPath.fromEncoding(inStream);
- }
-
- @Override
- public CertPath engineGenerateCertPath(InputStream inStream, String encoding)
- throws CertificateException {
- return OpenSSLX509CertPath.fromEncoding(inStream, encoding);
- }
-
- @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);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/PRF.java b/crypto/src/main/java/org/conscrypt/PRF.java
deleted file mode 100644
index afbbb45..0000000
--- a/crypto/src/main/java/org/conscrypt/PRF.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.net.ssl.SSLException;
-
-/**
- * This class provides functionality for computation
- * of PRF values for TLS (http://www.ietf.org/rfc/rfc2246.txt)
- * and SSL v3 (http://wp.netscape.com/eng/ssl3) protocols.
- */
-public class PRF {
- private static Logger.Stream logger = Logger.getStream("prf");
-
- private static Mac md5_mac;
- private static Mac sha_mac;
- protected static MessageDigest md5;
- protected static MessageDigest sha;
- private static int md5_mac_length;
- private static int sha_mac_length;
-
- static private void init() {
- try {
- md5_mac = Mac.getInstance("HmacMD5");
- sha_mac = Mac.getInstance("HmacSHA1");
- } catch (NoSuchAlgorithmException e) {
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "There is no provider of HmacSHA1 or HmacMD5 "
- + "algorithms installed in the system"));
- }
- md5_mac_length = md5_mac.getMacLength();
- sha_mac_length = sha_mac.getMacLength();
- try {
- md5 = MessageDigest.getInstance("MD5");
- sha = MessageDigest.getInstance("SHA-1");
- } catch (Exception e) {
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "Could not initialize the Digest Algorithms."));
- }
- }
-
- /**
- * Computes the value of SSLv3 pseudo random function.
- * @param out: the buffer to fill up with the value of the function.
- * @param secret: the buffer containing the secret value to generate prf.
- * @param seed: the seed to be used.
- */
- static synchronized void computePRF_SSLv3(byte[] out, byte[] secret, byte[] seed) {
- if (sha == null) {
- init();
- }
- int pos = 0;
- int iteration = 1;
- byte[] digest;
- while (pos < out.length) {
- byte[] pref = new byte[iteration];
- Arrays.fill(pref, (byte) (64 + iteration++));
- sha.update(pref);
- sha.update(secret);
- sha.update(seed);
- md5.update(secret);
- md5.update(sha.digest());
- digest = md5.digest(); // length == 16
- if (pos + 16 > out.length) {
- System.arraycopy(digest, 0, out, pos, out.length - pos);
- pos = out.length;
- } else {
- System.arraycopy(digest, 0, out, pos, 16);
- pos += 16;
- }
- }
- }
-
- /**
- * Computes the value of TLS pseudo random function.
- * @param out: the buffer to fill up with the value of the function.
- * @param secret: the buffer containing the secret value to generate prf.
- * @param str_bytes: the label bytes to be used.
- * @param seed: the seed to be used.
- */
- synchronized static void computePRF(byte[] out, byte[] secret,
- byte[] str_byts, byte[] seed) throws GeneralSecurityException {
- if (sha_mac == null) {
- init();
- }
- // Do concatenation of the label with the seed:
- // (metterings show that is is faster to concatenate the arrays
- // and to call HMAC.update on cancatenation, than twice call for
- // each of the part, i.e.:
- // time(HMAC.update(label+seed))
- // < time(HMAC.update(label)) + time(HMAC.update(seed))
- // but it takes more memmory (approximaty on 4%)
- /*
- byte[] tmp_seed = new byte[seed.length + str_byts.length];
- System.arraycopy(str_byts, 0, tmp_seed, 0, str_byts.length);
- System.arraycopy(seed, 0, tmp_seed, str_byts.length, seed.length);
- seed = tmp_seed;
- */
- SecretKeySpec keyMd5;
- SecretKeySpec keySha1;
- if ((secret == null) || (secret.length == 0)) {
- secret = new byte[8];
- keyMd5 = new SecretKeySpec(secret, "HmacMD5");
- keySha1 = new SecretKeySpec(secret, "HmacSHA1");
- } else {
- int length = secret.length >> 1; // division by 2
- int offset = secret.length & 1; // remainder
- keyMd5 = new SecretKeySpec(secret, 0, length + offset,
- "HmacMD5");
- keySha1 = new SecretKeySpec(secret, length, length
- + offset, "HmacSHA1");
- }
-
- //byte[] str_byts = label.getBytes();
-
- if (logger != null) {
- logger.println("secret["+secret.length+"]: ");
- logger.printAsHex(16, "", " ", secret);
- logger.println("label["+str_byts.length+"]: ");
- logger.printAsHex(16, "", " ", str_byts);
- logger.println("seed["+seed.length+"]: ");
- logger.printAsHex(16, "", " ", seed);
- logger.println("MD5 key:");
- logger.printAsHex(16, "", " ", keyMd5.getEncoded());
- logger.println("SHA1 key:");
- logger.printAsHex(16, "", " ", keySha1.getEncoded());
- }
-
- md5_mac.init(keyMd5);
- sha_mac.init(keySha1);
-
- int pos = 0;
- md5_mac.update(str_byts);
- byte[] hash = md5_mac.doFinal(seed); // A(1)
- while (pos < out.length) {
- md5_mac.update(hash);
- md5_mac.update(str_byts);
- md5_mac.update(seed);
- if (pos + md5_mac_length < out.length) {
- md5_mac.doFinal(out, pos);
- pos += md5_mac_length;
- } else {
- System.arraycopy(md5_mac.doFinal(), 0, out,
- pos, out.length - pos);
- break;
- }
- // make A(i)
- hash = md5_mac.doFinal(hash);
- }
- if (logger != null) {
- logger.println("P_MD5:");
- logger.printAsHex(md5_mac_length, "", " ", out);
- }
-
- pos = 0;
- sha_mac.update(str_byts);
- hash = sha_mac.doFinal(seed); // A(1)
- byte[] sha1hash;
- while (pos < out.length) {
- sha_mac.update(hash);
- sha_mac.update(str_byts);
- sha1hash = sha_mac.doFinal(seed);
- for (int i = 0; (i < sha_mac_length) & (pos < out.length); i++) {
- out[pos++] ^= sha1hash[i];
- }
- // make A(i)
- hash = sha_mac.doFinal(hash);
- }
-
- if (logger != null) {
- logger.println("PRF:");
- logger.printAsHex(sha_mac_length, "", " ", out);
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/PinEntryException.java b/crypto/src/main/java/org/conscrypt/PinEntryException.java
deleted file mode 100644
index 8c651db..0000000
--- a/crypto/src/main/java/org/conscrypt/PinEntryException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-// public for testing by CertPinManagerTest
-public class PinEntryException extends Exception {
-
- PinEntryException() {
- }
-
- PinEntryException(String msg) {
- super(msg);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinFailureLogger.java b/crypto/src/main/java/org/conscrypt/PinFailureLogger.java
deleted file mode 100644
index bdb44a9..0000000
--- a/crypto/src/main/java/org/conscrypt/PinFailureLogger.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.List;
-import libcore.io.Base64;
-import libcore.io.DropBox;
-
-public class PinFailureLogger {
-
- private static final long LOG_INTERVAL_NANOS = 1000 * 1000 * 1000 * 60 * 60;
-
- private static long lastLoggedNanos = 0;
-
- public static synchronized void log(String cn, boolean chainContainsUserCert,
- boolean pinIsEnforcing,
- List<X509Certificate> chain) {
- // if we've logged recently, don't do it again
- if (!timeToLog()) {
- return;
- }
- // otherwise, log the event
- writeToLog(cn, chainContainsUserCert, pinIsEnforcing, chain);
- // update the last logged time
- lastLoggedNanos = System.nanoTime();
- }
-
- protected static synchronized void writeToLog(String cn, boolean chainContainsUserCert,
- boolean pinIsEnforcing,
- List<X509Certificate> chain) {
- StringBuilder sb = new StringBuilder();
- sb.append(cn);
- sb.append("|");
- sb.append(chainContainsUserCert);
- sb.append("|");
- sb.append(pinIsEnforcing);
- sb.append("|");
- for (X509Certificate cert : chain) {
- try {
- sb.append(Base64.encode(cert.getEncoded()));
- } catch (CertificateEncodingException e) {
- sb.append("Error: could not encode certificate");
- }
- sb.append("|");
- }
- DropBox.addText("exp_det_cert_pin_failure", sb.toString());
- }
-
- protected static boolean timeToLog() {
- long currentTimeNanos = System.nanoTime();
- return ((currentTimeNanos - lastLoggedNanos) > LOG_INTERVAL_NANOS);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinListEntry.java b/crypto/src/main/java/org/conscrypt/PinListEntry.java
deleted file mode 100644
index a401700..0000000
--- a/crypto/src/main/java/org/conscrypt/PinListEntry.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import libcore.io.EventLogger;
-
-/**
- * This class represents a single entry in the pin file.
- */
-// public for testing by CertPinManagerTest
-public class PinListEntry {
-
- /** The Common Name (CN) as used on the SSL certificate */
- private final String cn;
-
- /**
- * Determines whether a failed match here will prevent the chain from being accepted. If true,
- * an unpinned chain will log and cause a match failure. If false, it will merely log.
- */
- private final boolean enforcing;
-
- private final Set<String> pinnedFingerprints = new HashSet<String>();
-
- private static final boolean DEBUG = false;
-
- private final TrustedCertificateStore certStore;
-
- public String getCommonName() {
- return cn;
- }
-
- public boolean getEnforcing() {
- return enforcing;
- }
-
- public PinListEntry(String entry, TrustedCertificateStore store) throws PinEntryException {
- if (entry == null) {
- throw new NullPointerException("entry == null");
- }
- certStore = store;
- // Examples:
- // *.google.com=true|34c8a0d...9e04ca05f,9e04ca05f...34c8a0d
- // *.android.com=true|ca05f...8a0d34c
- // clients.google.com=false|9e04ca05f...34c8a0d,34c8a0d...9e04ca05f
- String[] values = entry.split("[=,|]");
- // entry must have a CN, an enforcement value, and at least one pin
- if (values.length < 3) {
- throw new PinEntryException("Received malformed pin entry");
- }
- // get the cn
- cn = values[0]; // is there more validation we can do here?
- enforcing = enforcementValueFromString(values[1]);
- // the remainder should be pins
- addPins(Arrays.copyOfRange(values, 2, values.length));
- }
-
- private static boolean enforcementValueFromString(String val) throws PinEntryException {
- if (val.equals("true")) {
- return true;
- } else if (val.equals("false")) {
- return false;
- } else {
- throw new PinEntryException("Enforcement status is not a valid value");
- }
- }
-
- /**
- * Checks the given chain against the pin list corresponding to this entry.
- *
- * If the pin list does not contain the required certs and the enforcing field is true then
- * this returns true, indicating a verification error. Otherwise, it returns false and
- * verification should proceed.
- */
- public boolean chainIsNotPinned(List<X509Certificate> chain) {
- for (X509Certificate cert : chain) {
- String fingerprint = getFingerprint(cert);
- if (pinnedFingerprints.contains(fingerprint)) {
- return false;
- }
- }
- logPinFailure(chain);
- return enforcing;
- }
-
- private static String getFingerprint(X509Certificate cert) {
- try {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- }
- }
-
- private void addPins(String[] pins) {
- for (String pin : pins) {
- validatePin(pin);
- }
- Collections.addAll(pinnedFingerprints, pins);
- }
-
- private static void validatePin(String pin) {
- // check to make sure the length is correct
- if (pin.length() != 128) {
- throw new IllegalArgumentException("Pin is not a valid length");
- }
- // check to make sure that it's a valid hex string
- try {
- new BigInteger(pin, 16);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Pin is not a valid hex string", e);
- }
- }
-
- private boolean chainContainsUserCert(List<X509Certificate> chain) {
- if (certStore == null) {
- return false;
- }
- for (X509Certificate cert : chain) {
- if (certStore.isUserAddedCertificate(cert)) {
- return true;
- }
- }
- return false;
- }
-
- private void logPinFailure(List<X509Certificate> chain) {
- PinFailureLogger.log(cn, chainContainsUserCert(chain), enforcing, chain);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/PinManagerException.java b/crypto/src/main/java/org/conscrypt/PinManagerException.java
deleted file mode 100644
index e52ae83..0000000
--- a/crypto/src/main/java/org/conscrypt/PinManagerException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-class PinManagerException extends Exception {
-
- PinManagerException() {
- }
-
- PinManagerException(String msg) {
- super(msg);
- }
-
- PinManagerException(String msg, Exception e) {
- super(msg, e);
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/Platform.java b/crypto/src/main/java/org/conscrypt/Platform.java
deleted file mode 100644
index 3a577ce..0000000
--- a/crypto/src/main/java/org/conscrypt/Platform.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import org.apache.harmony.security.utils.AlgNameMapper;
-import org.apache.harmony.security.utils.AlgNameMapperSource;
-
-class Platform {
- private static class NoPreloadHolder {
- public static final Platform MAPPER = new Platform();
- }
-
- /**
- * Runs all the setup for the platform that only needs to run once.
- */
- public static void setup() {
- NoPreloadHolder.MAPPER.ping();
- }
-
- /**
- * Just a placeholder to make sure the class is initialized.
- */
- private void ping() {
- }
-
- private Platform() {
- AlgNameMapper.setSource(new OpenSSLMapper());
- }
-
- private static class OpenSSLMapper implements AlgNameMapperSource {
- @Override
- public String mapNameToOid(String algName) {
- return NativeCrypto.OBJ_txt2nid_oid(algName);
- }
-
- @Override
- public String mapOidToName(String oid) {
- return NativeCrypto.OBJ_txt2nid_longName(oid);
- }
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/ProtocolVersion.java b/crypto/src/main/java/org/conscrypt/ProtocolVersion.java
deleted file mode 100644
index 4e2555c..0000000
--- a/crypto/src/main/java/org/conscrypt/ProtocolVersion.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.conscrypt;
-
-import java.util.Hashtable;
-
-/**
- *
- * Represents Protocol Version
- */
-public class ProtocolVersion {
- /**
- * Protocols supported by this provider implementation
- */
- public static final String[] supportedProtocols = new String[] { "TLSv1",
- "SSLv3" };
-
- private static Hashtable<String, ProtocolVersion> protocolsByName = new Hashtable<String, ProtocolVersion>(4);
-
- /**
- *
- * Returns true if protocol version is supported
- *
- * @param version
- */
- public static boolean isSupported(byte[] version) {
- if (version[0] != 3 || (version[1] != 0 && version[1] != 1)) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns ProtocolVersion
- *
- * @param version
- * @return
- */
- public static ProtocolVersion getByVersion(byte[] version) {
- if (version[0] == 3) {
- if (version[1] == 1) {
- return TLSv1;
- }
- if (version[1] == 0) {
- return SSLv3;
- }
- }
- return null;
- }
-
- /**
- * Returns true if provider supports protocol version
- *
- * @param name
- * @return
- */
- public static boolean isSupported(String name) {
- return protocolsByName.containsKey(name);
- }
-
- /**
- * Returns ProtocolVersion
- *
- * @param name
- * @return
- */
- public static ProtocolVersion getByName(String name) {
- return protocolsByName.get(name);
- }
-
- /**
- * Highest protocol version supported by provider implementation
- *
- * @param protocols
- * @return
- */
- public static ProtocolVersion getLatestVersion(String[] protocols) {
- if (protocols == null || protocols.length == 0) {
- return null;
- }
- ProtocolVersion latest = getByName(protocols[0]);
- ProtocolVersion current;
- for (int i = 1; i < protocols.length; i++) {
- current = getByName(protocols[i]);
- if (current == null) {
- continue;
- }
- if ((latest == null)
- || (latest.version[0] < current.version[0])
- || (latest.version[0] == current.version[0] && latest.version[1] < current.version[1])) {
- latest = current;
- }
- }
- return latest;
-
- }
-
- /**
- * SSL 3.0 protocol version
- */
- public static final ProtocolVersion SSLv3 = new ProtocolVersion("SSLv3",
- new byte[] { 3, 0 });
-
- /**
- * TLS 1.0 protocol version
- */
- public static final ProtocolVersion TLSv1 = new ProtocolVersion("TLSv1",
- new byte[] { 3, 1 });
-
- static {
- protocolsByName.put(SSLv3.name, SSLv3);
- protocolsByName.put(TLSv1.name, TLSv1);
- protocolsByName.put("SSL", SSLv3);
- protocolsByName.put("TLS", TLSv1);
- }
-
- /**
- * Protocol name
- */
- public final String name;
-
- /**
- * Protocol version as byte array
- */
- public final byte[] version;
-
- private ProtocolVersion(String name, byte[] version) {
- this.name = name;
- this.version = version;
- }
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java b/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java
deleted file mode 100644
index d2834d3..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLBufferedInput.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-/**
- * This is a wrapper input stream for ByteBuffer data source.
- * Among with the read functionality it provides info
- * about number of cunsumed bytes from the source ByteBuffer.
- * The source ByteBuffer object can be reseted.
- * So one instance of this wrapper can be reused for several
- * ByteBuffer data sources.
- */
-public class SSLBufferedInput extends SSLInputStream {
-
- private ByteBuffer in;
- private int bytik;
- private int consumed = 0;
-
- /**
- * Constructor
- */
- protected SSLBufferedInput() {}
-
- /**
- * Sets the buffer as a data source
- */
- protected void setSourceBuffer(ByteBuffer in) {
- consumed = 0;
- this.in = in;
- }
-
- @Override
- public int available() throws IOException {
- // in assumption that the buffer has been set
- return in.remaining();
- }
-
- /**
- * Returns the number of consumed bytes.
- */
- protected int consumed() {
- return consumed;
- }
-
- /**
- * Reads the following byte value. If there are no bytes in the source
- * buffer, method throws java.nio.BufferUnderflowException.
- */
- @Override
- public int read() throws IOException {
- // TODO: implement optimized read(int)
- // and read(byte[], int, int) methods
- bytik = in.get() & 0x00FF;
- consumed ++;
- return bytik;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java b/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java
deleted file mode 100644
index d070a02..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLClientSessionCache.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * A persistent {@link javax.net.ssl.SSLSession} cache used by
- * {@link javax.net.ssl.SSLSessionContext} to share client-side SSL sessions
- * across processes. For example, this cache enables applications to
- * persist and reuse sessions across restarts.
- *
- * <p>The {@code SSLSessionContext} implementation converts
- * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
- * session data is dependent upon the caller's implementation and is opaque to
- * the {@code SSLClientSessionCache} implementation.
- */
-public interface SSLClientSessionCache {
-
- /**
- * Gets data from a pre-existing session for a given server host and port.
- *
- * @param host from {@link javax.net.ssl.SSLSession#getPeerHost()}
- * @param port from {@link javax.net.ssl.SSLSession#getPeerPort()}
- * @return the session data or null if none is cached
- * @throws NullPointerException if host is null
- */
- public byte[] getSessionData(String host, int port);
-
- /**
- * Stores session data for the given session.
- *
- * @param session to cache data for
- * @param sessionData to cache
- * @throws NullPointerException if session, result of
- * {@code session.getPeerHost()} or data is null
- */
- public void putSessionData(SSLSession session, byte[] sessionData);
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLContextImpl.java b/crypto/src/main/java/org/conscrypt/SSLContextImpl.java
deleted file mode 100644
index 75aed4f..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLContextImpl.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.KeyManagementException;
-import java.security.SecureRandom;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContextSpi;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-/**
- * Implementation of SSLContext service provider interface.
- */
-public class SSLContextImpl extends SSLContextSpi {
-
- /**
- * The default SSLContextImpl for use with SSLContext.getInstance("Default").
- * Protected by the DefaultSSLContextImpl.class monitor.
- */
- private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL;
-
- /** Client session cache. */
- private final ClientSessionContext clientSessionContext;
-
- /** Server session cache. */
- private final ServerSessionContext serverSessionContext;
-
- protected SSLParametersImpl sslParameters;
-
- public SSLContextImpl() {
- clientSessionContext = new ClientSessionContext();
- serverSessionContext = new ServerSessionContext();
- }
-
- /**
- * Constuctor for the DefaultSSLContextImpl.
- * @param dummy is null, used to distinguish this case from the
- * public SSLContextImpl() constructor.
- */
- protected SSLContextImpl(DefaultSSLContextImpl dummy)
- throws GeneralSecurityException, IOException {
- synchronized (DefaultSSLContextImpl.class) {
- if (DEFAULT_SSL_CONTEXT_IMPL == null) {
- clientSessionContext = new ClientSessionContext();
- serverSessionContext = new ServerSessionContext();
- DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this;
- } else {
- clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext();
- serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext();
- }
- sslParameters = new SSLParametersImpl(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(),
- DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(),
- null,
- clientSessionContext,
- serverSessionContext);
- }
- }
-
- /**
- * Initializes this {@code SSLContext} instance. All of the arguments are
- * optional, and the security providers will be searched for the required
- * implementations of the needed algorithms.
- *
- * @param kms the key sources or {@code null}
- * @param tms the trust decision sources or {@code null}
- * @param sr the randomness source or {@code null}
- * @throws KeyManagementException if initializing this instance fails
- */
- @Override
- public void engineInit(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr) throws KeyManagementException {
- sslParameters = new SSLParametersImpl(kms, tms, sr,
- clientSessionContext, serverSessionContext);
- }
-
- @Override
- public SSLSocketFactory engineGetSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new SSLSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLServerSocketFactory engineGetServerSocketFactory() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- return new SSLServerSocketFactoryImpl(sslParameters);
- }
-
- @Override
- public SSLEngine engineCreateSSLEngine(String host, int port) {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
- p.setUseClientMode(false);
- return new SSLEngineImpl(host, port, p);
- }
-
- @Override
- public SSLEngine engineCreateSSLEngine() {
- if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initialized.");
- }
- SSLParametersImpl p = (SSLParametersImpl) sslParameters.clone();
- p.setUseClientMode(false);
- return new SSLEngineImpl(p);
- }
-
- @Override
- public ServerSessionContext engineGetServerSessionContext() {
- return serverSessionContext;
- }
-
- @Override
- public ClientSessionContext engineGetClientSessionContext() {
- return clientSessionContext;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java b/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java
deleted file mode 100644
index f2cb77d..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineAppData.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.nio.ByteBuffer;
-import javax.net.ssl.SSLException;
-
-/**
- * This class is used to retrieve the application data
- * arrived for the SSLEngine.
- */
-public class SSLEngineAppData implements Appendable {
-
- /**
- * Buffer containing received application data.
- */
- byte[] buffer;
-
- /**
- * Constructor
- */
- protected SSLEngineAppData() {}
-
- /**
- * Stores received data. The source data is not cloned,
- * just the array reference is remembered into the buffer field.
- */
- public void append(byte[] src) {
- if (buffer != null) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLException("Attempt to override the data"));
- }
- buffer = src;
- }
-
- /**
- * Places the data from the buffer into the array of destination
- * ByteBuffer objects.
- */
- protected int placeTo(ByteBuffer[] dsts, int offset, int length) {
- if (buffer == null) {
- return 0;
- }
- int pos = 0;
- int len = buffer.length;
- int rem;
- // write data to the buffers
- for (int i=offset; i<offset+length; i++) {
- rem = dsts[i].remaining();
- // TODO: optimization work - use hasArray, array(), arraycopy
- if (len - pos < rem) {
- // can fully write remaining data into buffer
- dsts[i].put(buffer, pos, len - pos);
- pos = len;
- // data was written, exit
- break;
- }
- // write chunk of data
- dsts[i].put(buffer, pos, rem);
- pos += rem;
- }
- if (pos != len) {
- // The data did not feet into the buffers,
- // it should not happen, because the destination buffers
- // had been checked for the space before record unwrapping.
- // But if it so, we should allert about internal error.
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "The received application data could not be fully written"
- + "into the destination buffers"));
- }
- buffer = null;
- return len;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java b/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java
deleted file mode 100644
index f4a2d2d..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineDataStream.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.nio.ByteBuffer;
-
-/**
- * This class provides the DataStream functionality
- * implemented over the array of ByteBuffer instances.
- * Among with the data chunks read functionality
- * it provides the info about amount of consumed data.
- * The source ByteBuffer objects can be replaced by other.
- * So one instance of this wrapper can be reused for several
- * data sources.
- */
-public class SSLEngineDataStream implements DataStream {
-
- private ByteBuffer[] srcs;
- private int offset;
- private int limit;
-
- private int available;
- private int consumed;
-
- protected SSLEngineDataStream() {}
-
- protected void setSourceBuffers(ByteBuffer[] srcs, int offset, int length) {
- this.srcs = srcs;
- this.offset = offset;
- this.limit = offset+length;
- this.consumed = 0;
- this.available = 0;
- for (int i=offset; i<limit; i++) {
- if (srcs[i] == null) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- available += srcs[i].remaining();
- }
- }
-
- public int available() {
- return available;
- }
-
- public boolean hasData() {
- return available > 0;
- }
-
- public byte[] getData(int length) {
- // TODO: optimization work:
- // use ByteBuffer.get(byte[],int,int)
- // and ByteBuffer.hasArray() methods
- int len = (length < available) ? length : available;
- available -= len;
- consumed += len;
- byte[] res = new byte[len];
- int pos = 0;
- loop:
- for (; offset<limit; offset++) {
- while (srcs[offset].hasRemaining()) {
- res[pos++] = srcs[offset].get();
- len --;
- if (len == 0) {
- break loop;
- }
- }
- }
- return res;
- }
-
- protected int consumed() {
- return consumed;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java b/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
deleted file mode 100644
index 3ed9980..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLEngineImpl.java
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ReadOnlyBufferException;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLSession;
-
-/**
- * Implementation of SSLEngine.
- * @see javax.net.ssl.SSLEngine class documentation for more information.
- */
-public class SSLEngineImpl extends SSLEngine {
-
- // indicates if peer mode was set
- private boolean peer_mode_was_set = false;
- // indicates if handshake has been started
- private boolean handshake_started = false;
- // indicates if inbound operations finished
- private boolean isInboundDone = false;
- // indicates if outbound operations finished
- private boolean isOutboundDone = false;
- // indicates if close_notify alert had been sent to another peer
- private boolean close_notify_was_sent = false;
- // indicates if close_notify alert had been received from another peer
- private boolean close_notify_was_received = false;
- // indicates if engine was closed (it means that
- // all the works on it are done, except (probably) some finalizing work)
- private boolean engine_was_closed = false;
- // indicates if engine was shutted down (it means that
- // all cleaning work had been done and the engine is not operable)
- private boolean engine_was_shutteddown = false;
-
- // record protocol to be used
- protected SSLRecordProtocol recordProtocol;
- // input stream for record protocol
- private SSLBufferedInput recProtIS;
- // handshake protocol to be used
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to be used
- private AlertProtocol alertProtocol;
- // place where application data will be stored
- private SSLEngineAppData appData;
- // outcoming application data stream
- private SSLEngineDataStream dataStream = new SSLEngineDataStream();
- // active session object
- private SSLSessionImpl session;
-
- // peer configuration parameters
- protected SSLParametersImpl sslParameters;
-
- // in case of emergency situations when data could not be
- // placed in destination buffers it will be stored in this
- // fields
- private byte[] remaining_wrapped_data = null;
- private byte[] remaining_hsh_data = null;
-
- // logger
- private Logger.Stream logger = Logger.getStream("engine");
-
- protected SSLEngineImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- }
-
- protected SSLEngineImpl(String host, int port, SSLParametersImpl sslParameters) {
- super(host, port);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Starts the handshake.
- * @throws SSLException
- * @see javax.net.ssl.SSLEngine#beginHandshake() method documentation
- * for more information
- */
- @Override
- public void beginHandshake() throws SSLException {
- if (engine_was_closed) {
- throw new SSLException("Engine has already been closed.");
- }
- if (!peer_mode_was_set) {
- throw new IllegalStateException("Client/Server mode was not set");
- }
- if (!handshake_started) {
- handshake_started = true;
- if (getUseClientMode()) {
- handshakeProtocol = new ClientHandshakeImpl(this);
- } else {
- handshakeProtocol = new ServerHandshakeImpl(this);
- }
- appData = new SSLEngineAppData();
- alertProtocol = new AlertProtocol();
- recProtIS = new SSLBufferedInput();
- recordProtocol = new SSLRecordProtocol(handshakeProtocol,
- alertProtocol, recProtIS, appData);
- }
- handshakeProtocol.start();
- }
-
- /**
- * Closes inbound operations of this engine
- * @throws SSLException
- * @see javax.net.ssl.SSLEngine#closeInbound() method documentation
- * for more information
- */
- @Override
- public void closeInbound() throws SSLException {
- if (logger != null) {
- logger.println("closeInbound() "+isInboundDone);
- }
- if (isInboundDone) {
- return;
- }
- isInboundDone = true;
- engine_was_closed = true;
- if (handshake_started) {
- if (!close_notify_was_received) {
- if (session != null) {
- session.invalidate();
- }
- alertProtocol.alert(AlertProtocol.FATAL,
- AlertProtocol.INTERNAL_ERROR);
- throw new SSLException("Inbound is closed before close_notify "
- + "alert has been received.");
- }
- } else {
- // engine is closing before initial handshake has been made
- shutdown();
- }
- }
-
- /**
- * Closes outbound operations of this engine
- * @see javax.net.ssl.SSLEngine#closeOutbound() method documentation
- * for more information
- */
- @Override
- public void closeOutbound() {
- if (logger != null) {
- logger.println("closeOutbound() "+isOutboundDone);
- }
- if (isOutboundDone) {
- return;
- }
- isOutboundDone = true;
- if (handshake_started) {
- // initial handshake had been started
- alertProtocol.alert(AlertProtocol.WARNING,
- AlertProtocol.CLOSE_NOTIFY);
- close_notify_was_sent = true;
- } else {
- // engine is closing before initial handshake has been made
- shutdown();
- }
- engine_was_closed = true;
- }
-
- /**
- * Returns handshake's delegated tasks to be run
- * @return the delegated task to be executed.
- * @see javax.net.ssl.SSLEngine#getDelegatedTask() method documentation
- * for more information
- */
- @Override
- public Runnable getDelegatedTask() {
- return handshakeProtocol.getTask();
- }
-
- /**
- * Returns names of supported cipher suites.
- * @return array of strings containing the names of supported cipher suites
- * @see javax.net.ssl.SSLEngine#getSupportedCipherSuites() method
- * documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnabledCipherSuites() method
- * documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnabledCipherSuites(String[]) method
- * documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getSupportedProtocols() method
- * documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnabledProtocols() method
- * documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnabledProtocols(String[]) method
- * documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setUseClientMode(boolean) method
- * documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- if (handshake_started) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- peer_mode_was_set = true;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getUseClientMode() method
- * documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setNeedClientAuth(boolean) method
- * documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getNeedClientAuth() method
- * documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setWantClientAuth(boolean) method
- * documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getWantClientAuth() method
- * documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean) method
- * documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getEnableSessionCreation() method
- * documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- // -----------------------------------------------------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getHandshakeStatus() method
- * documentation for more information
- */
- @Override
- public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
- if (!handshake_started || engine_was_shutteddown) {
- // initial handshake has not been started yet
- return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
- }
- if (alertProtocol.hasAlert()) {
- // need to send an alert
- return SSLEngineResult.HandshakeStatus.NEED_WRAP;
- }
- if (close_notify_was_sent && !close_notify_was_received) {
- // waiting for "close_notify" response
- return SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
- }
- return handshakeProtocol.getStatus();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#getSession() method
- * documentation for more information
- */
- @Override
- public SSLSession getSession() {
- if (session != null) {
- return session;
- }
- return SSLSessionImpl.getNullSession();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#isInboundDone() method
- * documentation for more information
- */
- @Override
- public boolean isInboundDone() {
- return isInboundDone || engine_was_closed;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLEngine#isOutboundDone() method
- * documentation for more information
- */
- @Override
- public boolean isOutboundDone() {
- return isOutboundDone;
- }
-
- /**
- * Decodes one complete SSL/TLS record provided in the source buffer.
- * If decoded record contained application data, this data will
- * be placed in the destination buffers.
- * For more information about TLS record fragmentation see
- * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
- * @param src source buffer containing SSL/TLS record.
- * @param dsts destination buffers to place received application data.
- * @see javax.net.ssl.SSLEngine#unwrap(ByteBuffer,ByteBuffer[],int,int)
- * method documentation for more information
- */
- @Override
- public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts,
- int offset, int length) throws SSLException {
- if (engine_was_shutteddown) {
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
- }
- if ((src == null) || (dsts == null)) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
-
- if (!handshake_started) {
- beginHandshake();
- }
-
- SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
- // If is is initial handshake or connection closure stage,
- // check if this call was made in spite of handshake status
- if ((session == null || engine_was_closed) && (
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP) ||
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_TASK))) {
- return new SSLEngineResult(
- getEngineStatus(), handshakeStatus, 0, 0);
- }
-
- if (src.remaining() < recordProtocol.getMinRecordSize()) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_UNDERFLOW,
- getHandshakeStatus(), 0, 0);
- }
-
- try {
- src.mark();
- // check the destination buffers and count their capacity
- int capacity = 0;
- for (int i=offset; i<offset+length; i++) {
- if (dsts[i] == null) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- if (dsts[i].isReadOnly()) {
- throw new ReadOnlyBufferException();
- }
- capacity += dsts[i].remaining();
- }
- if (capacity < recordProtocol.getDataSize(src.remaining())) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- getHandshakeStatus(), 0, 0);
- }
- recProtIS.setSourceBuffer(src);
- // unwrap the record contained in source buffer, pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- int type = recordProtocol.unwrap();
- // process the data and return the result
- switch (type) {
- case ContentType.HANDSHAKE:
- case ContentType.CHANGE_CIPHER_SPEC:
- if (handshakeProtocol.getStatus().equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- session = recordProtocol.getSession();
- }
- break;
- case ContentType.APPLICATION_DATA:
- break;
- case ContentType.ALERT:
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- if (session != null) {
- session.invalidate();
- }
- String description = "Fatal alert received "
- + alertProtocol.getAlertDescription();
- shutdown();
- throw new SSLException(description);
- } else {
- if (logger != null) {
- logger.println("Warning allert has been received: "
- + alertProtocol.getAlertDescription());
- }
- switch(alertProtocol.getDescriptionCode()) {
- case AlertProtocol.CLOSE_NOTIFY:
- alertProtocol.setProcessed();
- close_notify_was_received = true;
- if (!close_notify_was_sent) {
- closeOutbound();
- closeInbound();
- } else {
- closeInbound();
- shutdown();
- }
- break;
- case AlertProtocol.NO_RENEGOTIATION:
- alertProtocol.setProcessed();
- if (session == null) {
- // message received during the initial
- // handshake
- throw new AlertException(
- AlertProtocol.HANDSHAKE_FAILURE,
- new SSLHandshakeException(
- "Received no_renegotiation "
- + "during the initial handshake"));
- } else {
- // just stop the handshake
- handshakeProtocol.stop();
- }
- break;
- default:
- alertProtocol.setProcessed();
- }
- }
- break;
- }
- return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(),
- recProtIS.consumed(),
- // place the app. data (if any) into the dest. buffers
- // and get the number of produced bytes:
- appData.placeTo(dsts, offset, length));
- } catch (BufferUnderflowException e) {
- // there was not enought data ource buffer to make complete packet
- src.reset();
- return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW,
- getHandshakeStatus(), 0, 0);
- } catch (AlertException e) {
- // fatal alert occured
- alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
- engine_was_closed = true;
- src.reset();
- if (session != null) {
- session.invalidate();
- }
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw e.getReason();
- } catch (SSLException e) {
- throw e;
- } catch (IOException e) {
- alertProtocol.alert(AlertProtocol.FATAL,
- AlertProtocol.INTERNAL_ERROR);
- engine_was_closed = true;
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw new SSLException(e.getMessage());
- }
- }
-
- /**
- * Encodes the application data into SSL/TLS record. If handshake status
- * of the engine differs from NOT_HANDSHAKING the operation can work
- * without consuming of the source data.
- * For more information about TLS record fragmentation see
- * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2.
- * @param srcs the source buffers with application data to be encoded
- * into SSL/TLS record.
- * @param offset the offset in the destination buffers array pointing to
- * the first buffer with the source data.
- * @param len specifies the maximum number of buffers to be procesed.
- * @param dst the destination buffer where encoded data will be placed.
- * @see javax.net.ssl.SSLEngine#wrap(ByteBuffer[],int,int,ByteBuffer) method
- * documentation for more information
- */
- @Override
- public SSLEngineResult wrap(ByteBuffer[] srcs, int offset,
- int len, ByteBuffer dst) throws SSLException {
- if (engine_was_shutteddown) {
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0);
- }
- if ((srcs == null) || (dst == null)) {
- throw new IllegalStateException(
- "Some of the input parameters are null");
- }
- if (dst.isReadOnly()) {
- throw new ReadOnlyBufferException();
- }
-
- if (!handshake_started) {
- beginHandshake();
- }
-
- SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus();
- // If it is an initial handshake or connection closure stage,
- // check if this call was made in spite of handshake status
- if ((session == null || engine_was_closed) && (
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP) ||
- handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_TASK))) {
- return new SSLEngineResult(
- getEngineStatus(), handshakeStatus, 0, 0);
- }
-
- int capacity = dst.remaining();
- int produced = 0;
-
- if (alertProtocol.hasAlert()) {
- // we have an alert to be sent
- if (capacity < recordProtocol.getRecordSize(2)) {
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- byte[] alert_data = alertProtocol.wrap();
- // place the alert record into destination
- dst.put(alert_data);
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- if (session != null) {
- session.invalidate();
- }
- // fatal alert has been sent, so shut down the engine
- shutdown();
- return new SSLEngineResult(
- SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- } else {
- alertProtocol.setProcessed();
- // check if the works on this engine have been done
- if (close_notify_was_sent && close_notify_was_received) {
- shutdown();
- return new SSLEngineResult(SSLEngineResult.Status.CLOSED,
- SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
- 0, alert_data.length);
- }
- return new SSLEngineResult(
- getEngineStatus(),
- getHandshakeStatus(),
- 0, alert_data.length);
- }
- }
-
- if (capacity < recordProtocol.getMinRecordSize()) {
- if (logger != null) {
- logger.println("Capacity of the destination("
- +capacity+") < MIN_PACKET_SIZE("
- +recordProtocol.getMinRecordSize()+")");
- }
- return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
-
- try {
- if (!handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
- // so we wraps application data
- dataStream.setSourceBuffers(srcs, offset, len);
- if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE) &&
- (capacity < recordProtocol.getRecordSize(
- dataStream.available()))) {
- if (logger != null) {
- logger.println("The destination buffer("
- +capacity+") can not take the resulting packet("
- + recordProtocol.getRecordSize(
- dataStream.available())+")");
- }
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- }
- if (remaining_wrapped_data == null) {
- remaining_wrapped_data =
- recordProtocol.wrap(ContentType.APPLICATION_DATA,
- dataStream);
- }
- if (capacity < remaining_wrapped_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_wrapped_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, dataStream.consumed(), 0);
- } else {
- dst.put(remaining_wrapped_data);
- produced = remaining_wrapped_data.length;
- remaining_wrapped_data = null;
- return new SSLEngineResult(getEngineStatus(),
- handshakeStatus, dataStream.consumed(), produced);
- }
- } else {
- if (remaining_hsh_data == null) {
- remaining_hsh_data = handshakeProtocol.wrap();
- }
- if (capacity < remaining_hsh_data.length) {
- // It should newer happen because we checked the destination
- // buffer size, but there is a possibility
- // (if dest buffer was filled outside)
- // so we just remember the data into remaining_hsh_data
- // and will enclose it during the the next call
- return new SSLEngineResult(
- SSLEngineResult.Status.BUFFER_OVERFLOW,
- handshakeStatus, 0, 0);
- } else {
- dst.put(remaining_hsh_data);
- produced = remaining_hsh_data.length;
- remaining_hsh_data = null;
-
- handshakeStatus = handshakeProtocol.getStatus();
- if (handshakeStatus.equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- session = recordProtocol.getSession();
- }
- }
- return new SSLEngineResult(
- getEngineStatus(), getHandshakeStatus(), 0, produced);
- }
- } catch (AlertException e) {
- // fatal alert occured
- alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode());
- engine_was_closed = true;
- if (session != null) {
- session.invalidate();
- }
- // shutdown work will be made after the alert will be sent
- // to another peer (by wrap method)
- throw e.getReason();
- }
- }
-
- // Shutdownes the engine and makes all cleanup work.
- private void shutdown() {
- engine_was_closed = true;
- engine_was_shutteddown = true;
- isOutboundDone = true;
- isInboundDone = true;
- if (handshake_started) {
- alertProtocol.shutdown();
- alertProtocol = null;
- handshakeProtocol.shutdown();
- handshakeProtocol = null;
- recordProtocol.shutdown();
- recordProtocol = null;
- }
- }
-
-
- private SSLEngineResult.Status getEngineStatus() {
- return (engine_was_closed)
- ? SSLEngineResult.Status.CLOSED
- : SSLEngineResult.Status.OK;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLInputStream.java b/crypto/src/main/java/org/conscrypt/SSLInputStream.java
deleted file mode 100644
index c8a5eca..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLInputStream.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is a base for all input stream classes used
- * in protocol implementation. It extends an InputStream with
- * some additional read methods allowing to read TLS specific
- * data types such as uint8, uint32 etc (see TLS v 1 specification
- * at http://www.ietf.org/rfc/rfc2246.txt).
- */
-public abstract class SSLInputStream extends InputStream {
-
- @Override
- public abstract int available() throws IOException;
-
- /**
- * Reads the following byte value. Note that in the case of
- * reaching of the end of the data this methods throws the
- * exception, not return -1. The type of exception depends
- * on implementation. It was done for simplifying and speeding
- * up of processing of such cases.
- * @see org.conscrypt.SSLStreamedInput#read()
- * @see org.conscrypt.SSLBufferedInput#read()
- * @see org.conscrypt.HandshakeIODataStream#read()
- */
- @Override
- public abstract int read() throws IOException;
-
- /**
- * Reads and returns uint8 value.
- */
- public int readUint8() throws IOException {
- return read() & 0x00FF;
- }
-
- /**
- * Reads and returns uint16 value.
- */
- public int readUint16() throws IOException {
- return (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint24 value.
- */
- public int readUint24() throws IOException {
- return (read() << 16) | (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint32 value.
- */
- public long readUint32() throws IOException {
- return (read() << 24) | (read() << 16)
- | (read() << 8) | (read() & 0x00FF);
- }
-
- /**
- * Reads and returns uint64 value.
- */
- public long readUint64() throws IOException {
- long hi = readUint32();
- long lo = readUint32();
- return (hi << 32) | lo;
- }
-
- /**
- * Returns the vector of opaque values of specified length;
- * @param length - the length of the vector to be read.
- * @return the read data
- * @throws IOException if read operation could not be finished.
- */
- public byte[] read(int length) throws IOException {
- byte[] res = new byte[length];
- for (int i=0; i<length; i++) {
- res[i] = (byte) read();
- }
- return res;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int read_b;
- int i = 0;
- do {
- if ((read_b = read()) == -1) {
- return (i == 0) ? -1 : i;
- }
- b[off+i] = (byte) read_b;
- i++;
- } while ((available() != 0) && (i<len));
- return i;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java b/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java
deleted file mode 100644
index 21b8ae2..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLParametersImpl.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-import java.util.Arrays;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * The instances of this class encapsulate all the info
- * about enabled cipher suites and protocols,
- * as well as the information about client/server mode of
- * ssl socket, whether it require/want client authentication or not,
- * and controls whether new SSL sessions may be established by this
- * socket or not.
- */
-public class SSLParametersImpl implements Cloneable {
-
- // default source of authentication keys
- private static volatile X509KeyManager defaultKeyManager;
- // default source of authentication trust decisions
- private static volatile X509TrustManager defaultTrustManager;
- // default source of random numbers
- private static volatile SecureRandom defaultSecureRandom;
- // default SSL parameters
- private static volatile SSLParametersImpl defaultParameters;
-
- // client session context contains the set of reusable
- // client-side SSL sessions
- private final ClientSessionContext clientSessionContext;
- // server session context contains the set of reusable
- // server-side SSL sessions
- private final ServerSessionContext serverSessionContext;
- // source of authentication keys
- private X509KeyManager keyManager;
- // source of authentication trust decisions
- private X509TrustManager trustManager;
- // source of random numbers
- private SecureRandom secureRandom;
-
- // cipher suites available for SSL connection
- private CipherSuite[] enabledCipherSuites;
- // string representations of available cipher suites
- private String[] enabledCipherSuiteNames = null;
-
- // protocols available for SSL connection
- private String[] enabledProtocols = ProtocolVersion.supportedProtocols;
-
- // if the peer with this parameters tuned to work in client mode
- private boolean client_mode = true;
- // if the peer with this parameters tuned to require client authentication
- private boolean need_client_auth = false;
- // if the peer with this parameters tuned to request client authentication
- private boolean want_client_auth = false;
- // if the peer with this parameters allowed to cteate new SSL session
- private boolean enable_session_creation = true;
-
- protected CipherSuite[] getEnabledCipherSuitesMember() {
- if (enabledCipherSuites == null) {
- this.enabledCipherSuites = CipherSuite.DEFAULT_CIPHER_SUITES;
- }
- return enabledCipherSuites;
- }
-
- /**
- * Initializes the parameters. Naturally this constructor is used
- * in SSLContextImpl.engineInit method which directly passes its
- * parameters. In other words this constructor holds all
- * the functionality provided by SSLContext.init method.
- * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
- * SecureRandom)} for more information
- */
- protected SSLParametersImpl(KeyManager[] kms, TrustManager[] tms,
- SecureRandom sr, ClientSessionContext clientSessionContext,
- ServerSessionContext serverSessionContext)
- throws KeyManagementException {
- this.serverSessionContext = serverSessionContext;
- this.clientSessionContext = clientSessionContext;
-
- // It's not described by the spec of SSLContext what should happen
- // if the arrays of length 0 are specified. This implementation
- // behave as for null arrays (i.e. use installed security providers)
-
- // initialize keyManager
- if ((kms == null) || (kms.length == 0)) {
- keyManager = getDefaultKeyManager();
- } else {
- keyManager = findX509KeyManager(kms);
- }
-
- // initialize trustManager
- if ((tms == null) || (tms.length == 0)) {
- trustManager = getDefaultTrustManager();
- } else {
- trustManager = findX509TrustManager(tms);
- }
- // initialize secure random
- // BEGIN android-removed
- // if (sr == null) {
- // if (defaultSecureRandom == null) {
- // defaultSecureRandom = new SecureRandom();
- // }
- // secureRandom = defaultSecureRandom;
- // } else {
- // secureRandom = sr;
- // }
- // END android-removed
- // BEGIN android-added
- // We simply use the SecureRandom passed in by the caller. If it's
- // null, we don't replace it by a new instance. The native code below
- // then directly accesses /dev/urandom. Not the most elegant solution,
- // but faster than going through the SecureRandom object.
- secureRandom = sr;
- // END android-added
- }
-
- protected static SSLParametersImpl getDefault() throws KeyManagementException {
- SSLParametersImpl result = defaultParameters;
- if (result == null) {
- // single-check idiom
- defaultParameters = result = new SSLParametersImpl(null,
- null,
- null,
- new ClientSessionContext(),
- new ServerSessionContext());
- }
- return (SSLParametersImpl) result.clone();
- }
-
- /**
- * @return server session context
- */
- protected ServerSessionContext getServerSessionContext() {
- return serverSessionContext;
- }
-
- /**
- * @return client session context
- */
- protected ClientSessionContext getClientSessionContext() {
- return clientSessionContext;
- }
-
- /**
- * @return key manager
- */
- protected X509KeyManager getKeyManager() {
- return keyManager;
- }
-
- /**
- * @return trust manager
- */
- protected X509TrustManager getTrustManager() {
- return trustManager;
- }
-
- /**
- * @return secure random
- */
- protected SecureRandom getSecureRandom() {
- if (secureRandom != null) {
- return secureRandom;
- }
- SecureRandom result = defaultSecureRandom;
- if (result == null) {
- // single-check idiom
- defaultSecureRandom = result = new SecureRandom();
- }
- secureRandom = result;
- return secureRandom;
- }
-
- /**
- * @return the secure random member reference, even it is null
- */
- protected SecureRandom getSecureRandomMember() {
- return secureRandom;
- }
-
- /**
- * @return the names of enabled cipher suites
- */
- protected String[] getEnabledCipherSuites() {
- if (enabledCipherSuiteNames == null) {
- CipherSuite[] enabledCipherSuites = getEnabledCipherSuitesMember();
- enabledCipherSuiteNames = new String[enabledCipherSuites.length];
- for (int i = 0; i< enabledCipherSuites.length; i++) {
- enabledCipherSuiteNames[i] = enabledCipherSuites[i].getName();
- }
- }
- return enabledCipherSuiteNames.clone();
- }
-
- /**
- * Sets the set of available cipher suites for use in SSL connection.
- * @param suites: String[]
- * @return
- */
- protected void setEnabledCipherSuites(String[] suites) {
- if (suites == null) {
- throw new IllegalArgumentException("suites == null");
- }
- CipherSuite[] cipherSuites = new CipherSuite[suites.length];
- for (int i=0; i<suites.length; i++) {
- String suite = suites[i];
- if (suite == null) {
- throw new IllegalArgumentException("suites[" + i + "] == null");
- }
- cipherSuites[i] = CipherSuite.getByName(suite);
- if (cipherSuites[i] == null || !cipherSuites[i].supported) {
- throw new IllegalArgumentException(suite + " is not supported.");
- }
- }
- enabledCipherSuites = cipherSuites;
- enabledCipherSuiteNames = suites;
- }
-
- /**
- * @return the set of enabled protocols
- */
- protected String[] getEnabledProtocols() {
- return enabledProtocols.clone();
- }
-
- /**
- * Sets the set of available protocols for use in SSL connection.
- * @param protocols String[]
- */
- protected void setEnabledProtocols(String[] protocols) {
- if (protocols == null) {
- throw new IllegalArgumentException("protocols == null");
- }
- for (int i=0; i<protocols.length; i++) {
- String protocol = protocols[i];
- if (protocol == null) {
- throw new IllegalArgumentException("protocols[" + i + "] == null");
- }
- if (!ProtocolVersion.isSupported(protocol)) {
- throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
- }
- }
- enabledProtocols = protocols;
- }
-
- /**
- * Tunes the peer holding this parameters to work in client mode.
- * @param mode if the peer is configured to work in client mode
- */
- protected void setUseClientMode(boolean mode) {
- client_mode = mode;
- }
-
- /**
- * Returns the value indicating if the parameters configured to work
- * in client mode.
- */
- protected boolean getUseClientMode() {
- return client_mode;
- }
-
- /**
- * Tunes the peer holding this parameters to require client authentication
- */
- protected void setNeedClientAuth(boolean need) {
- need_client_auth = need;
- // reset the want_client_auth setting
- want_client_auth = false;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters tuned
- * to require client authentication
- */
- protected boolean getNeedClientAuth() {
- return need_client_auth;
- }
-
- /**
- * Tunes the peer holding this parameters to request client authentication
- */
- protected void setWantClientAuth(boolean want) {
- want_client_auth = want;
- // reset the need_client_auth setting
- need_client_auth = false;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters
- * tuned to request client authentication
- * @return
- */
- protected boolean getWantClientAuth() {
- return want_client_auth;
- }
-
- /**
- * Allows/disallows the peer holding this parameters to
- * create new SSL session
- */
- protected void setEnableSessionCreation(boolean flag) {
- enable_session_creation = flag;
- }
-
- /**
- * Returns the value indicating if the peer with this parameters
- * allowed to cteate new SSL session
- */
- protected boolean getEnableSessionCreation() {
- return enable_session_creation;
- }
-
- /**
- * Returns the clone of this object.
- * @return the clone.
- */
- @Override
- protected Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- private static X509KeyManager getDefaultKeyManager() throws KeyManagementException {
- X509KeyManager result = defaultKeyManager;
- if (result == null) {
- // single-check idiom
- defaultKeyManager = result = createDefaultKeyManager();
- }
- return result;
- }
- private static X509KeyManager createDefaultKeyManager() throws KeyManagementException {
- try {
- String algorithm = KeyManagerFactory.getDefaultAlgorithm();
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
- kmf.init(null, null);
- KeyManager[] kms = kmf.getKeyManagers();
- return findX509KeyManager(kms);
- } catch (NoSuchAlgorithmException e) {
- throw new KeyManagementException(e);
- } catch (KeyStoreException e) {
- throw new KeyManagementException(e);
- } catch (UnrecoverableKeyException e) {
- throw new KeyManagementException(e);
- }
- }
- private static X509KeyManager findX509KeyManager(KeyManager[] kms) throws KeyManagementException {
- for (KeyManager km : kms) {
- if (km instanceof X509KeyManager) {
- return (X509KeyManager)km;
- }
- }
- throw new KeyManagementException("Failed to find an X509KeyManager in " + Arrays.toString(kms));
- }
-
- /**
- * Gets the default trust manager.
- *
- * TODO: Move this to a published API under dalvik.system.
- */
- public static X509TrustManager getDefaultTrustManager() throws KeyManagementException {
- X509TrustManager result = defaultTrustManager;
- if (result == null) {
- // single-check idiom
- defaultTrustManager = result = createDefaultTrustManager();
- }
- return result;
- }
- private static X509TrustManager createDefaultTrustManager() throws KeyManagementException {
- try {
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init((KeyStore) null);
- TrustManager[] tms = tmf.getTrustManagers();
- X509TrustManager trustManager = findX509TrustManager(tms);
- return trustManager;
- } catch (NoSuchAlgorithmException e) {
- throw new KeyManagementException(e);
- } catch (KeyStoreException e) {
- throw new KeyManagementException(e);
- }
- }
- private static X509TrustManager findX509TrustManager(TrustManager[] tms) throws KeyManagementException {
- for (TrustManager tm : tms) {
- if (tm instanceof X509TrustManager) {
- return (X509TrustManager)tm;
- }
- }
- throw new KeyManagementException("Failed to find an X509TrustManager in " + Arrays.toString(tms));
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java b/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java
deleted file mode 100644
index 24b6c61..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLRecordProtocol.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import javax.net.ssl.SSLProtocolException;
-
-/**
- * This class performs functionality dedicated to SSL record layer.
- * It unpacks and routes income data to the appropriate
- * client protocol (handshake, alert, application data protocols)
- * and packages outcome data into SSL/TLS records.
- * Initially created object has null connection state and does not
- * perform any cryptography computations over the income/outcome data.
- * After handshake protocol agreed upon security parameters they are placed
- * into SSLSessionImpl object and available for record protocol as
- * pending session. The order of setting up of the pending session
- * as an active session differs for client and server modes.
- * So for client mode the parameters are provided by handshake protocol
- * during retrieving of change_cipher_spec message to be sent (by calling of
- * getChangeCipherSpecMesage method).
- * For server side mode record protocol retrieves the parameters from
- * handshake protocol after receiving of client's change_cipher_spec message.
- * After the pending session has been set up as a current session,
- * new connection state object is created and used for encryption/decryption
- * of the messages.
- * Among with base functionality this class provides the information about
- * constrains on the data length, and information about correspondence
- * of plain and encrypted data lengths.
- * For more information on TLS v1 see http://www.ietf.org/rfc/rfc2246.txt,
- * on SSL v3 see http://wp.netscape.com/eng/ssl3,
- * on SSL v2 see http://wp.netscape.com/eng/security/SSL_2.html.
- */
-public class SSLRecordProtocol {
-
- /**
- * Maximum length of allowed plain data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_DATA_LENGTH = 16384; // 2^14
- /**
- * Maximum length of allowed compressed data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_COMPRESSED_DATA_LENGTH
- = MAX_DATA_LENGTH + 1024;
- /**
- * Maximum length of allowed ciphered data fragment
- * as specified by TLS specification.
- */
- protected static final int MAX_CIPHERED_DATA_LENGTH
- = MAX_COMPRESSED_DATA_LENGTH + 1024;
- /**
- * Maximum length of ssl record. It is counted as:
- * type(1) + version(2) + length(2) + MAX_CIPHERED_DATA_LENGTH
- */
- protected static final int MAX_SSL_PACKET_SIZE
- = MAX_CIPHERED_DATA_LENGTH + 5;
- // the SSL session used for connection
- private SSLSessionImpl session;
- // protocol version of the connection
- private byte[] version;
- // input stream of record protocol
- private SSLInputStream in;
- // handshake protocol object to which handshaking data will be transmitted
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to indicate alerts occurred/received
- private AlertProtocol alertProtocol;
- // application data object to which application data will be transmitted
- private Appendable appData;
- // connection state holding object
- private ConnectionState
- activeReadState, activeWriteState, pendingConnectionState;
-
- // logger
- private Logger.Stream logger = Logger.getStream("record");
-
- // flag indicating if session object has been changed after
- // handshake phase (to distinguish session pending state)
- private boolean sessionWasChanged = false;
-
- // change cipher spec message content
- private static final byte[] change_cipher_spec_byte = new byte[] {1};
-
- /**
- * Creates an instance of record protocol and tunes
- * up the client protocols to use ut.
- * @param handshakeProtocol: HandshakeProtocol
- * @param alertProtocol: AlertProtocol
- * @param in: SSLInputStream
- * @param appData: Appendable
- */
- protected SSLRecordProtocol(HandshakeProtocol handshakeProtocol,
- AlertProtocol alertProtocol,
- SSLInputStream in,
- Appendable appData) {
- this.handshakeProtocol = handshakeProtocol;
- this.handshakeProtocol.setRecordProtocol(this);
- this.alertProtocol = alertProtocol;
- this.alertProtocol.setRecordProtocol(this);
- this.in = in;
- this.appData = appData;
- }
-
- /**
- * Returns the session obtained during the handshake negotiation.
- * If the handshake process was not completed, method returns null.
- * @return the session in effect.
- */
- protected SSLSessionImpl getSession() {
- return session;
- }
-
- /**
- * Returns the minimum possible length of the SSL record.
- * @return
- */
- protected int getMinRecordSize() {
- return (activeReadState == null)
- ? 6 // type + version + length + 1 byte of data
- : 5 + activeReadState.getMinFragmentSize();
- }
-
- /**
- * Returns the record length for the specified incoming data length.
- * If actual resulting record length is greater than
- * MAX_CIPHERED_DATA_LENGTH, MAX_CIPHERED_DATA_LENGTH is returned.
- */
- protected int getRecordSize(int data_size) {
- if (activeWriteState == null) {
- return 5+data_size; // type + version + length + data_size
- } else {
- int res = 5 + activeWriteState.getFragmentSize(data_size);
- return (res > MAX_CIPHERED_DATA_LENGTH)
- ? MAX_CIPHERED_DATA_LENGTH // so the source data should be
- // split into several packets
- : res;
- }
- }
-
- /**
- * Returns the upper bound of length of data containing in the record with
- * specified length.
- * If the provided record_size is greater or equal to
- * MAX_CIPHERED_DATA_LENGTH the returned value will be
- * MAX_DATA_LENGTH
- * counted as for data with
- * MAX_CIPHERED_DATA_LENGTH length.
- */
- protected int getDataSize(int record_size) {
- record_size -= 5; // - (type + version + length + data_size)
- if (record_size > MAX_CIPHERED_DATA_LENGTH) {
- // the data of such size consists of the several packets
- return MAX_DATA_LENGTH;
- }
- if (activeReadState == null) {
- return record_size;
- }
- return activeReadState.getContentSize(record_size);
- }
-
- /**
- * Depending on the Connection State (Session) encrypts and compress
- * the provided data, and packs it into TLSCiphertext structure.
- * @param content_type: int
- * @return ssl packet created over the current connection state
- */
- protected byte[] wrap(byte content_type, DataStream dataStream) {
- byte[] fragment = dataStream.getData(MAX_DATA_LENGTH);
- return wrap(content_type, fragment, 0, fragment.length);
- }
-
- /**
- * Depending on the Connection State (Session) encrypts and compress
- * the provided data, and packs it into TLSCiphertext structure.
- * @param content_type: int
- * @param fragment: byte[]
- * @return ssl packet created over the current connection state
- */
- protected byte[] wrap(byte content_type,
- byte[] fragment, int offset, int len) {
- if (logger != null) {
- logger.println("SSLRecordProtocol.wrap: TLSPlaintext.fragment["
- +len+"]:");
- logger.print(fragment, offset, len);
- }
- if (len > MAX_DATA_LENGTH) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "The provided chunk of data is too big: " + len
- + " > MAX_DATA_LENGTH == "+MAX_DATA_LENGTH));
- }
- byte[] ciphered_fragment = fragment;
- if (activeWriteState != null) {
- ciphered_fragment =
- activeWriteState.encrypt(content_type, fragment, offset, len);
- if (ciphered_fragment.length > MAX_CIPHERED_DATA_LENGTH) {
- throw new AlertException(
- AlertProtocol.INTERNAL_ERROR,
- new SSLProtocolException(
- "The ciphered data increased more than on 1024 bytes"));
- }
- if (logger != null) {
- logger.println("SSLRecordProtocol.wrap: TLSCiphertext.fragment["
- +ciphered_fragment.length+"]:");
- logger.print(ciphered_fragment);
- }
- }
- return packetize(content_type, version, ciphered_fragment);
- }
-
- private byte[] packetize(byte type, byte[] version, byte[] fragment) {
- byte[] buff = new byte[5+fragment.length];
- buff[0] = type;
- if (version != null) {
- buff[1] = version[0];
- buff[2] = version[1];
- } else {
- buff[1] = 3;
- buff[2] = 1;
- }
- buff[3] = (byte) ((0x00FF00 & fragment.length) >> 8);
- buff[4] = (byte) (0x0000FF & fragment.length);
- System.arraycopy(fragment, 0, buff, 5, fragment.length);
- return buff;
- }
-
- /**
- * Set the ssl session to be used after sending the changeCipherSpec message
- * @param session: SSLSessionImpl
- */
- private void setSession(SSLSessionImpl session) {
- if (!sessionWasChanged) {
- // session was not changed for current handshake process
- if (logger != null) {
- logger.println("SSLRecordProtocol.setSession: Set pending session");
- logger.println(" cipher name: " + session.getCipherSuite());
- }
- this.session = session;
- // create new connection state
- pendingConnectionState = ((version == null) || (version[1] == 1))
- ? (ConnectionState) new ConnectionStateTLS(getSession())
- : (ConnectionState) new ConnectionStateSSLv3(getSession());
- sessionWasChanged = true;
- } else {
- // wait for rehandshaking's session
- sessionWasChanged = false;
- }
- }
-
- /**
- * Returns the change cipher spec message to be sent to another peer.
- * The pending connection state will be built on the base of provided
- * session object
- * The calling of this method triggers pending write connection state to
- * be active.
- * @return ssl record containing the "change cipher spec" message.
- */
- protected byte[] getChangeCipherSpecMesage(SSLSessionImpl session) {
- // make change_cipher_spec_message:
- byte[] change_cipher_spec_message;
- if (activeWriteState == null) {
- change_cipher_spec_message = new byte[] {
- ContentType.CHANGE_CIPHER_SPEC, version[0],
- version[1], 0, 1, 1
- };
- } else {
- change_cipher_spec_message =
- packetize(ContentType.CHANGE_CIPHER_SPEC, version,
- activeWriteState.encrypt(ContentType.CHANGE_CIPHER_SPEC,
- change_cipher_spec_byte, 0, 1));
- }
- setSession(session);
- activeWriteState = pendingConnectionState;
- if (logger != null) {
- logger.println("SSLRecordProtocol.getChangeCipherSpecMesage");
- logger.println("activeWriteState = pendingConnectionState");
- logger.print(change_cipher_spec_message);
- }
- return change_cipher_spec_message;
- }
-
- /**
- * 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 {
- in.skip(2); // just skip the version number
- }
- 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;
- }
-
- /**
- * Passes the alert information to the alert protocol.
- * @param level: byte
- * @param description: byte
- */
- protected void alert(byte level, byte description) {
- if (logger != null) {
- logger.println("SSLRecordProtocol.allert: "+level+" "+description);
- }
- alertProtocol.alert(level, description);
- }
-
- /**
- * Sets up the SSL version used in this connection.
- * This method is calling from the handshake protocol after
- * it becomes known which protocol version will be used.
- * @param ver: byte[]
- * @return
- */
- protected void setVersion(byte[] ver) {
- this.version = ver;
- }
-
- /**
- * Shuts down the protocol. It will be impossible to use the instance
- * after the calling of this method.
- */
- protected void shutdown() {
- session = null;
- version = null;
- in = null;
- handshakeProtocol = null;
- alertProtocol = null;
- appData = null;
- if (pendingConnectionState != null) {
- pendingConnectionState.shutdown();
- }
- pendingConnectionState = null;
- if (activeReadState != null) {
- activeReadState.shutdown();
- }
- activeReadState = null;
- if (activeReadState != null) {
- activeReadState.shutdown();
- }
- activeWriteState = null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java b/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java
deleted file mode 100644
index a380ce9..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSessionCache.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * A persistent {@link javax.net.ssl.SSLSession} cache used by
- * {@link javax.net.ssl.SSLSessionContext} to share server-side SSL sessions
- * across processes. For example, this cache enables one server to resume
- * a session started by a different server based on a session ID provided
- * by the client.
- *
- * <p>The {@code SSLSessionContext} implementation converts
- * {@code SSLSession}s into raw bytes and vice versa. The exact makeup of the
- * session data is dependent upon the caller's implementation and is opaque to
- * the {@code SSLServerSessionCache} implementation.
- */
-public interface SSLServerSessionCache {
-
- /**
- * Gets the session data for given session ID.
- *
- * @param id from {@link javax.net.ssl.SSLSession#getId()}
- * @return the session data or null if none is cached
- * @throws NullPointerException if id is null
- */
- public byte[] getSessionData(byte[] id);
-
- /**
- * Stores session data for the given session.
- *
- * @param session to cache data for
- * @param sessionData to cache
- * @throws NullPointerException if session or data is null
- */
- public void putSessionData(SSLSession session, byte[] sessionData);
-} \ No newline at end of file
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java
deleted file mode 100644
index 5b16f85..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSocketFactoryImpl.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.security.KeyManagementException;
-import javax.net.ssl.SSLServerSocketFactory;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Implementation of SSLServerSocketFactory.
- */
-public class SSLServerSocketFactoryImpl extends SSLServerSocketFactory {
-
- private SSLParametersImpl sslParameters;
- private IOException instantiationException;
-
- /**
- * Constructor.
- */
- public SSLServerSocketFactoryImpl() {
- try {
- this.sslParameters = SSLParametersImpl.getDefault();
- this.sslParameters.setUseClientMode(false);
- } catch (KeyManagementException e) {
- instantiationException =
- new IOException("Delayed instantiation exception:");
- instantiationException.initCause(e);
- }
- }
-
- /**
- * Constructor.
- */
- protected SSLServerSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = (SSLParametersImpl) sslParameters.clone();
- this.sslParameters.setUseClientMode(false);
- }
-
- /**
- * @see javax.net.ssl.SSLServerSocketFactory#getDefaultCipherSuites()
- */
- @Override
- public String[] getDefaultCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * @see javax.net.ssl.SSLServerSocketFactory#getSupportedCipherSuites()
- */
- @Override
- public String[] getSupportedCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket()
- */
- @Override
- public ServerSocket createServerSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int)
- */
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int,int)
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog)
- throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port, backlog,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.ServerSocketFactory#createServerSocket(int,int,InetAddress)
- */
- @Override
- public ServerSocket createServerSocket(int port, int backlog,
- InetAddress iAddress) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLServerSocketImpl(port, backlog, iAddress,
- (SSLParametersImpl) sslParameters.clone());
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java b/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java
deleted file mode 100644
index a30e3b4..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLServerSocketImpl.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import javax.net.ssl.SSLServerSocket;
-
-/**
- * SSLServerSocket implementation
- * @see javax.net.ssl.SSLServerSocket class documentation for more information.
- */
-public class SSLServerSocketImpl extends SSLServerSocket {
-
- // the sslParameters object encapsulates all the info
- // about supported and enabled cipher suites and protocols,
- // as well as the information about client/server mode of
- // ssl socket, whether it require/want client authentication or not,
- // and controls whether new SSL sessions may be established by this
- // socket or not.
- private final SSLParametersImpl sslParameters;
-
- // logger
- private Logger.Stream logger = Logger.getStream("ssocket");
-
- /**
- * Ctor
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(SSLParametersImpl sslParameters) throws IOException {
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, SSLParametersImpl sslParameters)
- throws IOException {
- super(port);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param backlog: int
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, int backlog,
- SSLParametersImpl sslParameters) throws IOException {
- super(port, backlog);
- this.sslParameters = sslParameters;
- }
-
- /**
- * Ctor
- * @param port: int
- * @param backlog: int
- * @param iAddress: InetAddress
- * @param sslParameters: SSLParameters
- * @throws IOException
- */
- protected SSLServerSocketImpl(int port, int backlog,
- InetAddress iAddress,
- SSLParametersImpl sslParameters)
- throws IOException {
- super(port, backlog, iAddress);
- this.sslParameters = sslParameters;
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getSupportedCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnabledCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnabledCipherSuites(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getSupportedProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnabledProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnabledProtocols(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setUseClientMode(boolean)
- * method documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- sslParameters.setUseClientMode(mode);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getUseClientMode()
- * method documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setNeedClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getNeedClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setWantClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getWantClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#setEnableSessionCreation(boolean)
- * method documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLServerSocket#getEnableSessionCreation()
- * method documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
-
- // ------------- ServerSocket's methods overridings ----------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.ServerSocket#accept()
- * method documentation for more information
- */
- @Override
- public Socket accept() throws IOException {
- if (logger != null) {
- logger.println("SSLServerSocketImpl.accept ..");
- }
- SSLSocketImpl s = new SSLSocketImpl(
- (SSLParametersImpl) sslParameters.clone());
- implAccept(s);
- s.init();
- if (logger != null) {
- logger.println("SSLServerSocketImpl: accepted, initialized");
- }
- return s;
- }
-
- /**
- * Returns the string representation of the object.
- */
- @Override
- public String toString() {
- return "[SSLServerSocketImpl]";
- }
-
- // -----------------------------------------------------------------
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java b/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
deleted file mode 100644
index 9631b1e..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSessionImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Principal;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Map;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSessionBindingEvent;
-import javax.net.ssl.SSLSessionBindingListener;
-import javax.net.ssl.SSLSessionContext;
-import org.conscrypt.util.EmptyArray;
-
-public final class SSLSessionImpl implements SSLSession, Cloneable {
-
- /*
- * Holds default instances so class preloading doesn't create an instance of
- * it.
- */
- private static class DefaultHolder {
- public static final SSLSessionImpl NULL_SESSION = new SSLSessionImpl(null);
- }
-
- private long creationTime;
- private boolean isValid = true;
- private final Map<String, Object> values = new HashMap<String, Object>();
-
- byte[] id;
- long lastAccessedTime;
- ProtocolVersion protocol;
- CipherSuite cipherSuite;
- SSLSessionContext context;
- X509Certificate[] localCertificates;
- X509Certificate[] peerCertificates;
- private String peerHost;
- private int peerPort = -1;
- byte[] master_secret;
- byte[] clientRandom;
- byte[] serverRandom;
- final boolean isServer;
-
- public static SSLSessionImpl getNullSession() {
- return DefaultHolder.NULL_SESSION;
- }
-
- public SSLSessionImpl(CipherSuite cipher_suite, SecureRandom secureRandom) {
- creationTime = System.currentTimeMillis();
- lastAccessedTime = creationTime;
- if (cipher_suite == null) {
- this.cipherSuite = CipherSuite.SSL_NULL_WITH_NULL_NULL;
- id = EmptyArray.BYTE;
- isServer = false;
- isValid = false;
- } else {
- this.cipherSuite = cipher_suite;
- id = new byte[32];
- secureRandom.nextBytes(id);
- long time = creationTime / 1000;
- id[28] = (byte) ((time & 0xFF000000) >>> 24);
- id[29] = (byte) ((time & 0x00FF0000) >>> 16);
- id[30] = (byte) ((time & 0x0000FF00) >>> 8);
- id[31] = (byte) ((time & 0x000000FF));
- isServer = true;
- }
-
- }
-
- public SSLSessionImpl(SecureRandom secureRandom) {
- this(null, secureRandom);
- }
-
- public int getApplicationBufferSize() {
- return SSLRecordProtocol.MAX_DATA_LENGTH;
- }
-
- public String getCipherSuite() {
- return cipherSuite.getName();
- }
-
- public long getCreationTime() {
- return creationTime;
- }
-
- public byte[] getId() {
- return id;
- }
-
- public long getLastAccessedTime() {
- return lastAccessedTime;
- }
-
- public Certificate[] getLocalCertificates() {
- return localCertificates;
- }
-
- public Principal getLocalPrincipal() {
- if (localCertificates != null && localCertificates.length > 0) {
- return localCertificates[0].getSubjectX500Principal();
- }
- return null;
- }
-
- public int getPacketBufferSize() {
- return SSLRecordProtocol.MAX_SSL_PACKET_SIZE;
- }
-
- public javax.security.cert.X509Certificate[] getPeerCertificateChain()
- throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[peerCertificates.length];
- for (int i = 0; i < certs.length; i++) {
- try {
- certs[i] = javax.security.cert.X509Certificate.getInstance(peerCertificates[i]
- .getEncoded());
- } catch (javax.security.cert.CertificateException ignored) {
- } catch (CertificateEncodingException ignored) {
- }
- }
- return certs;
- }
-
- public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- return peerCertificates;
- }
-
- public String getPeerHost() {
- return peerHost;
- }
-
- public int getPeerPort() {
- return peerPort;
- }
-
- public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
- if (peerCertificates == null) {
- throw new SSLPeerUnverifiedException("No peer certificate");
- }
- return peerCertificates[0].getSubjectX500Principal();
- }
-
- public String getProtocol() {
- return (protocol == null) ? "NONE" : protocol.name;
- }
-
- public SSLSessionContext getSessionContext() {
- return context;
- }
-
- public Object getValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- return values.get(name);
- }
-
- public String[] getValueNames() {
- return values.keySet().toArray(new String[values.size()]);
- }
-
- public void invalidate() {
- isValid = false;
- context = null;
- }
-
- public boolean isValid() {
- if (isValid && context != null && context.getSessionTimeout() != 0
- && lastAccessedTime + context.getSessionTimeout() > System.currentTimeMillis()) {
- isValid = false;
- }
- return isValid;
- }
-
- public void putValue(String name, Object value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("name == null || value == null");
- }
- Object old = values.put(name, value);
- if (value instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) value).valueBound(new SSLSessionBindingEvent(this, name));
- }
- if (old instanceof SSLSessionBindingListener) {
- ((SSLSessionBindingListener) old).valueUnbound(new SSLSessionBindingEvent(this, name));
- }
-
- }
-
- public void removeValue(String name) {
- if (name == null) {
- throw new IllegalArgumentException("name == null");
- }
- Object old = values.remove(name);
- if (old instanceof SSLSessionBindingListener) {
- SSLSessionBindingListener listener = (SSLSessionBindingListener) old;
- listener.valueUnbound(new SSLSessionBindingEvent(this, name));
- }
- }
-
- @Override
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
- void setPeer(String peerHost, int peerPort) {
- this.peerHost = peerHost;
- this.peerPort = peerPort;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java b/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java
deleted file mode 100644
index dc971ac..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketFactoryImpl.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import javax.net.ssl.SSLSocketFactory;
-import org.conscrypt.util.EmptyArray;
-
-/**
- * Implementation of SSLSocketFactory.
- */
-public class SSLSocketFactoryImpl extends SSLSocketFactory {
-
- private final SSLParametersImpl sslParameters;
- private final IOException instantiationException;
-
- /**
- * Constructor.
- */
- public SSLSocketFactoryImpl() {
- SSLParametersImpl sslParametersLocal = null;
- IOException instantiationExceptionLocal = null;
- try {
- sslParametersLocal = SSLParametersImpl.getDefault();
- } catch (KeyManagementException e) {
- instantiationExceptionLocal = new IOException("Delayed instantiation exception:");
- instantiationExceptionLocal.initCause(e);
- }
- this.sslParameters = sslParametersLocal;
- this.instantiationException = instantiationExceptionLocal;
- }
-
- /**
- * Constructor.
- */
- protected SSLSocketFactoryImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.instantiationException = null;
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
- */
- @Override
- public String[] getDefaultCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
- */
- @Override
- public String[] getSupportedCipherSuites() {
- if (instantiationException != null) {
- return EmptyArray.STRING;
- }
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * @see javax.net.ssl.SSLSocketFactory#createSocket(Socket,String,int,boolean)
- */
- @Override
- public Socket createSocket(Socket s, String host, int port,
- boolean autoClose) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketWrapper(s, host, port, autoClose, (SSLParametersImpl) sslParameters
- .clone());
- }
-
- // -------------- Methods inherided from SocketFactory --------------
-
- /**
- * @see javax.net.SocketFactory#createSocket()
- */
- @Override
- public Socket createSocket() throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl((SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(String,int)
- */
- @Override
- public Socket createSocket(String host, int port)
- throws IOException, UnknownHostException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(String,int,InetAddress,int)
- */
- @Override
- public Socket createSocket(String host, int port,
- InetAddress localHost, int localPort) throws IOException,
- UnknownHostException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port, localHost, localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(InetAddress,int)
- */
- @Override
- public Socket createSocket(InetAddress host, int port)
- throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(host, port,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- /**
- * @see javax.net.SocketFactory#createSocket(InetAddress,int,InetAddress,int)
- */
- @Override
- public Socket createSocket(InetAddress address, int port,
- InetAddress localAddress, int localPort) throws IOException {
- if (instantiationException != null) {
- throw instantiationException;
- }
- return new SSLSocketImpl(address, port, localAddress, localPort,
- (SSLParametersImpl) sslParameters.clone());
- }
-
- // ------------------------------------------------------------------
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java b/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
deleted file mode 100644
index 138a143..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketImpl.java
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import javax.net.ssl.HandshakeCompletedEvent;
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLEngineResult;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-/**
- * SSLSocket implementation.
- * @see javax.net.ssl.SSLSocket class documentation for more information.
- */
-public class SSLSocketImpl extends SSLSocket {
-
- // indicates if handshake has been started
- private boolean handshake_started = false;
-
- // used when we're wrapping a socket
- private final String wrappedHost;
- private final int wrappedPort;
-
- // record protocol to be used
- protected SSLRecordProtocol recordProtocol;
- // handshake protocol to be used
- private HandshakeProtocol handshakeProtocol;
- // alert protocol to be used
- private AlertProtocol alertProtocol;
- // application data input stream, this stream is presented by
- // ssl socket as an input stream. Additionally this object is a
- // place where application data will be stored by record protocol
- private SSLSocketInputStream appDataIS;
- // outgoing application data stream
- private SSLSocketOutputStream appDataOS;
- // active session object
- private SSLSessionImpl session;
-
- private boolean socket_was_closed = false;
-
- // the sslParameters object encapsulates all the info
- // about supported and enabled cipher suites and protocols,
- // as well as the information about client/server mode of
- // ssl socket, whether it require/want client authentication or not,
- // and controls whether new SSL sessions may be established by this
- // socket or not.
- protected SSLParametersImpl sslParameters;
- // super's streams to be wrapped:
- protected InputStream input;
- protected OutputStream output;
- // handshake complete listeners
- private ArrayList<HandshakeCompletedListener> listeners;
- // logger
- private Logger.Stream logger = Logger.getStream("socket");
-
- // ----------------- Constructors and initializers --------------------
-
- /**
- * Constructor
- * @param sslParameters: SSLParametersImpl
- * @see javax.net.ssl.SSLSocket#SSLSocket() method documentation
- * for more information.
- */
- protected SSLSocketImpl(SSLParametersImpl sslParameters) {
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- // init should be called after creation!
- }
-
- /**
- * Constructor
- * @param host: String
- * @param port: int
- * @param sslParameters: SSLParametersImpl
- * @throws IOException
- * @throws UnknownHostException
- * @see javax.net.ssl.SSLSocket#SSLSocket(String,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(String host, int port, SSLParametersImpl sslParameters)
- throws IOException, UnknownHostException {
- super(host, port);
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.sslParameters = sslParameters;
- init();
- }
-
- /**
- * Constructor
- * @param host: String
- * @param port: int
- * @param localHost: InetAddress
- * @param localPort: int
- * @param sslParameters: SSLParametersImpl
- * @throws IOException
- * @throws UnknownHostException
- * @see javax.net.ssl.SSLSocket#SSLSocket(String,int,InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(String host, int port,
- InetAddress localHost, int localPort,
- SSLParametersImpl sslParameters) throws IOException,
- UnknownHostException {
- super(host, port, localHost, localPort);
- this.wrappedHost = host;
- this.wrappedPort = port;
- this.sslParameters = sslParameters;
- init();
- }
-
- /**
- * Constructor
- * @param host: InetAddress
- * @param port: int
- * @param sslParameters: SSLParametersImpl
- * @return
- * @throws IOException
- * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(InetAddress host, int port,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port);
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- init();
- }
-
- /**
- * Constructor
- * @param address: InetAddress
- * @param port: int
- * @param localAddress: InetAddress
- * @param localPort: int
- * @param sslParameters: SSLParametersImpl
- * @return
- * @throws IOException
- * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int,InetAddress,int)
- * method documentation for more information.
- */
- protected SSLSocketImpl(InetAddress address, int port,
- InetAddress localAddress, int localPort,
- SSLParametersImpl sslParameters) throws IOException {
- super(address, port, localAddress, localPort);
- this.sslParameters = sslParameters;
- this.wrappedHost = null;
- this.wrappedPort = -1;
- init();
- }
-
- /**
- * Initialize the SSL socket.
- */
- protected void init() throws IOException {
- if (appDataIS != null) {
- // already initialized
- return;
- }
- initTransportLayer();
- appDataIS = new SSLSocketInputStream(this);
- appDataOS = new SSLSocketOutputStream(this);
- }
-
- /**
- * Initialize the transport data streams.
- */
- protected void initTransportLayer() throws IOException {
- input = super.getInputStream();
- output = super.getOutputStream();
- }
-
- /**
- * Closes the transport data streams.
- */
- protected void closeTransportLayer() throws IOException {
- super.close();
- if (input != null) {
- input.close();
- output.close();
- }
- }
-
- String getWrappedHostName() {
- return wrappedHost;
- }
-
- int getWrappedPort() {
- return wrappedPort;
- }
-
- String getPeerHostName() {
- if (wrappedHost != null) {
- return wrappedHost;
- }
- InetAddress inetAddress = super.getInetAddress();
- if (inetAddress != null) {
- return inetAddress.getHostName();
- }
- return null;
- }
-
- int getPeerPort() {
- return (wrappedPort == -1) ? super.getPort() : wrappedPort;
- }
-
- // --------------- SSLParameters based methods ---------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSupportedCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedCipherSuites() {
- return CipherSuite.getSupportedCipherSuiteNames();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnabledCipherSuites()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledCipherSuites() {
- return sslParameters.getEnabledCipherSuites();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- sslParameters.setEnabledCipherSuites(suites);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSupportedProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getSupportedProtocols() {
- return ProtocolVersion.supportedProtocols.clone();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnabledProtocols()
- * method documentation for more information
- */
- @Override
- public String[] getEnabledProtocols() {
- return sslParameters.getEnabledProtocols();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnabledProtocols(String[])
- * method documentation for more information
- */
- @Override
- public void setEnabledProtocols(String[] protocols) {
- sslParameters.setEnabledProtocols(protocols);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setUseClientMode(boolean)
- * method documentation for more information
- */
- @Override
- public void setUseClientMode(boolean mode) {
- if (handshake_started) {
- throw new IllegalArgumentException(
- "Could not change the mode after the initial handshake has begun.");
- }
- sslParameters.setUseClientMode(mode);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getUseClientMode()
- * method documentation for more information
- */
- @Override
- public boolean getUseClientMode() {
- return sslParameters.getUseClientMode();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setNeedClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setNeedClientAuth(boolean need) {
- sslParameters.setNeedClientAuth(need);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getNeedClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getNeedClientAuth() {
- return sslParameters.getNeedClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setWantClientAuth(boolean)
- * method documentation for more information
- */
- @Override
- public void setWantClientAuth(boolean want) {
- sslParameters.setWantClientAuth(want);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getWantClientAuth()
- * method documentation for more information
- */
- @Override
- public boolean getWantClientAuth() {
- return sslParameters.getWantClientAuth();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean)
- * method documentation for more information
- */
- @Override
- public void setEnableSessionCreation(boolean flag) {
- sslParameters.setEnableSessionCreation(flag);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getEnableSessionCreation()
- * method documentation for more information
- */
- @Override
- public boolean getEnableSessionCreation() {
- return sslParameters.getEnableSessionCreation();
- }
-
- // -----------------------------------------------------------------
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getSession()
- * method documentation for more information
- */
- @Override
- public SSLSession getSession() {
- if (!handshake_started) {
- try {
- startHandshake();
- } catch (IOException e) {
- // return an invalid session with
- // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL"
- return SSLSessionImpl.getNullSession();
- }
- }
- return session;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener)
- * method documentation for more information
- */
- @Override
- public void addHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- listeners = new ArrayList<HandshakeCompletedListener>();
- }
- listeners.add(listener);
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener)
- * method documentation for more information
- */
- @Override
- public void removeHandshakeCompletedListener(
- HandshakeCompletedListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("Provided listener is null");
- }
- if (listeners == null) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- if (!listeners.remove(listener)) {
- throw new IllegalArgumentException(
- "Provided listener is not registered");
- }
- }
-
- /**
- * Performs the handshake process over the SSL/TLS connection
- * as described in rfc 2246, TLS v1 specification
- * http://www.ietf.org/rfc/rfc2246.txt. If the initial handshake
- * has been already done, this method initiates rehandshake.
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#startHandshake()
- * method documentation for more information
- */
- @Override
- public void startHandshake() throws IOException {
- if (appDataIS == null) {
- throw new IOException("Socket is not connected.");
- }
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
-
- if (!handshake_started) {
- handshake_started = true;
- if (sslParameters.getUseClientMode()) {
- if (logger != null) {
- logger.println("SSLSocketImpl: CLIENT");
- }
- handshakeProtocol = new ClientHandshakeImpl(this);
- } else {
- if (logger != null) {
- logger.println("SSLSocketImpl: SERVER");
- }
- handshakeProtocol = new ServerHandshakeImpl(this);
- }
-
- alertProtocol = new AlertProtocol();
- recordProtocol = new SSLRecordProtocol(handshakeProtocol,
- alertProtocol, new SSLStreamedInput(input),
- appDataIS.dataPoint);
- }
-
- if (logger != null) {
- logger.println("SSLSocketImpl.startHandshake");
- }
-
- handshakeProtocol.start();
-
- doHandshake();
-
- if (logger != null) {
- logger.println("SSLSocketImpl.startHandshake: END");
- }
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getInputStream()
- * method documentation for more information
- */
- @Override
- public InputStream getInputStream() throws IOException {
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
- return appDataIS;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#getOutputStream()
- * method documentation for more information
- */
- @Override
- public OutputStream getOutputStream() throws IOException {
- if (socket_was_closed) {
- throw new IOException("Socket has already been closed.");
- }
- return appDataOS;
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.Socket#connect(SocketAddress)
- * method documentation for more information
- */
- @Override
- public void connect(SocketAddress endpoint) throws IOException {
- super.connect(endpoint);
- init();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see java.net.Socket#connect(SocketAddress,int)
- * method documentation for more information
- */
- @Override
- public void connect(SocketAddress endpoint, int timeout)
- throws IOException {
- super.connect(endpoint, timeout);
- init();
- }
-
- /**
- * This method works according to the specification of implemented class.
- * @see javax.net.ssl.SSLSocket#close()
- * method documentation for more information
- */
- @Override
- public void close() throws IOException {
- if (logger != null) {
- logger.println("SSLSocket.close "+socket_was_closed);
- }
- if (!socket_was_closed) {
- if (handshake_started) {
- alertProtocol.alert(AlertProtocol.WARNING,
- AlertProtocol.CLOSE_NOTIFY);
- try {
- output.write(alertProtocol.wrap());
- } catch (IOException ex) { }
- alertProtocol.setProcessed();
- }
- shutdown();
- closeTransportLayer();
- socket_was_closed = true;
- }
- }
-
- /**
- * This method is not supported for SSLSocket implementation.
- */
- @Override
- public void sendUrgentData(int data) throws IOException {
- throw new SocketException(
- "Method sendUrgentData() is not supported.");
- }
-
- /**
- * This method is not supported for SSLSocket implementation.
- */
- @Override
- public void setOOBInline(boolean on) throws SocketException {
- throw new SocketException(
- "Methods sendUrgentData, setOOBInline are not supported.");
- }
-
- // -----------------------------------------------------------------
-
- private void shutdown() {
- if (handshake_started) {
- alertProtocol.shutdown();
- alertProtocol = null;
- handshakeProtocol.shutdown();
- handshakeProtocol = null;
- recordProtocol.shutdown();
- recordProtocol = null;
- }
- socket_was_closed = true;
- }
-
- /**
- * This method is called by SSLSocketInputStream class
- * when client application tries to read application data from
- * the stream, but there is no data in its underlying buffer.
- * @throws IOException
- */
- protected void needAppData() throws IOException {
- if (!handshake_started) {
- startHandshake();
- }
- int type;
- if (logger != null) {
- logger.println("SSLSocket.needAppData..");
- }
- try {
- while(appDataIS.available() == 0) {
- // read and unwrap the record contained in the transport
- // input stream (SSLStreamedInput), pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- switch (type = recordProtocol.unwrap()) {
- case ContentType.HANDSHAKE:
- if (!handshakeProtocol.getStatus().equals(
- SSLEngineResult.HandshakeStatus
- .NOT_HANDSHAKING)) {
- // handshake protocol got addressed to it message
- // and did not ignore it, so it's a rehandshake
- doHandshake();
- }
- break;
- case ContentType.ALERT:
- processAlert();
- if (socket_was_closed) {
- return;
- }
- break;
- case ContentType.APPLICATION_DATA:
- if (logger != null) {
- logger.println(
- "SSLSocket.needAppData: got the data");
- }
- break;
- default:
- // will throw exception
- reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLException("Unexpected message of type "
- + type + " has been got"));
- }
- if (alertProtocol.hasAlert()) {
- // warning alert occurred during wrap or unwrap
- // (note: fatal alert causes AlertException
- // to be thrown)
- output.write(alertProtocol.wrap());
- alertProtocol.setProcessed();
- }
- if (socket_was_closed) {
- appDataIS.setEnd();
- return;
- }
- }
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- } catch (EndOfSourceException e) {
- // end of socket's input stream has been reached
- appDataIS.setEnd();
- }
- if (logger != null) {
- logger.println("SSLSocket.needAppData: app data len: "
- + appDataIS.available());
- }
- }
-
- /**
- * This method is called by SSLSocketOutputStream when a client application
- * tries to send the data over ssl protocol.
- */
- protected void writeAppData(byte[] data, int offset, int len) throws IOException {
- if (!handshake_started) {
- startHandshake();
- }
- if (logger != null) {
- logger.println("SSLSocket.writeAppData: " +
- len + " " + SSLRecordProtocol.MAX_DATA_LENGTH);
- //logger.println(new String(data, offset, len));
- }
- try {
- if (len < SSLRecordProtocol.MAX_DATA_LENGTH) {
- output.write(recordProtocol.wrap(ContentType.APPLICATION_DATA,
- data, offset, len));
- } else {
- while (len >= SSLRecordProtocol.MAX_DATA_LENGTH) {
- output.write(recordProtocol.wrap(
- ContentType.APPLICATION_DATA, data, offset,
- SSLRecordProtocol.MAX_DATA_LENGTH));
- offset += SSLRecordProtocol.MAX_DATA_LENGTH;
- len -= SSLRecordProtocol.MAX_DATA_LENGTH;
- }
- if (len > 0) {
- output.write(
- recordProtocol.wrap(ContentType.APPLICATION_DATA,
- data, offset, len));
- }
- }
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- }
- }
-
- /*
- * Performs handshake process over this connection. The handshake
- * process is directed by the handshake status code provided by
- * handshake protocol. If this status is NEED_WRAP, method retrieves
- * handshake message from handshake protocol and sends it to another peer.
- * If this status is NEED_UNWRAP, method receives and processes handshake
- * message from another peer. Each of this stages (wrap/unwrap) change
- * the state of handshake protocol and this process is performed
- * until handshake status is FINISHED. After handshake process is finished
- * handshake completed event are sent to the registered listeners.
- * For more information about the handshake process see
- * TLS v1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 7.3.
- */
- private void doHandshake() throws IOException {
- SSLEngineResult.HandshakeStatus status;
- int type;
- try {
- while (!(status = handshakeProtocol.getStatus()).equals(
- SSLEngineResult.HandshakeStatus.FINISHED)) {
- if (logger != null) {
- String s = (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_WRAP))
- ? "NEED_WRAP"
- : (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP))
- ? "NEED_UNWRAP"
- : "STATUS: OTHER!";
- logger.println("SSLSocketImpl: HS status: "+s+" "+status);
- }
- if (status.equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
- output.write(handshakeProtocol.wrap());
- } else if (status.equals(
- SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
- // read and unwrap the record contained in the transport
- // input stream (SSLStreamedInput), pass it
- // to appropriate client protocol (alert, handshake, or app)
- // and retrieve the type of unwrapped data
- switch (type = recordProtocol.unwrap()) {
- case ContentType.HANDSHAKE:
- case ContentType.CHANGE_CIPHER_SPEC:
- break;
- case ContentType.APPLICATION_DATA:
- // So it's rehandshake and
- // if app data buffer will be overloaded
- // it will throw alert exception.
- // Probably we should count the number of
- // not handshaking data and make additional
- // constraints (do not expect buffer overflow).
- break;
- case ContentType.ALERT:
- processAlert();
- if (socket_was_closed) {
- return;
- }
- break;
- default:
- // will throw exception
- reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE,
- new SSLException(
- "Unexpected message of type "
- + type + " has been got"));
- }
- } else {
- // will throw exception
- reportFatalAlert(AlertProtocol.INTERNAL_ERROR,
- new SSLException(
- "Handshake passed unexpected status: "+status));
- }
- if (alertProtocol.hasAlert()) {
- // warning alert occurred during wrap or unwrap
- // (note: fatal alert causes AlertException
- // to be thrown)
- output.write(alertProtocol.wrap());
- alertProtocol.setProcessed();
- }
- }
- } catch (EndOfSourceException e) {
- appDataIS.setEnd();
- throw new IOException("Connection was closed");
- } catch (AlertException e) {
- // will throw exception
- reportFatalAlert(e.getDescriptionCode(), e.getReason());
- }
-
- session = recordProtocol.getSession();
- if (listeners != null) {
- // notify the listeners
- HandshakeCompletedEvent event =
- new HandshakeCompletedEvent(this, session);
- int size = listeners.size();
- for (int i=0; i<size; i++) {
- listeners.get(i)
- .handshakeCompleted(event);
- }
- }
- }
-
- /*
- * Process received alert message
- */
- private void processAlert() throws IOException {
- if (!alertProtocol.hasAlert()) {
- return;
- }
- if (alertProtocol.isFatalAlert()) {
- alertProtocol.setProcessed();
- String description = "Fatal alert received "
- + alertProtocol.getAlertDescription();
- shutdown();
- throw new SSLException(description);
- }
-
- if (logger != null) {
- logger.println("Warning alert received: "
- + alertProtocol.getAlertDescription());
- }
- switch(alertProtocol.getDescriptionCode()) {
- case AlertProtocol.CLOSE_NOTIFY:
- alertProtocol.setProcessed();
- appDataIS.setEnd();
- close();
- return;
- default:
- alertProtocol.setProcessed();
- // TODO: process other warning messages
- }
- }
-
- /*
- * Sends fatal alert message and throws exception
- */
- private void reportFatalAlert(byte description_code,
- SSLException reason) throws IOException {
- alertProtocol.alert(AlertProtocol.FATAL, description_code);
- try {
- // the output stream can be closed
- output.write(alertProtocol.wrap());
- } catch (IOException ex) { }
- alertProtocol.setProcessed();
- shutdown();
- throw reason;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java b/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java
deleted file mode 100644
index 36c5c03..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketInputStream.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.net.ssl.SSLException;
-
-/**
- * This class provides input data stream functionality
- * for SSLSocket. It accumulates the application data
- * received by SSL protocol.
- */
-public final class SSLSocketInputStream extends InputStream {
-
- // The size of the internal data buffer.
- // It should not be less than maximum data chunk enclosed
- // in one ssl packet.
- private static final int BUFFER_SIZE = SSLRecordProtocol.MAX_DATA_LENGTH;
-
- // Internal buffer accumulating the received application data
- private byte[] buffer = new byte[BUFFER_SIZE];
-
- // position of the next byte to read from the buffer
- private int pos;
-
- // position of the last byte to read + 1
- private int end;
-
- // the ssl socket owning the stream
- private final SSLSocketImpl owner;
-
- // the flag indicating that the end of the (owner's) input stream
- // has been reached
- private boolean end_reached = false;
-
- /**
- * Creates the application data input stream for specified socket.
- * @param owner the socket which will provide this input stream
- * to client applications.
- */
- protected SSLSocketInputStream(SSLSocketImpl owner) {
- this.owner = owner;
- }
-
- // The helper delivering the application data from the record layer
- protected Adapter dataPoint = new Adapter();
-
- /**
- * Tells to the stream that the end of the income data has
- * been reached.
- */
- protected void setEnd() {
- end_reached = true;
- }
-
- // ------------------ InputStream implementation -------------------
-
- /**
- * Returns the number of bytes available for reading without blocking.
- * @return the number of available bytes.
- * @throws IOException
- */
- @Override
- public int available() throws IOException {
- return end - pos;
- }
-
- /**
- * Closes the stream
- * @throws IOException
- */
- @Override
- public void close() throws IOException {
- buffer = null;
- }
-
- /**
- * Reads one byte. If there is no data in the underlying buffer,
- * this operation can block until the data will be
- * available.
- * @return read value.
- * @throws IOException
- */
- @Override
- public int read() throws IOException {
- if (buffer == null) {
- throw new IOException("Stream was closed.");
- }
- while (pos == end) {
- if (end_reached) {
- return -1;
- }
- // If there is no data in the buffer
- // - will block until the data will be provided by
- // record layer
- owner.needAppData();
- }
- return buffer[pos++] & 0xFF;
- }
-
- @Override public int read(byte[] b, int off, int len) throws IOException {
- int read_b;
- int i = 0;
- do {
- if ((read_b = read()) == -1) {
- return (i == 0) ? -1 : i;
- }
- b[off+i] = (byte) read_b;
- i++;
- } while ((available() != 0) && (i<len));
- return i;
- }
-
- // The helper class delivering the application data from the record layer
- // to this input stream.
- // It 'adapts' the InputStream interface to Appendable, which is used for
- // transmission of income data from the record protocol to its clients.
- private class Adapter implements org.conscrypt.Appendable {
- /**
- * Appends the data to the stream.
- * This method could be implemented in the outer class
- * itself, but it could be insecure.
- */
- public void append(byte[] src) {
- int length = src.length;
- if (BUFFER_SIZE - (end - pos) < length) {
- // If the size of the buffer is greater than or equals to
- // SSLRecordProtocol.MAX_DATA_LENGTH this situation will
- // happen iff:
- // 1. the length of received data fragment is greater
- // than allowed by the spec
- // 2. it is rehandshaking stage and we have got several
- // extra app data messages.
- // In any case it is better to throw alert exception.
- throw new AlertException(AlertProtocol.INTERNAL_ERROR,
- new SSLException("Could not accept income app data."));
- }
- if (end + length > BUFFER_SIZE) {
- // move the content of the buffer to the beginning
- System.arraycopy(buffer, pos, buffer, 0, end-pos);
- end -= pos;
- pos = 0;
- }
- System.arraycopy(src, 0, buffer, end, length);
- end = end + length;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java b/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java
deleted file mode 100644
index e3afed7..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketOutputStream.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import libcore.io.Streams;
-
-/**
- * This is a application data output stream used in SSLSocket
- * implementation.
- * The written bytes are encrypted, packed into the records,
- * and then sent to the peer host.
- */
-public class SSLSocketOutputStream extends OutputStream {
- private final SSLSocketImpl owner;
-
- protected SSLSocketOutputStream(SSLSocketImpl owner) {
- this.owner = owner;
- }
-
- @Override public void write(int b) throws IOException {
- Streams.writeSingleByte(this, b);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- owner.writeAppData(b, off, len);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java b/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java
deleted file mode 100644
index 2110aea..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLSocketWrapper.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-/**
- * This class wraps the SSL fuctionality over existing conneted socket.
- */
-public class SSLSocketWrapper extends SSLSocketImpl {
-
- private final Socket socket;
- private final boolean autoClose;
-
- protected SSLSocketWrapper(Socket socket, String host, int port, boolean autoClose,
- SSLParametersImpl sslParameters) throws IOException {
- super(host, port, sslParameters);
- if (!socket.isConnected()) {
- throw new SocketException("Socket is not connected.");
- }
- this.socket = socket;
- this.autoClose = autoClose;
- init();
- }
-
- @Override
- protected void initTransportLayer() throws IOException {
- input = socket.getInputStream();
- output = socket.getOutputStream();
- }
-
- @Override
- protected void closeTransportLayer() throws IOException {
- if (autoClose && (input != null)) {
- socket.close();
- input.close();
- output.close();
- }
- }
-
- // ------------------- Wrapping method implementations ---------------
-
- @Override
- public void connect(SocketAddress sockaddr, int timeout)
- throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void connect(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public void bind(SocketAddress sockaddr) throws IOException {
- throw new IOException("Underlying socket is already connected.");
- }
-
- @Override
- public SocketAddress getRemoteSocketAddress() {
- return socket.getRemoteSocketAddress();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- return socket.getLocalSocketAddress();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- return socket.getLocalAddress();
- }
-
- @Override
- public InetAddress getInetAddress() {
- return socket.getInetAddress();
- }
-
- @Override
- public String toString() {
- return "SSL socket over " + socket.toString();
- }
-
- @Override
- public void setSoLinger(boolean on, int linger) throws SocketException {
- socket.setSoLinger(on, linger);
- }
-
- @Override
- public void setTcpNoDelay(boolean on) throws SocketException {
- socket.setTcpNoDelay(on);
- }
-
- @Override
- public void setReuseAddress(boolean on) throws SocketException {
- socket.setReuseAddress(on);
- }
-
- @Override
- public void setKeepAlive(boolean on) throws SocketException {
- socket.setKeepAlive(on);
- }
-
- @Override
- public void setTrafficClass(int tos) throws SocketException {
- socket.setTrafficClass(tos);
- }
-
- @Override
- public void setSoTimeout(int to) throws SocketException {
- socket.setSoTimeout(to);
- }
-
- @Override
- public void setSendBufferSize(int size) throws SocketException {
- socket.setSendBufferSize(size);
- }
-
- @Override
- public void setReceiveBufferSize(int size) throws SocketException {
- socket.setReceiveBufferSize(size);
- }
-
- @Override
- public boolean getTcpNoDelay() throws SocketException {
- return socket.getTcpNoDelay();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- return socket.getReuseAddress();
- }
-
- @Override
- public boolean getOOBInline() throws SocketException {
- return socket.getOOBInline();
- }
-
- @Override
- public boolean getKeepAlive() throws SocketException {
- return socket.getKeepAlive();
- }
-
- @Override
- public int getTrafficClass() throws SocketException {
- return socket.getTrafficClass();
- }
-
- @Override
- public int getSoTimeout() throws SocketException {
- return socket.getSoTimeout();
- }
-
- @Override
- public int getSoLinger() throws SocketException {
- return socket.getSoLinger();
- }
-
- @Override
- public int getSendBufferSize() throws SocketException {
- return socket.getSendBufferSize();
- }
-
- @Override
- public int getReceiveBufferSize() throws SocketException {
- return socket.getReceiveBufferSize();
- }
-
- @Override
- public boolean isConnected() {
- return socket.isConnected();
- }
-
- @Override
- public boolean isClosed() {
- return socket.isClosed();
- }
-
- @Override
- public boolean isBound() {
- return socket.isBound();
- }
-
- @Override
- public boolean isOutputShutdown() {
- return socket.isOutputShutdown();
- }
-
- @Override
- public boolean isInputShutdown() {
- return socket.isInputShutdown();
- }
-
- @Override
- public int getPort() {
- return socket.getPort();
- }
-
- @Override
- public int getLocalPort() {
- return socket.getLocalPort();
- }
-
- @Override
- public FileDescriptor getFileDescriptor$() {
- return socket.getFileDescriptor$();
- }
-
- // -------------------------------------------------------------------
-
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java b/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java
deleted file mode 100644
index 4c8a885..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLStreamedInput.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class acts like a filtered input stream: it takes
- * the bytes from another InputStream.
- */
-public class SSLStreamedInput extends SSLInputStream {
-
- private InputStream in;
-
- public SSLStreamedInput(InputStream in) {
- this.in = in;
- }
-
- @Override
- public int available() throws IOException {
- return in.available();
- }
-
- /**
- * Read an opaque value from the stream.
- * @return the value read from the underlying stream.
- * @throws IOException if the data could not be read from
- * the underlying stream
- * @throws org.conscrypt.EndOfSourceException if the end of the underlying
- * stream has been reached.
- */
- @Override
- public int read() throws IOException {
- int res = in.read();
- if (res < 0) {
- throw new EndOfSourceException();
- }
- return res;
- }
-}
-
diff --git a/crypto/src/main/java/org/conscrypt/SSLv3Constants.java b/crypto/src/main/java/org/conscrypt/SSLv3Constants.java
deleted file mode 100644
index ea6482f..0000000
--- a/crypto/src/main/java/org/conscrypt/SSLv3Constants.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-/**
- *
- * Contains SSL 3.0 constants
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec.</a>
- */
-public class SSLv3Constants {
-
- /**
- * Client is a sender. Used in hash calculating for finished message.
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.6.9
- * Finished</a>
- */
- static final byte[] client = new byte[] { 0x43, 0x4C, 0x4E, 0x54 };
-
- /**
- * Server is a sender. Used in hash calculating for finished message.
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.6.9
- * Finished</a>
- */
- static final byte[] server = new byte[] { 0x53, 0x52, 0x56, 0x52 };
-
- /**
- * pad_1 for MD5
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] MD5pad1 = new byte[] { 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 };
-
- /**
- * pad_1 for SHA
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] SHApad1 = new byte[] { 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36 };
-
- /**
- * pad_2 for MD5
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] MD5pad2 = new byte[] { 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C };
-
- /**
- * pad_2 for SHA
- * @see <a href="http://wp.netscape.com/eng/ssl3">SSL 3.0 Spec., 5.2.3.1
- * Null or standard stream cipher</a>
- */
- static final byte[] SHApad2 = new byte[] { 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
- 0x5C, 0x5C, 0x5C };
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java b/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java
deleted file mode 100644
index 2e55c0d..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHandshakeImpl.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PrivilegedExceptionAction;
-import java.security.PublicKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Arrays;
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.interfaces.DHPublicKey;
-import javax.crypto.spec.DHParameterSpec;
-import javax.crypto.spec.DHPublicKeySpec;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.net.ssl.X509KeyManager;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * Server side handshake protocol implementation.
- * Handshake protocol operates on top of the Record Protocol.
- * It responsible for negotiating a session.
- *
- * The implementation processes inbound client handshake messages,
- * creates and sends respond messages. Outbound messages are supplied
- * to Record Protocol. Detected errors are reported to the Alert protocol.
- *
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.
- * Handshake protocol.</a>
- *
- */
-public class ServerHandshakeImpl extends HandshakeProtocol {
-
- // private key used in key exchange
- private PrivateKey privKey;
-
- /**
- * Creates Server Handshake Implementation
- *
- * @param owner
- */
- public ServerHandshakeImpl(Object owner) {
- super(owner);
- status = NEED_UNWRAP;
- }
-
- /**
- * Start session negotiation
- */
- @Override
- public void start() {
- if (session == null) { // initial handshake
- status = NEED_UNWRAP;
- return; // wait client hello
- }
- if (clientHello != null && this.status != FINISHED) {
- // current negotiation has not completed
- return; // ignore
- }
-
- // renegotiation
- sendHelloRequest();
- status = NEED_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 1: // CLIENT_HELLO
- 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 11: // CLIENT CERTIFICATE
- 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 15: // CERTIFICATE_VERIFY
- if (isResuming
- || clientKeyExchange == null
- || clientCert == null
- || clientKeyExchange.isEmpty() //client certificate
- // contains fixed DH
- // 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 16: // CLIENT_KEY_EXCHANGE
- 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 20: // FINISHED
- 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;
- }
- }
- }
- /**
- * Processes SSLv2 Hello message
- * @ see TLS 1.0 spec., E.1. Version 2 client hello
- * @param bytes
- */
- @Override
- public void unwrapSSLv2(byte[] bytes) {
- io_stream.append(bytes);
- io_stream.mark();
- try {
- clientHello = new ClientHello(io_stream);
- } catch (IOException e) {
- io_stream.reset();
- return;
- }
- if (nonBlocking) {
- delegatedTasks.add(new DelegatedTask(new Runnable() {
- public void run() {
- processClientHello();
- }
- }, this));
- return;
- }
- processClientHello();
- }
-
- /**
- *
- * Processes Client Hello message.
- * Server responds to client hello message with server hello
- * and (if necessary) server certificate, server key exchange,
- * certificate request, and server hello done messages.
- */
- void processClientHello() {
- CipherSuite cipher_suite;
-
- // check that clientHello contains CompressionMethod.null
- checkCompression: {
- for (int i = 0; i < clientHello.compression_methods.length; i++) {
- if (clientHello.compression_methods[i] == 0) {
- break checkCompression;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "HANDSHAKE FAILURE. Incorrect client hello message");
- }
-
- byte[] server_version = clientHello.client_version;
- if (!ProtocolVersion.isSupported(clientHello.client_version)) {
- if (clientHello.client_version[0] >= 3) {
- // Protocol from the future, admit that the newest thing we know is TLSv1
- server_version = ProtocolVersion.TLSv1.version;
- } else {
- fatalAlert(AlertProtocol.PROTOCOL_VERSION,
- "PROTOCOL VERSION. Unsupported client version "
- + clientHello.client_version[0]
- + clientHello.client_version[1]);
- }
- }
-
- isResuming = false;
- FIND: if (clientHello.session_id.length != 0) {
- // client wishes to reuse session
-
- SSLSessionImpl sessionToResume;
- boolean reuseCurrent = false;
-
- // reuse current session
- if (session != null
- && Arrays.equals(session.id, clientHello.session_id)) {
- if (session.isValid()) {
- isResuming = true;
- break FIND;
- }
- reuseCurrent = true;
- }
-
- // find session in cash
- sessionToResume = findSessionToResume(clientHello.session_id);
- if (sessionToResume == null || !sessionToResume.isValid()) {
- if (!parameters.getEnableSessionCreation()) {
- if (reuseCurrent) {
- // we can continue current session
- sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
- status = NOT_HANDSHAKING;
- clearMessages();
- return;
- }
- // throw AlertException
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created");
- }
- session = null;
- } else {
- session = (SSLSessionImpl)sessionToResume.clone();
- isResuming = true;
- }
- }
-
- if (isResuming) {
- cipher_suite = session.cipherSuite;
- // clientHello.cipher_suites must include at least cipher_suite from the session
- checkCipherSuite: {
- for (int i = 0; i < clientHello.cipher_suites.length; i++) {
- if (cipher_suite.equals(clientHello.cipher_suites[i])) {
- break checkCipherSuite;
- }
- }
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "HANDSHAKE FAILURE. Incorrect client hello message");
- }
- } else {
- cipher_suite = selectSuite(clientHello.cipher_suites);
- if (cipher_suite == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "HANDSHAKE FAILURE. NO COMMON SUITE");
- }
- if (!parameters.getEnableSessionCreation()) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE,
- "SSL Session may not be created");
- }
- session = new SSLSessionImpl(cipher_suite, parameters.getSecureRandom());
- if (engineOwner != null) {
- session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
- } else {
- session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
- }
- }
-
- recordProtocol.setVersion(server_version);
- session.protocol = ProtocolVersion.getByVersion(server_version);
- session.clientRandom = clientHello.random;
-
- // create server hello message
- serverHello = new ServerHello(parameters.getSecureRandom(),
- server_version,
- session.getId(), cipher_suite, (byte) 0); //CompressionMethod.null
- session.serverRandom = serverHello.random;
- send(serverHello);
- if (isResuming) {
- sendChangeCipherSpec();
- return;
- }
-
- // create and send server certificate message if needed
- if (!cipher_suite.isAnonymous()) { // need to send server certificate
- X509Certificate[] certs = null;
- String certType = cipher_suite.getServerKeyType();
- if (certType == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "NO CERT TYPE FOR " + cipher_suite.getName());
- }
- // obtain certificates from key manager
- String alias = null;
- X509KeyManager km = parameters.getKeyManager();
- if (km instanceof X509ExtendedKeyManager) {
- X509ExtendedKeyManager ekm = (X509ExtendedKeyManager)km;
- if (this.socketOwner != null) {
- alias = ekm.chooseServerAlias(certType, null,
- this.socketOwner);
- } else {
- alias = ekm.chooseEngineServerAlias(certType, null,
- this.engineOwner);
- }
- if (alias != null) {
- certs = ekm.getCertificateChain(alias);
- }
- } else {
- alias = km.chooseServerAlias(certType, null, this.socketOwner);
- if (alias != null) {
- certs = km.getCertificateChain(alias);
- }
- }
-
- if (certs == null) {
- fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "NO SERVER CERTIFICATE FOUND");
- return;
- }
- session.localCertificates = certs;
- serverCert = new CertificateMessage(certs);
- privKey = km.getPrivateKey(alias);
- send(serverCert);
- }
-
- // create and send server key exchange message if needed
- RSAPublicKey rsakey = null;
- DHPublicKeySpec dhkeySpec = null;
- byte[] hash = null;
- BigInteger p = null;
- BigInteger g = null;
-
- KeyPairGenerator kpg = null;
-
- try {
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- PublicKey pk = serverCert.certs[0].getPublicKey();
- if (getRSAKeyLength(pk) > 512) {
- // key is longer than 512 bits
- kpg = KeyPairGenerator.getInstance("RSA");
- kpg.initialize(512);
- }
- } else if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_DSS_EXPORT
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DHE_RSA_EXPORT
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon
- || cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT) {
- kpg = KeyPairGenerator.getInstance("DH");
- p = new BigInteger(1, DHParameters.getPrime());
- g = new BigInteger("2");
- DHParameterSpec spec = new DHParameterSpec(p, g);
- kpg.initialize(spec);
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- }
-
- if (kpg != null) {
- // need to send server key exchange message
- DigitalSignature ds = new DigitalSignature(cipher_suite.authType);
- KeyPair kp = null;
- try {
- kp = kpg.genKeyPair();
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- rsakey = (RSAPublicKey) kp.getPublic();
- } else {
- DHPublicKey dhkey = (DHPublicKey) kp.getPublic();
- KeyFactory kf = KeyFactory.getInstance("DH");
- dhkeySpec = kf.getKeySpec(dhkey, DHPublicKeySpec.class);
- }
- if (!cipher_suite.isAnonymous()) { // calculate signed_params
-
- // init by private key which correspond to
- // server certificate
- ds.init(privKey);
-
- // use emphemeral key for key exchange
- privKey = kp.getPrivate();
- ds.update(clientHello.getRandom());
- ds.update(serverHello.getRandom());
-
-//FIXME 1_byte==0x00
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- ServerKeyExchange.updateSignatureRsa(ds, rsakey.getModulus(),
- rsakey.getPublicExponent());
- } else {
- ServerKeyExchange.updateSignatureDh(ds, dhkeySpec.getP(), dhkeySpec.getG(),
- dhkeySpec.getY());
- }
- hash = ds.sign();
- } else {
- privKey = kp.getPrivate(); // use emphemeral key for key exchange
- }
- } catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "INTERNAL ERROR", e);
- }
-
- if (cipher_suite.keyExchange == CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- serverKeyExchange = new ServerKeyExchange(rsakey.getModulus(),
- rsakey.getPublicExponent(), null, hash);
- } else {
- serverKeyExchange = new ServerKeyExchange(p,
- g, dhkeySpec.getY(), hash);
- }
- send(serverKeyExchange);
- }
-
- // CERTIFICATE_REQUEST
- certRequest: if (parameters.getWantClientAuth()
- || parameters.getNeedClientAuth()) {
- X509Certificate[] accepted;
- try {
- X509TrustManager tm = parameters.getTrustManager();
- accepted = tm.getAcceptedIssuers();
- } catch (ClassCastException e) {
- // don't send certificateRequest
- break certRequest;
- }
- byte[] requestedClientCertTypes = { CipherSuite.TLS_CT_RSA_SIGN,
- CipherSuite.TLS_CT_DSS_SIGN };
- certificateRequest = new CertificateRequest(
- requestedClientCertTypes, accepted);
- send(certificateRequest);
- }
-
- // SERVER_HELLO_DONE
- serverHelloDone = new ServerHelloDone();
- send(serverHelloDone);
- status = NEED_UNWRAP;
- }
-
- /**
- * Creates and sends finished message
- */
- @Override
- protected void makeFinished() {
- byte[] verify_data;
- boolean isTLS = (serverHello.server_version[1] == 1); // TLS 1.0 protocol
- if (isTLS) {
- verify_data = new byte[12];
- computerVerifyDataTLS("server finished", verify_data);
- } else { // SSL 3.0 protocol (http://wp.netscape.com/eng/ssl3)
- verify_data = new byte[36];
- computerVerifyDataSSLv3(SSLv3Constants.server, verify_data);
- }
- serverFinished = new Finished(verify_data);
- send(serverFinished);
- if (isResuming) {
- if (isTLS) {
- computerReferenceVerifyDataTLS("client finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
- }
- status = NEED_UNWRAP;
- } else {
- session.lastAccessedTime = System.currentTimeMillis();
- status = FINISHED;
- }
- }
-
- // find sesssion in the session hash
- private SSLSessionImpl findSessionToResume(byte[] session_id) {
- return (SSLSessionImpl)parameters.getServerSessionContext().getSession(session_id);
- }
-
- // find appropriate cipher_suite in the client suites
- private CipherSuite selectSuite(CipherSuite[] clientSuites) {
- for (CipherSuite clientSuite : clientSuites) {
- if (!clientSuite.supported) {
- continue;
- }
- for (CipherSuite enabledCipherSuite : parameters.getEnabledCipherSuitesMember()) {
- if (clientSuite.equals(enabledCipherSuite)) {
- return clientSuite;
- }
- }
- }
- return null;
- }
-
- /**
- * Processes inbound ChangeCipherSpec message
- */
- @Override
- public void receiveChangeCipherSpec() {
- if (isResuming) {
- if (serverFinished == null) {
- unexpectedMessage();
- } else {
- changeCipherSpecReceived = true;
- }
- } else {
- if ((parameters.getNeedClientAuth() && clientCert == null)
- || clientKeyExchange == null
- || (clientCert != null && clientCert.certs.length > 0
- && !clientKeyExchange.isEmpty()
- && certificateVerify == null)) {
- unexpectedMessage();
- } else {
- changeCipherSpecReceived = true;
- }
- if (serverHello.server_version[1] == 1) {
- computerReferenceVerifyDataTLS("client finished");
- } else {
- computerReferenceVerifyDataSSLv3(SSLv3Constants.client);
- }
- }
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHello.java b/crypto/src/main/java/org/conscrypt/ServerHello.java
deleted file mode 100644
index 3cc3b46..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHello.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-import libcore.io.Streams;
-
-/**
- *
- * Represents server hello message.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.3.
- * Server hello.</a>
- */
-public class ServerHello extends Message {
-
- /**
- * Server version
- */
- byte[] server_version = new byte[2];
-
- /**
- * Random bytes
- */
- byte[] random = new byte[32];
-
- /**
- * Session id
- */
- byte[] session_id;
-
- /**
- * Selected cipher suite
- */
- CipherSuite cipher_suite;
-
- /**
- * Selected compression method
- */
- byte compression_method;
-
- /**
- * Creates outbound message
- * @param sr
- * @param server_version
- * @param session_id
- * @param cipher_suite
- * @param compression_method
- */
- public ServerHello(SecureRandom sr, byte[] server_version,
- byte[] session_id, CipherSuite cipher_suite, byte compression_method) {
- long gmt_unix_time = new java.util.Date().getTime() / 1000;
- sr.nextBytes(random);
- random[0] = (byte) ((gmt_unix_time & 0xFF000000) >>> 24);
- random[1] = (byte) ((gmt_unix_time & 0xFF0000) >>> 16);
- random[2] = (byte) ((gmt_unix_time & 0xFF00) >>> 8);
- random[3] = (byte) (gmt_unix_time & 0xFF);
- this.session_id = session_id;
- this.cipher_suite = cipher_suite;
- this.compression_method = compression_method;
- this.server_version = server_version;
- length = 38 + session_id.length;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ServerHello(HandshakeIODataStream in, int length) throws IOException {
-
- server_version[0] = (byte) in.read();
- server_version[1] = (byte) in.read();
- Streams.readFully(in, random);
- int size = in.readUint8();
- session_id = new byte[size];
- in.read(session_id, 0, size);
- byte b0 = (byte) in.read();
- byte b1 = (byte) in.read();
- cipher_suite = CipherSuite.getByCode(b0, b1);
- compression_method = (byte) in.read();
- this.length = 38 + session_id.length;
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ServerHello");
- }
-
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.write(server_version);
- out.write(random);
- out.writeUint8(session_id.length);
- out.write(session_id);
- out.write(cipher_suite.toBytes());
- out.write(compression_method);
- length = 38 + session_id.length;
- }
-
- /**
- * Returns server random
- * @return
- */
- public byte[] getRandom() {
- return random;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_HELLO;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerHelloDone.java b/crypto/src/main/java/org/conscrypt/ServerHelloDone.java
deleted file mode 100644
index 3e40f9a..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerHelloDone.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-
-/**
- *
- * Represents server hello done message
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.5.
- * Server hello done</a>
- *
- */
-public class ServerHelloDone extends Message {
-
- /**
- * Creates outbound message
- *
- */
- public ServerHelloDone() {
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @throws IOException
- */
- public ServerHelloDone(HandshakeIODataStream in, int length)
- throws IOException {
- if (length != 0) {
- fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ServerHelloDone");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- }
-
- /**
- * Returns message length
- * @return
- */
- @Override
- public int length() {
- return 0;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_HELLO_DONE;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java b/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java
deleted file mode 100644
index d949850..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerKeyExchange.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.RSAPublicKeySpec;
-
-/**
- *
- * Represents server key exchange message.
- * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.3.
- * Server key exchange message.</a>
- *
- */
-public class ServerKeyExchange extends Message {
-
- // ServerRSAParams ServerDHParams
- final BigInteger par1; // rsa_modulus dh_p
- final byte[] bytes1;
-
- final BigInteger par2; // rsa_exponent dh_g
- final byte[] bytes2;
-
- final BigInteger par3; // dh_Ys
- final byte[] bytes3;
-
- /**
- * Signature
- */
- final byte[] hash;
-
- private RSAPublicKey key;
-
- /**
- * Creates outbound message
- * @param par1 rsa_modulus or dh_p
- * @param par2 rsa_exponent or dh_g
- * @param par3 dh_Ys for ServerDHParams; should be null for ServerRSAParams
- * @param hash should be null for anonymous SignatureAlgorithm
- */
- public ServerKeyExchange(BigInteger par1, BigInteger par2, BigInteger par3,
- byte[] hash) {
- this.par1 = par1;
- this.par2 = par2;
- this.par3 = par3;
- this.hash = hash;
-
- bytes1 = toUnsignedByteArray(this.par1);
-
- bytes2 = toUnsignedByteArray(this.par2);
-
- length = 4 + bytes1.length + bytes2.length;
- if (hash != null) {
- length += 2 + hash.length;
- }
- if (par3 == null) {
- bytes3 = null;
- return;
- }
- bytes3 = toUnsignedByteArray(this.par3);
- length += 2 + bytes3.length;
- }
-
- /**
- * Remove first byte if 0. Needed because BigInteger.toByteArray() sometimes
- * returns a zero prefix.
- */
- public static byte[] toUnsignedByteArray(BigInteger bi) {
- if (bi == null) {
- return null;
- }
- byte[] bb = bi.toByteArray();
- // bb is not null, and has at least 1 byte - ZERO is represented as [0]
- if (bb[0] == 0) {
- byte[] noZero = new byte[bb.length - 1];
- System.arraycopy(bb, 1, noZero, 0, noZero.length);
- return noZero;
- } else {
- return bb;
- }
- }
-
- public static void updateSignatureRsa(DigitalSignature ds, BigInteger modulus,
- BigInteger publicExponent) {
- byte[] tmp;
- byte[] tmpLength = new byte[2];
- tmp = ServerKeyExchange.toUnsignedByteArray(modulus);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(publicExponent);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- }
-
- public static void updateSignatureDh(DigitalSignature ds, BigInteger p, BigInteger g,
- BigInteger y) {
- byte[] tmp;
- byte[] tmpLength = new byte[2];
- tmp = ServerKeyExchange.toUnsignedByteArray(p);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(g);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- tmp = ServerKeyExchange.toUnsignedByteArray(y);
- tmpLength[0] = (byte) ((tmp.length & 0xFF00) >>> 8);
- tmpLength[1] = (byte) (tmp.length & 0xFF);
- ds.update(tmpLength);
- ds.update(tmp);
- }
-
- public boolean verifySignature(DigitalSignature ds) {
- if (par3 != null) {
- updateSignatureDh(ds, par1, par2, par3);
- } else {
- updateSignatureRsa(ds, par1, par2);
- }
- return ds.verifySignature(hash);
- }
-
- /**
- * Will return {@code true} if the signature is {@code null} since this is
- * considered anonymous.
- */
- public boolean isAnonymous() {
- return hash == null;
- }
-
- /**
- * Creates inbound message
- * @param in
- * @param length
- * @param keyExchange
- * @throws IOException
- */
- public ServerKeyExchange(HandshakeIODataStream in, int length,
- int keyExchange) throws IOException {
-
- int size = in.readUint16();
- bytes1 = in.read(size);
- par1 = new BigInteger(1, bytes1);
- this.length = 2 + bytes1.length;
- size = in.readUint16();
- bytes2 = in.read(size);
- par2 = new BigInteger(1, bytes2);
- this.length += 2 + bytes2.length;
- if (keyExchange != CipherSuite.KEY_EXCHANGE_RSA_EXPORT) {
- size = in.readUint16();
- bytes3 = in.read(size);
- par3 = new BigInteger(1, bytes3);
- this.length += 2 + bytes3.length;
- } else {
- par3 = null;
- bytes3 = null;
- }
- if (keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon_EXPORT
- && keyExchange != CipherSuite.KEY_EXCHANGE_DH_anon) {
- size = in.readUint16();
- hash = in.read(size);
- this.length += 2 + hash.length;
- } else {
- hash = null;
- }
- if (this.length != length) {
- fatalAlert(AlertProtocol.DECODE_ERROR,
- "DECODE ERROR: incorrect ServerKeyExchange");
- }
- }
-
- /**
- * Sends message
- * @param out
- */
- @Override
- public void send(HandshakeIODataStream out) {
- out.writeUint16(bytes1.length);
- out.write(bytes1);
- out.writeUint16(bytes2.length);
- out.write(bytes2);
- if (bytes3 != null) {
- out.writeUint16(bytes3.length);
- out.write(bytes3);
- }
- if (hash != null) {
- out.writeUint16(hash.length);
- out.write(hash);
- }
- }
-
- /**
- * Returns RSAPublicKey generated using ServerRSAParams
- * (rsa_modulus and rsa_exponent).
- *
- * @return
- */
- public RSAPublicKey getRSAPublicKey() {
- if (key != null) {
- return key;
- }
- try {
- KeyFactory kf = KeyFactory.getInstance("RSA");
- key = (RSAPublicKey) kf.generatePublic(new RSAPublicKeySpec(par1,
- par2));
- } catch (Exception e) {
- return null;
- }
- return key;
- }
-
- /**
- * Returns message type
- * @return
- */
- @Override
- public int getType() {
- return Handshake.SERVER_KEY_EXCHANGE;
- }
-
-}
diff --git a/crypto/src/main/java/org/conscrypt/ServerSessionContext.java b/crypto/src/main/java/org/conscrypt/ServerSessionContext.java
deleted file mode 100644
index 8bd8b0f..0000000
--- a/crypto/src/main/java/org/conscrypt/ServerSessionContext.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * Caches server sessions. Indexes by session ID. Users typically look up
- * sessions using the ID provided by an SSL client.
- */
-public class ServerSessionContext extends AbstractSessionContext {
-
- private SSLServerSessionCache persistentCache;
-
- public ServerSessionContext() {
- super(100, 0);
-
- // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
- // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);
-
- // TODO remove SSL_CTX session cache limit so we can manage it
- // SSL_CTX_sess_set_cache_size(sslCtxNativePointer, 0);
-
- // TODO override trimToSize and removeEldestEntry to use
- // SSL_CTX_sessions to remove from native cache
-
- // Set a trivial session id context. OpenSSL uses this to make
- // sure you don't reuse sessions externalized with i2d_SSL_SESSION
- // between apps. However our sessions are either in memory or
- // exported to a app's SSLServerSessionCache.
- NativeCrypto.SSL_CTX_set_session_id_context(sslCtxNativePointer, new byte[] { ' ' });
- }
-
- public void setPersistentCache(SSLServerSessionCache persistentCache) {
- this.persistentCache = persistentCache;
- }
-
- protected void sessionRemoved(SSLSession session) {}
-
- @Override
- public SSLSession getSession(byte[] sessionId) {
- SSLSession session = super.getSession(sessionId);
- if (session != null) {
- return session;
- }
-
- // Check persistent cache.
- if (persistentCache != null) {
- byte[] data = persistentCache.getSessionData(sessionId);
- if (data != null) {
- session = toSession(data, null, -1);
- if (session != null && session.isValid()) {
- super.putSession(session);
- return session;
- }
- }
- }
-
- return null;
- }
-
- @Override
- void putSession(SSLSession session) {
- super.putSession(session);
-
- // TODO: In background thread.
- if (persistentCache != null) {
- byte[] data = toBytes(session);
- if (data != null) {
- persistentCache.putSessionData(session, data);
- }
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java b/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java
deleted file mode 100644
index 150d018..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustManagerFactoryImpl.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import javax.net.ssl.ManagerFactoryParameters;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactorySpi;
-
-/**
- *
- * TrustManagerFactory service provider interface implementation.
- *
- * @see javax.net.ssl.TrustManagerFactorySpi
- */
-public class TrustManagerFactoryImpl extends TrustManagerFactorySpi {
-
- private KeyStore keyStore;
-
- /**
- * @see javax.net.ssl.TrustManagerFactorySpi#engineInit(KeyStore)
- */
- @Override
- public void engineInit(KeyStore ks) throws KeyStoreException {
- if (ks != null) {
- keyStore = ks;
- } else {
- keyStore = KeyStore.getInstance("AndroidCAStore");
- try {
- keyStore.load(null, null);
- } catch (IOException e) {
- throw new KeyStoreException(e);
- } catch (CertificateException e) {
- throw new KeyStoreException(e);
- } catch (NoSuchAlgorithmException e) {
- throw new KeyStoreException(e);
- }
- }
- }
-
- /**
- * @see javax.net.ssl#engineInit(ManagerFactoryParameters)
- */
- @Override
- public void engineInit(ManagerFactoryParameters spec)
- throws InvalidAlgorithmParameterException {
- throw new InvalidAlgorithmParameterException(
- "ManagerFactoryParameters not supported");
- }
-
- /**
- * @see javax.net.ssl#engineGetTrustManagers()
- */
- @Override
- public TrustManager[] engineGetTrustManagers() {
- if (keyStore == null) {
- throw new IllegalStateException(
- "TrustManagerFactory is not initialized");
- }
- return new TrustManager[] { new TrustManagerImpl(keyStore) };
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java b/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java
deleted file mode 100644
index ef366d2..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustManagerImpl.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.cert.CertPath;
-import java.security.cert.CertPathValidator;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateParsingException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.PKIXParameters;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.net.ssl.X509TrustManager;
-import libcore.io.EventLogger;
-
-/**
- *
- * TrustManager implementation. The implementation is based on CertPathValidator
- * PKIX and CertificateFactory X509 implementations. This implementations should
- * be provided by some certification provider.
- *
- * @see javax.net.ssl.X509TrustManager
- */
-public final class TrustManagerImpl implements X509TrustManager {
-
- /**
- * The AndroidCAStore if non-null, null otherwise.
- */
- private final KeyStore rootKeyStore;
-
- /**
- * The CertPinManager, which validates the chain against a host-to-pin mapping
- */
- private CertPinManager pinManager;
-
- /**
- * The backing store for the AndroidCAStore if non-null. This will
- * be null when the rootKeyStore is null, implying we are not
- * using the AndroidCAStore.
- */
- private final TrustedCertificateStore trustedCertificateStore;
-
- private final CertPathValidator validator;
-
- /**
- * An index of TrustAnchor instances that we've seen. Unlike the
- * TrustedCertificateStore, this may contain intermediate CAs.
- */
- private final TrustedCertificateIndex trustedCertificateIndex;
-
- /**
- * This is lazily initialized in the AndroidCAStore case since it
- * forces us to bring all the CAs into memory. In the
- * non-AndroidCAStore, we initialize this as part of the
- * constructor.
- */
- private final X509Certificate[] acceptedIssuers;
-
- private final Exception err;
- private final CertificateFactory factory;
-
- /**
- * Creates X509TrustManager based on a keystore
- *
- * @param ks
- */
- public TrustManagerImpl(KeyStore keyStore) {
- this(keyStore, null);
- }
-
- /**
- * For testing only
- */
- public TrustManagerImpl(KeyStore keyStore, CertPinManager manager) {
- CertPathValidator validatorLocal = null;
- CertificateFactory factoryLocal = null;
- KeyStore rootKeyStoreLocal = null;
- TrustedCertificateStore trustedCertificateStoreLocal = null;
- TrustedCertificateIndex trustedCertificateIndexLocal = null;
- X509Certificate[] acceptedIssuersLocal = null;
- Exception errLocal = null;
- try {
- validatorLocal = CertPathValidator.getInstance("PKIX");
- factoryLocal = CertificateFactory.getInstance("X509");
-
- // if we have an AndroidCAStore, we will lazily load CAs
- if ("AndroidCAStore".equals(keyStore.getType())) {
- rootKeyStoreLocal = keyStore;
- trustedCertificateStoreLocal = new TrustedCertificateStore();
- acceptedIssuersLocal = null;
- trustedCertificateIndexLocal = new TrustedCertificateIndex();
- } else {
- rootKeyStoreLocal = null;
- trustedCertificateStoreLocal = null;
- acceptedIssuersLocal = acceptedIssuers(keyStore);
- trustedCertificateIndexLocal
- = new TrustedCertificateIndex(trustAnchors(acceptedIssuersLocal));
- }
-
- } catch (Exception e) {
- errLocal = e;
- }
-
- if (manager != null) {
- this.pinManager = manager;
- } else {
- try {
- pinManager = new CertPinManager(trustedCertificateStoreLocal);
- } catch (PinManagerException e) {
- throw new SecurityException("Could not initialize CertPinManager", e);
- }
- }
-
- this.rootKeyStore = rootKeyStoreLocal;
- this.trustedCertificateStore = trustedCertificateStoreLocal;
- this.validator = validatorLocal;
- this.factory = factoryLocal;
- this.trustedCertificateIndex = trustedCertificateIndexLocal;
- this.acceptedIssuers = acceptedIssuersLocal;
- this.err = errLocal;
- }
-
- private static X509Certificate[] acceptedIssuers(KeyStore ks) {
- try {
- // Note that unlike the PKIXParameters code to create a Set of
- // TrustAnchors from a KeyStore, this version takes from both
- // TrustedCertificateEntry and PrivateKeyEntry, not just
- // TrustedCertificateEntry, which is why TrustManagerImpl
- // cannot just use an PKIXParameters(KeyStore)
- // constructor.
-
- // TODO remove duplicates if same cert is found in both a
- // PrivateKeyEntry and TrustedCertificateEntry
- List<X509Certificate> trusted = new ArrayList<X509Certificate>();
- for (Enumeration<String> en = ks.aliases(); en.hasMoreElements();) {
- final String alias = en.nextElement();
- final X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
- if (cert != null) {
- trusted.add(cert);
- }
- }
- return trusted.toArray(new X509Certificate[trusted.size()]);
- } catch (KeyStoreException e) {
- return new X509Certificate[0];
- }
- }
-
- private static Set<TrustAnchor> trustAnchors(X509Certificate[] certs) {
- Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>(certs.length);
- for (X509Certificate cert : certs) {
- trustAnchors.add(new TrustAnchor(cert, null));
- }
- return trustAnchors;
- }
-
- @Override public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- checkTrusted(chain, authType, null, true);
- }
-
- @Override public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- checkTrusted(chain, authType, null, false);
- }
-
- /**
- * Validates whether a server is trusted. If hostname is given and non-null it also checks if
- * chain is pinned appropriately for that host. If null, it does not check for pinned certs.
- * The return value is a list of the certificates used for making the trust decision.
- */
- public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType,
- String host) throws CertificateException {
- return checkTrusted(chain, authType, host, false);
- }
-
- public void handleTrustStorageUpdate() {
- if (acceptedIssuers == null) {
- trustedCertificateIndex.reset();
- } else {
- trustedCertificateIndex.reset(trustAnchors(acceptedIssuers));
- }
- }
-
- 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
- Set<TrustAnchor> trustAnchor = new HashSet<TrustAnchor>(); // there can only be one!
- 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);
- // the cachedTrust can be null if there isn't anything in the index or if a user has
- // 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);
- // Add intermediate CAs to the index to tolerate sites
- // that assume that the browser will have cached these.
- // The server certificate is skipped by skipping the
- // zeroth element of new chain and note that the root CA
- // will have been removed in
- // 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;
- }
-
- /**
- * Clean up the certificate chain, returning a cleaned up chain,
- * which may be a new array instance if elements were removed.
- * Theoretically, we shouldn't have to do this, but various web
- * servers in practice are mis-configured to have out-of-order
- * certificates, expired self-issued root certificate, or CAs with
- * unsupported signature algorithms such as
- * md2WithRSAEncryption. This also handles removing old certs
- * after bridge CA certs.
- */
- private X509Certificate[] cleanupCertChainAndFindTrustAnchors(X509Certificate[] chain,
- Set<TrustAnchor> trustAnchors) {
- X509Certificate[] original = chain;
-
- // 1. Clean the received certificates chain.
- int currIndex;
- // Start with the first certificate in the chain, assuming it
- // is the leaf certificate (server or client cert).
- for (currIndex = 0; currIndex < chain.length; currIndex++) {
- // Walk the chain to find a "subject" matching
- // the "issuer" of the current certificate. In a properly
- // ordered chain this should be the next cert and be fast.
- // If not, we reorder things to be as the validator will
- // expect.
- boolean foundNext = false;
- for (int nextIndex = currIndex + 1; nextIndex < chain.length; nextIndex++) {
- if (chain[currIndex].getIssuerDN().equals(chain[nextIndex].getSubjectDN())) {
- foundNext = true;
- // Exchange certificates so that 0 through currIndex + 1 are in proper order
- if (nextIndex != currIndex + 1) {
- // don't mutuate original chain, which may be directly from an SSLSession
- if (chain == original) {
- chain = original.clone();
- }
- X509Certificate tempCertificate = chain[nextIndex];
- chain[nextIndex] = chain[currIndex + 1];
- chain[currIndex + 1] = tempCertificate;
- }
- break;
- }
- }
- // If we can't find the next in the chain, just give up
- // and use what we found so far. This drops unrelated
- // certificates that have nothing to do with the cert
- // chain.
- if (!foundNext) {
- break;
- }
- }
-
- // 2. Find the trust anchor in the chain, if any
- int anchorIndex;
- for (anchorIndex = 0; anchorIndex <= currIndex; anchorIndex++) {
- // If the current cert is a TrustAnchor, we can ignore the rest of the chain.
- // This avoids including "bridge" CA certs that added for legacy compatibility.
- TrustAnchor trustAnchor = findTrustAnchorBySubjectAndPublicKey(chain[anchorIndex]);
- if (trustAnchor != null) {
- trustAnchors.add(trustAnchor);
- break;
- }
- }
-
- // 3. If the chain is now shorter, copy to an appropriately sized array.
- int chainLength = anchorIndex;
- X509Certificate[] newChain = ((chainLength == chain.length)
- ? chain
- : Arrays.copyOf(chain, chainLength));
-
- // 4. If we didn't find a trust anchor earlier, look for one now
- if (trustAnchors.isEmpty()) {
- TrustAnchor trustAnchor = findTrustAnchorByIssuerAndSignature(newChain[anchorIndex-1]);
- if (trustAnchor != null) {
- trustAnchors.add(trustAnchor);
- }
- }
- return newChain;
- }
-
- /**
- * If an EKU extension is present in the end-entity certificate,
- * it MUST contain an appropriate key usage. For servers, this
- * includes anyExtendedKeyUsage, serverAuth, or the historical
- * Server Gated Cryptography options of nsSGC or msSGC. For
- * clients, this includes anyExtendedKeyUsage and clientAuth.
- */
- private static class ExtendedKeyUsagePKIXCertPathChecker extends PKIXCertPathChecker {
-
- private static final String EKU_OID = "2.5.29.37";
-
- private static final String EKU_anyExtendedKeyUsage = "2.5.29.37.0";
- private static final String EKU_clientAuth = "1.3.6.1.5.5.7.3.2";
- private static final String EKU_serverAuth = "1.3.6.1.5.5.7.3.1";
- private static final String EKU_nsSGC = "2.16.840.1.113730.4.1";
- private static final String EKU_msSGC = "1.3.6.1.4.1.311.10.3.3";
-
- private static final Set<String> SUPPORTED_EXTENSIONS
- = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(EKU_OID)));
-
- private final boolean clientAuth;
- private final X509Certificate leaf;
-
- private ExtendedKeyUsagePKIXCertPathChecker(boolean clientAuth, X509Certificate leaf) {
- this.clientAuth = clientAuth;
- this.leaf = leaf;
- }
-
- @Override public void init(boolean forward) throws CertPathValidatorException {
- }
-
- @Override public boolean isForwardCheckingSupported() {
- return true;
- }
-
- @Override public Set<String> getSupportedExtensions() {
- return SUPPORTED_EXTENSIONS;
- }
-
- @Override public void check(Certificate c, Collection<String> unresolvedCritExts)
- throws CertPathValidatorException {
- // We only want to validate the EKU on the leaf certificate.
- if (c != leaf) {
- return;
- }
- List<String> ekuOids;
- try {
- ekuOids = leaf.getExtendedKeyUsage();
- } catch (CertificateParsingException e) {
- // A malformed EKU is bad news, consider it fatal.
- throw new CertPathValidatorException(e);
- }
- // We are here to check EKU, but there is none.
- if (ekuOids == null) {
- return;
- }
-
- boolean goodExtendedKeyUsage = false;
- for (String ekuOid : ekuOids) {
- // anyExtendedKeyUsage for clients and servers
- if (ekuOid.equals(EKU_anyExtendedKeyUsage)) {
- goodExtendedKeyUsage = true;
- break;
- }
-
- // clients
- if (clientAuth) {
- if (ekuOid.equals(EKU_clientAuth)) {
- goodExtendedKeyUsage = true;
- break;
- }
- continue;
- }
-
- // servers
- if (ekuOid.equals(EKU_serverAuth)) {
- goodExtendedKeyUsage = true;
- break;
- }
- if (ekuOid.equals(EKU_nsSGC)) {
- goodExtendedKeyUsage = true;
- break;
- }
- if (ekuOid.equals(EKU_msSGC)) {
- goodExtendedKeyUsage = true;
- break;
- }
- }
- if (goodExtendedKeyUsage) {
- // Mark extendedKeyUsage as resolved if present.
- unresolvedCritExts.remove(EKU_OID);
- } else {
- throw new CertPathValidatorException("End-entity certificate does not have a valid "
- + "extendedKeyUsage.");
- }
- }
- }
-
- private TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate lastCert) {
- TrustAnchor trustAnchor = trustedCertificateIndex.findByIssuerAndSignature(lastCert);
- if (trustAnchor != null) {
- return trustAnchor;
- }
- if (trustedCertificateStore == null) {
- return null;
- }
- // we have a KeyStore and the issuer of the last cert in
- // the chain seems to be missing from the
- // TrustedCertificateIndex, check the KeyStore for a hit
- X509Certificate issuer = trustedCertificateStore.findIssuer(lastCert);
- if (issuer != null) {
- return trustedCertificateIndex.index(issuer);
- }
- return null;
- }
-
- /**
- * Check the trustedCertificateIndex for the cert to see if it is
- * already trusted and failing that check the KeyStore if it is
- * available.
- */
- private TrustAnchor findTrustAnchorBySubjectAndPublicKey(X509Certificate cert) {
- TrustAnchor trustAnchor = trustedCertificateIndex.findBySubjectAndPublicKey(cert);
- if (trustAnchor != null) {
- return trustAnchor;
- }
- if (trustedCertificateStore == null) {
- // not trusted and no TrustedCertificateStore to check
- return null;
- }
- // probe KeyStore for a cert. AndroidCAStore stores its
- // contents hashed by cert subject on the filesystem to make
- // this faster than scanning all key store entries.
- if (trustedCertificateStore.isTrustAnchor(cert)) {
- // add new TrustAnchor to params index to avoid
- // checking filesystem next time around.
- return trustedCertificateIndex.index(cert);
- }
- return null;
- }
-
- @Override public X509Certificate[] getAcceptedIssuers() {
- return (acceptedIssuers != null) ? acceptedIssuers.clone() : acceptedIssuers(rootKeyStore);
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java
deleted file mode 100644
index b322cd1..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateIndex.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.PublicKey;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-
-/**
- * Indexes {@code TrustAnchor} instances so they can be found in O(1)
- * time instead of O(N).
- */
-public final class TrustedCertificateIndex {
-
- private final Map<X500Principal, List<TrustAnchor>> subjectToTrustAnchors
- = new HashMap<X500Principal, List<TrustAnchor>>();
-
- public TrustedCertificateIndex() {}
-
- public TrustedCertificateIndex(Set<TrustAnchor> anchors) {
- index(anchors);
- }
-
- private void index(Set<TrustAnchor> anchors) {
- for (TrustAnchor anchor : anchors) {
- index(anchor);
- }
- }
-
- public TrustAnchor index(X509Certificate cert) {
- TrustAnchor anchor = new TrustAnchor(cert, null);
- index(anchor);
- return anchor;
- }
-
- public void index(TrustAnchor anchor) {
- X500Principal subject;
- X509Certificate cert = anchor.getTrustedCert();
- if (cert != null) {
- subject = cert.getSubjectX500Principal();
- } else {
- subject = anchor.getCA();
- }
-
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
- if (anchors == null) {
- anchors = new ArrayList<TrustAnchor>(1);
- subjectToTrustAnchors.put(subject, anchors);
- }
- anchors.add(anchor);
- }
- }
-
- public void reset() {
- synchronized (subjectToTrustAnchors) {
- subjectToTrustAnchors.clear();
- }
- }
-
- public void reset(Set<TrustAnchor> anchors) {
- synchronized (subjectToTrustAnchors) {
- reset();
- index(anchors);
- }
- }
-
- public TrustAnchor findByIssuerAndSignature(X509Certificate cert) {
- X500Principal issuer = cert.getIssuerX500Principal();
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(issuer);
- if (anchors == null) {
- return null;
- }
-
- for (TrustAnchor anchor : anchors) {
- PublicKey publicKey;
- try {
- X509Certificate caCert = anchor.getTrustedCert();
- if (caCert != null) {
- publicKey = caCert.getPublicKey();
- } else {
- publicKey = anchor.getCAPublicKey();
- }
- cert.verify(publicKey);
- return anchor;
- } catch (Exception ignored) {
- }
- }
- }
- return null;
- }
-
- public TrustAnchor findBySubjectAndPublicKey(X509Certificate cert) {
- X500Principal subject = cert.getSubjectX500Principal();
- synchronized (subjectToTrustAnchors) {
- List<TrustAnchor> anchors = subjectToTrustAnchors.get(subject);
- if (anchors == null) {
- return null;
- }
- return findBySubjectAndPublicKey(cert, anchors);
- }
- }
-
- private static TrustAnchor findBySubjectAndPublicKey(X509Certificate cert,
- Collection<TrustAnchor> anchors) {
- PublicKey certPublicKey = cert.getPublicKey();
- for (TrustAnchor anchor : anchors) {
- PublicKey caPublicKey;
- try {
- X509Certificate caCert = anchor.getTrustedCert();
- if (caCert != null) {
- caPublicKey = caCert.getPublicKey();
- } else {
- caPublicKey = anchor.getCAPublicKey();
- }
- if (caPublicKey.equals(certPublicKey)) {
- return anchor;
- }
- } catch (Exception e) {
- // can happen with unsupported public key types
- }
- }
- return null;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java
deleted file mode 100644
index c2d5c33..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateKeyStoreSpi.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.Key;
-import java.security.KeyStoreSpi;
-import java.security.cert.Certificate;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-
-/**
- * A KeyStoreSpi wrapper for the TrustedCertificateStore.
- */
-public final class TrustedCertificateKeyStoreSpi extends KeyStoreSpi {
-
- private final TrustedCertificateStore store = new TrustedCertificateStore();
-
- @Override public Key engineGetKey(String alias, char[] password) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return null;
- }
-
- @Override public Certificate[] engineGetCertificateChain(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return null;
- }
-
- @Override public Certificate engineGetCertificate(String alias) {
- return store.getCertificate(alias);
- }
-
- @Override public Date engineGetCreationDate(String alias) {
- return store.getCreationDate(alias);
- }
-
- @Override public void engineSetKeyEntry(
- String alias, Key key, char[] password, Certificate[] chain) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineSetCertificateEntry(String alias, Certificate cert) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineDeleteEntry(String alias) {
- throw new UnsupportedOperationException();
- }
-
- @Override public Enumeration<String> engineAliases() {
- return Collections.enumeration(store.aliases());
- }
-
- @Override public boolean engineContainsAlias(String alias) {
- return store.containsAlias(alias);
- }
-
- @Override public int engineSize() {
- return store.aliases().size();
- }
-
- @Override public boolean engineIsKeyEntry(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- return false;
- }
-
- @Override public boolean engineIsCertificateEntry(String alias) {
- return engineContainsAlias(alias);
- }
-
- @Override public String engineGetCertificateAlias(Certificate c) {
- return store.getCertificateAlias(c);
- }
-
- @Override public void engineStore(OutputStream stream, char[] password) {
- throw new UnsupportedOperationException();
- }
-
- @Override public void engineLoad(InputStream stream, char[] password) {
- if (stream != null) {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java b/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
deleted file mode 100644
index 1356776..0000000
--- a/crypto/src/main/java/org/conscrypt/TrustedCertificateStore.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import libcore.io.IoUtils;
-
-/**
- * A source for trusted root certificate authority (CA) certificates
- * supporting an immutable system CA directory along with mutable
- * directories allowing the user addition of custom CAs and user
- * removal of system CAs. This store supports the {@code
- * TrustedCertificateKeyStoreSpi} wrapper to allow a traditional
- * KeyStore interface for use with {@link
- * javax.net.ssl.TrustManagerFactory.init}.
- *
- * <p>The CAs are accessed via {@code KeyStore} style aliases. Aliases
- * are made up of a prefix identifying the source ("system:" vs
- * "user:") and a suffix based on the OpenSSL X509_NAME_hash_old
- * function of the CA's subject name. For example, the system CA for
- * "C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification
- * Authority" could be represented as "system:7651b327.0". By using
- * the subject hash, operations such as {@link #getCertificateAlias
- * getCertificateAlias} can be implemented efficiently without
- * scanning the entire store.
- *
- * <p>In addition to supporting the {@code
- * TrustedCertificateKeyStoreSpi} implementation, {@code
- * TrustedCertificateStore} also provides the additional public
- * methods {@link #isTrustAnchor} and {@link #findIssuer} to allow
- * efficient lookup operations for CAs again based on the file naming
- * convention.
- *
- * <p>The KeyChainService users the {@link installCertificate} and
- * {@link #deleteCertificateEntry} to install user CAs as well as
- * delete those user CAs as well as system CAs. The deletion of system
- * CAs is performed by placing an exact copy of that CA in the deleted
- * directory. Such deletions are intended to persist across upgrades
- * but not intended to mask a CA with a matching name or public key
- * but is otherwise reissued in a system update. Reinstalling a
- * deleted system certificate simply removes the copy from the deleted
- * directory, reenabling the original in the system directory.
- *
- * <p>Note that the default mutable directory is created by init via
- * configuration in the system/core/rootdir/init.rc file. The
- * directive "mkdir /data/misc/keychain 0775 system system"
- * ensures that its owner and group are the system uid and system
- * gid and that it is world readable but only writable by the system
- * user.
- */
-public final class TrustedCertificateStore {
-
- private static final String PREFIX_SYSTEM = "system:";
- private static final String PREFIX_USER = "user:";
-
- public static final boolean isSystem(String alias) {
- return alias.startsWith(PREFIX_SYSTEM);
- }
- public static final boolean isUser(String alias) {
- return alias.startsWith(PREFIX_USER);
- }
-
- private static final File CA_CERTS_DIR_SYSTEM;
- private static final File CA_CERTS_DIR_ADDED;
- private static final File CA_CERTS_DIR_DELETED;
- private static final CertificateFactory CERT_FACTORY;
- static {
- String ANDROID_ROOT = System.getenv("ANDROID_ROOT");
- String ANDROID_DATA = System.getenv("ANDROID_DATA");
- CA_CERTS_DIR_SYSTEM = new File(ANDROID_ROOT + "/etc/security/cacerts");
- CA_CERTS_DIR_ADDED = new File(ANDROID_DATA + "/misc/keychain/cacerts-added");
- CA_CERTS_DIR_DELETED = new File(ANDROID_DATA + "/misc/keychain/cacerts-removed");
-
- try {
- CERT_FACTORY = CertificateFactory.getInstance("X509");
- } catch (CertificateException e) {
- throw new AssertionError(e);
- }
- }
-
- private final File systemDir;
- private final File addedDir;
- private final File deletedDir;
-
- public TrustedCertificateStore() {
- this(CA_CERTS_DIR_SYSTEM, CA_CERTS_DIR_ADDED, CA_CERTS_DIR_DELETED);
- }
-
- public TrustedCertificateStore(File systemDir, File addedDir, File deletedDir) {
- this.systemDir = systemDir;
- this.addedDir = addedDir;
- this.deletedDir = deletedDir;
- }
-
- public Certificate getCertificate(String alias) {
- return getCertificate(alias, false);
- }
-
- public Certificate getCertificate(String alias, boolean includeDeletedSystem) {
-
- File file = fileForAlias(alias);
- if (file == null || (isUser(alias) && isTombstone(file))) {
- return null;
- }
- X509Certificate cert = readCertificate(file);
- if (cert == null || (isSystem(alias)
- && !includeDeletedSystem
- && isDeletedSystemCertificate(cert))) {
- // skip malformed certs as well as deleted system ones
- return null;
- }
- return cert;
- }
-
- private File fileForAlias(String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- File file;
- if (isSystem(alias)) {
- file = new File(systemDir, alias.substring(PREFIX_SYSTEM.length()));
- } else if (isUser(alias)) {
- file = new File(addedDir, alias.substring(PREFIX_USER.length()));
- } else {
- return null;
- }
- if (!file.exists() || isTombstone(file)) {
- // silently elide tombstones
- return null;
- }
- return file;
- }
-
- private boolean isTombstone(File file) {
- return file.length() == 0;
- }
-
- private X509Certificate readCertificate(File file) {
- if (!file.isFile()) {
- return null;
- }
- InputStream is = null;
- try {
- is = new BufferedInputStream(new FileInputStream(file));
- return (X509Certificate) CERT_FACTORY.generateCertificate(is);
- } catch (IOException e) {
- return null;
- } catch (CertificateException e) {
- // reading a cert while its being installed can lead to this.
- // just pretend like its not available yet.
- return null;
- } finally {
- IoUtils.closeQuietly(is);
- }
- }
-
- private void writeCertificate(File file, X509Certificate cert)
- throws IOException, CertificateException {
- File dir = file.getParentFile();
- dir.mkdirs();
- dir.setReadable(true, false);
- dir.setExecutable(true, false);
- OutputStream os = null;
- try {
- os = new FileOutputStream(file);
- os.write(cert.getEncoded());
- } finally {
- IoUtils.closeQuietly(os);
- }
- file.setReadable(true, false);
- }
-
- private boolean isDeletedSystemCertificate(X509Certificate x) {
- return getCertificateFile(deletedDir, x).exists();
- }
-
- public Date getCreationDate(String alias) {
- // containsAlias check ensures the later fileForAlias result
- // was not a deleted system cert.
- if (!containsAlias(alias)) {
- return null;
- }
- File file = fileForAlias(alias);
- if (file == null) {
- return null;
- }
- long time = file.lastModified();
- if (time == 0) {
- return null;
- }
- return new Date(time);
- }
-
- public Set<String> aliases() {
- Set<String> result = new HashSet<String>();
- addAliases(result, PREFIX_USER, addedDir);
- addAliases(result, PREFIX_SYSTEM, systemDir);
- return result;
- }
-
- public Set<String> userAliases() {
- Set<String> result = new HashSet<String>();
- addAliases(result, PREFIX_USER, addedDir);
- return result;
- }
-
- private void addAliases(Set<String> result, String prefix, File dir) {
- String[] files = dir.list();
- if (files == null) {
- return;
- }
- for (String filename : files) {
- String alias = prefix + filename;
- if (containsAlias(alias)) {
- result.add(alias);
- }
- }
- }
-
- public Set<String> allSystemAliases() {
- Set<String> result = new HashSet<String>();
- String[] files = systemDir.list();
- if (files == null) {
- return result;
- }
- for (String filename : files) {
- String alias = PREFIX_SYSTEM + filename;
- if (containsAlias(alias, true)) {
- result.add(alias);
- }
- }
- return result;
- }
-
- public boolean containsAlias(String alias) {
- return containsAlias(alias, false);
- }
-
- private boolean containsAlias(String alias, boolean includeDeletedSystem) {
- return getCertificate(alias, includeDeletedSystem) != null;
- }
-
- public String getCertificateAlias(Certificate c) {
- if (c == null || !(c instanceof X509Certificate)) {
- return null;
- }
- X509Certificate x = (X509Certificate) c;
- File user = getCertificateFile(addedDir, x);
- if (user.exists()) {
- return PREFIX_USER + user.getName();
- }
- if (isDeletedSystemCertificate(x)) {
- return null;
- }
- File system = getCertificateFile(systemDir, x);
- if (system.exists()) {
- return PREFIX_SYSTEM + system.getName();
- }
- return null;
- }
-
- /**
- * Returns true to indicate that the certificate was added by the
- * user, false otherwise.
- */
- public boolean isUserAddedCertificate(X509Certificate cert) {
- return getCertificateFile(addedDir, cert).exists();
- }
-
- /**
- * Returns a File for where the certificate is found if it exists
- * or where it should be installed if it does not exist. The
- * caller can disambiguate these cases by calling {@code
- * File.exists()} on the result.
- */
- private File getCertificateFile(File dir, final X509Certificate x) {
- // compare X509Certificate.getEncoded values
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate cert) {
- return cert.equals(x);
- }
- };
- return findCert(dir, x.getSubjectX500Principal(), selector, File.class);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by {@code
- * TrustManagerImpl} to locate a CA certificate with the same name
- * and public key as the provided {@code X509Certificate}. We
- * match on the name and public key and not the entire certificate
- * since a CA may be reissued with the same name and PublicKey but
- * with other differences (for example when switching signature
- * from md2WithRSAEncryption to SHA1withRSA)
- */
- public boolean isTrustAnchor(final X509Certificate c) {
- // compare X509Certificate.getPublicKey values
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate ca) {
- return ca.getPublicKey().equals(c.getPublicKey());
- }
- };
- boolean user = findCert(addedDir,
- c.getSubjectX500Principal(),
- selector,
- Boolean.class);
- if (user) {
- return true;
- }
- X509Certificate system = findCert(systemDir,
- c.getSubjectX500Principal(),
- selector,
- X509Certificate.class);
- return system != null && !isDeletedSystemCertificate(system);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by {@code
- * TrustManagerImpl} to locate the CA certificate that signed the
- * provided {@code X509Certificate}.
- */
- public X509Certificate findIssuer(final X509Certificate c) {
- // match on verified issuer of Certificate
- CertSelector selector = new CertSelector() {
- @Override public boolean match(X509Certificate ca) {
- try {
- c.verify(ca.getPublicKey());
- return true;
- } catch (Exception e) {
- return false;
- }
- }
- };
- X500Principal issuer = c.getIssuerX500Principal();
- X509Certificate user = findCert(addedDir, issuer, selector, X509Certificate.class);
- if (user != null) {
- return user;
- }
- X509Certificate system = findCert(systemDir, issuer, selector, X509Certificate.class);
- if (system != null && !isDeletedSystemCertificate(system)) {
- return system;
- }
- return null;
- }
-
- private static boolean isSelfIssuedCertificate(OpenSSLX509Certificate cert) {
- final long ctx = cert.getContext();
- return NativeCrypto.X509_check_issued(ctx, ctx) == 0;
- }
-
- /**
- * Converts the {@code cert} to the internal OpenSSL X.509 format so we can
- * run {@link NativeCrypto} methods on it.
- */
- private static OpenSSLX509Certificate convertToOpenSSLIfNeeded(X509Certificate cert)
- throws CertificateException {
- if (cert == null) {
- return null;
- }
-
- if (cert instanceof OpenSSLX509Certificate) {
- return (OpenSSLX509Certificate) cert;
- }
-
- try {
- return OpenSSLX509Certificate.fromX509Der(cert.getEncoded());
- } catch (Exception e) {
- throw new CertificateException(e);
- }
- }
-
- /**
- * Attempt to build a certificate chain from the supplied {@code leaf}
- * argument through the chain of issuers as high up as known. If the chain
- * can't be completed, the most complete chain available will be returned.
- * This means that a list with only the {@code leaf} certificate is returned
- * if no issuer certificates could be found.
- *
- * @throws CertificateException if there was a problem parsing the
- * certificates
- */
- public List<X509Certificate> getCertificateChain(X509Certificate leaf)
- throws CertificateException {
- final List<OpenSSLX509Certificate> chain = new ArrayList<OpenSSLX509Certificate>();
- chain.add(convertToOpenSSLIfNeeded(leaf));
-
- for (int i = 0; true; i++) {
- OpenSSLX509Certificate cert = chain.get(i);
- if (isSelfIssuedCertificate(cert)) {
- break;
- }
- OpenSSLX509Certificate issuer = convertToOpenSSLIfNeeded(findIssuer(cert));
- if (issuer == null) {
- break;
- }
- chain.add(issuer);
- }
-
- return new ArrayList<X509Certificate>(chain);
- }
-
- // like java.security.cert.CertSelector but with X509Certificate and without cloning
- private static interface CertSelector {
- public boolean match(X509Certificate cert);
- }
-
- private <T> T findCert(
- File dir, X500Principal subject, CertSelector selector, Class<T> desiredReturnType) {
-
- String hash = hash(subject);
- for (int index = 0; true; index++) {
- File file = file(dir, hash, index);
- if (!file.isFile()) {
- // could not find a match, no file exists, bail
- if (desiredReturnType == Boolean.class) {
- return (T) Boolean.FALSE;
- }
- if (desiredReturnType == File.class) {
- // we return file so that caller that wants to
- // write knows what the next available has
- // location is
- return (T) file;
- }
- return null;
- }
- if (isTombstone(file)) {
- continue;
- }
- X509Certificate cert = readCertificate(file);
- if (cert == null) {
- // skip problem certificates
- continue;
- }
- if (selector.match(cert)) {
- if (desiredReturnType == X509Certificate.class) {
- return (T) cert;
- }
- if (desiredReturnType == Boolean.class) {
- return (T) Boolean.TRUE;
- }
- if (desiredReturnType == File.class) {
- return (T) file;
- }
- throw new AssertionError();
- }
- }
- }
-
- private String hash(X500Principal name) {
- int hash = NativeCrypto.X509_NAME_hash_old(name);
- return IntegralToString.intToHexString(hash, false, 8);
- }
-
- private File file(File dir, String hash, int index) {
- return new File(dir, hash + '.' + index);
- }
-
- /**
- * This non-{@code KeyStoreSpi} public interface is used by the
- * {@code KeyChainService} to install new CA certificates. It
- * silently ignores the certificate if it already exists in the
- * store.
- */
- public void installCertificate(X509Certificate cert) throws IOException, CertificateException {
- if (cert == null) {
- throw new NullPointerException("cert == null");
- }
- File system = getCertificateFile(systemDir, cert);
- if (system.exists()) {
- File deleted = getCertificateFile(deletedDir, cert);
- if (deleted.exists()) {
- // we have a system cert that was marked deleted.
- // remove the deleted marker to expose the original
- if (!deleted.delete()) {
- throw new IOException("Could not remove " + deleted);
- }
- return;
- }
- // otherwise we just have a dup of an existing system cert.
- // return taking no further action.
- return;
- }
- File user = getCertificateFile(addedDir, cert);
- if (user.exists()) {
- // we have an already installed user cert, bail.
- return;
- }
- // install the user cert
- writeCertificate(user, cert);
- }
-
- /**
- * This could be considered the implementation of {@code
- * TrustedCertificateKeyStoreSpi.engineDeleteEntry} but we
- * consider {@code TrustedCertificateKeyStoreSpi} to be read
- * only. Instead, this is used by the {@code KeyChainService} to
- * delete CA certificates.
- */
- public void deleteCertificateEntry(String alias) throws IOException, CertificateException {
- if (alias == null) {
- return;
- }
- File file = fileForAlias(alias);
- if (file == null) {
- return;
- }
- if (isSystem(alias)) {
- X509Certificate cert = readCertificate(file);
- if (cert == null) {
- // skip problem certificates
- return;
- }
- File deleted = getCertificateFile(deletedDir, cert);
- if (deleted.exists()) {
- // already deleted system certificate
- return;
- }
- // write copy of system cert to marked as deleted
- writeCertificate(deleted, cert);
- return;
- }
- if (isUser(alias)) {
- // truncate the file to make a tombstone by opening and closing.
- // we need ensure that we don't leave a gap before a valid cert.
- new FileOutputStream(file).close();
- removeUnnecessaryTombstones(alias);
- return;
- }
- // non-existant user cert, nothing to delete
- }
-
- private void removeUnnecessaryTombstones(String alias) throws IOException {
- if (!isUser(alias)) {
- throw new AssertionError(alias);
- }
- int dotIndex = alias.lastIndexOf('.');
- if (dotIndex == -1) {
- throw new AssertionError(alias);
- }
-
- String hash = alias.substring(PREFIX_USER.length(), dotIndex);
- int lastTombstoneIndex = Integer.parseInt(alias.substring(dotIndex + 1));
-
- if (file(addedDir, hash, lastTombstoneIndex + 1).exists()) {
- return;
- }
- while (lastTombstoneIndex >= 0) {
- File file = file(addedDir, hash, lastTombstoneIndex);
- if (!isTombstone(file)) {
- break;
- }
- if (!file.delete()) {
- throw new IOException("Could not remove " + file);
- }
- lastTombstoneIndex--;
- }
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/X509PublicKey.java b/crypto/src/main/java/org/conscrypt/X509PublicKey.java
deleted file mode 100644
index 8d09fc2..0000000
--- a/crypto/src/main/java/org/conscrypt/X509PublicKey.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.PublicKey;
-import java.util.Arrays;
-
-/**
- * A simple but useless key class that holds X.509 public key information when
- * the appropriate KeyFactory for the key algorithm is not available.
- */
-public class X509PublicKey implements PublicKey {
- private static final long serialVersionUID = -8610156854731664298L;
-
- private final String algorithm;
-
- private final byte[] encoded;
-
- public X509PublicKey(String algorithm, byte[] encoded) {
- this.algorithm = algorithm;
- this.encoded = encoded;
- }
-
- @Override
- public String getAlgorithm() {
- return algorithm;
- }
-
- @Override
- public String getFormat() {
- return "X.509";
- }
-
- @Override
- public byte[] getEncoded() {
- return encoded;
- }
-
- @Override
- public String toString() {
- return "X509PublicKey [algorithm=" + algorithm + ", encoded=" + Arrays.toString(encoded)
- + "]";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((algorithm == null) ? 0 : algorithm.hashCode());
- result = prime * result + Arrays.hashCode(encoded);
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- X509PublicKey other = (X509PublicKey) obj;
- if (algorithm == null) {
- if (other.algorithm != null)
- return false;
- } else if (!algorithm.equals(other.algorithm))
- return false;
- if (!Arrays.equals(encoded, other.encoded))
- return false;
- return true;
- }
-}
diff --git a/crypto/src/main/java/org/conscrypt/util/EmptyArray.java b/crypto/src/main/java/org/conscrypt/util/EmptyArray.java
deleted file mode 100644
index e474562..0000000
--- a/crypto/src/main/java/org/conscrypt/util/EmptyArray.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Copied from libcore.util.EmptyArray
-
-package org.conscrypt.util;
-
-public final class EmptyArray {
- private EmptyArray() {}
-
- public static final boolean[] BOOLEAN = new boolean[0];
- public static final byte[] BYTE = new byte[0];
- public static final char[] CHAR = new char[0];
- public static final double[] DOUBLE = new double[0];
- public static final int[] INT = new int[0];
-
- public static final Class<?>[] CLASS = new Class[0];
- public static final Object[] OBJECT = new Object[0];
- public static final String[] STRING = new String[0];
- public static final Throwable[] THROWABLE = new Throwable[0];
- public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
-} \ No newline at end of file
diff --git a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp b/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
deleted file mode 100644
index cc5abbd..0000000
--- a/crypto/src/main/native/org_conscrypt_NativeCrypto.cpp
+++ /dev/null
@@ -1,8244 +0,0 @@
-/*
- * Copyright (C) 2007-2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Native glue for Java class org.conscrypt.NativeCrypto
- */
-
-#define TO_STRING1(x) #x
-#define TO_STRING(x) TO_STRING1(x)
-#ifndef JNI_JARJAR_PREFIX
-#define CONSCRYPT_UNBUNDLED
-#define JNI_JARJAR_PREFIX
-#endif
-
-#define LOG_TAG "NativeCrypto"
-
-#include <algorithm>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <vector>
-
-#include <jni.h>
-
-#include <openssl/asn1t.h>
-#include <openssl/dsa.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/ssl.h>
-#include <openssl/x509v3.h>
-
-#include "AsynchronousSocketCloseMonitor.h"
-#include "cutils/log.h"
-#include "JNIHelp.h"
-#include "JniConstants.h"
-#include "JniException.h"
-#include "NetFd.h"
-#include "ScopedLocalRef.h"
-#include "ScopedPrimitiveArray.h"
-#include "ScopedUtfChars.h"
-#include "UniquePtr.h"
-
-#undef WITH_JNI_TRACE
-#undef WITH_JNI_TRACE_DATA
-
-/*
- * How to use this for debugging with Wireshark:
- *
- * 1. Pull lines from logcat to a file that looks like (without quotes):
- * "RSA Session-ID:... Master-Key:..." <CR>
- * "RSA Session-ID:... Master-Key:..." <CR>
- * <etc>
- * 2. Start Wireshark
- * 3. Go to Edit -> Preferences -> SSL -> (Pre-)Master-Key log and fill in
- * the file you put the lines in above.
- * 4. Follow the stream that corresponds to the desired "Session-ID" in
- * the Server Hello.
- */
-#undef WITH_JNI_TRACE_KEYS
-
-#ifdef WITH_JNI_TRACE
-#define JNI_TRACE(...) \
- ((void)ALOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__)); \
-/*
- ((void)printf("I/" LOG_TAG "-jni:")); \
- ((void)printf(__VA_ARGS__)); \
- ((void)printf("\n"))
-*/
-#else
-#define JNI_TRACE(...) ((void)0)
-#endif
-// don't overwhelm logcat
-#define WITH_JNI_TRACE_DATA_CHUNK_SIZE 512
-
-static JavaVM* gJavaVM;
-static jclass openSslOutputStreamClass;
-
-static jclass byteArrayClass;
-static jclass calendarClass;
-static jclass objectClass;
-static jclass objectArrayClass;
-static jclass integerClass;
-static jclass inputStreamClass;
-static jclass outputStreamClass;
-static jclass stringClass;
-
-static jmethodID calendar_setMethod;
-static jmethodID inputStream_readMethod;
-static jmethodID integer_valueOfMethod;
-static jmethodID openSslInputStream_readLineMethod;
-static jmethodID outputStream_writeMethod;
-static jmethodID outputStream_flushMethod;
-
-struct OPENSSL_Delete {
- void operator()(void* p) const {
- OPENSSL_free(p);
- }
-};
-typedef UniquePtr<unsigned char, OPENSSL_Delete> Unique_OPENSSL_str;
-
-struct BIO_Delete {
- void operator()(BIO* p) const {
- BIO_free(p);
- }
-};
-typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
-
-struct BIGNUM_Delete {
- void operator()(BIGNUM* p) const {
- BN_free(p);
- }
-};
-typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
-
-struct ASN1_INTEGER_Delete {
- void operator()(ASN1_INTEGER* p) const {
- ASN1_INTEGER_free(p);
- }
-};
-typedef UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> Unique_ASN1_INTEGER;
-
-struct DH_Delete {
- void operator()(DH* p) const {
- DH_free(p);
- }
-};
-typedef UniquePtr<DH, DH_Delete> Unique_DH;
-
-struct DSA_Delete {
- void operator()(DSA* p) const {
- DSA_free(p);
- }
-};
-typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
-
-struct EC_GROUP_Delete {
- void operator()(EC_GROUP* p) const {
- EC_GROUP_clear_free(p);
- }
-};
-typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
-
-struct EC_POINT_Delete {
- void operator()(EC_POINT* p) const {
- EC_POINT_clear_free(p);
- }
-};
-typedef UniquePtr<EC_POINT, EC_POINT_Delete> Unique_EC_POINT;
-
-struct EC_KEY_Delete {
- void operator()(EC_KEY* p) const {
- EC_KEY_free(p);
- }
-};
-typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
-
-struct EVP_MD_CTX_Delete {
- void operator()(EVP_MD_CTX* p) const {
- EVP_MD_CTX_destroy(p);
- }
-};
-typedef UniquePtr<EVP_MD_CTX, EVP_MD_CTX_Delete> Unique_EVP_MD_CTX;
-
-struct EVP_CIPHER_CTX_Delete {
- void operator()(EVP_CIPHER_CTX* p) const {
- EVP_CIPHER_CTX_cleanup(p);
- }
-};
-typedef UniquePtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Delete> Unique_EVP_CIPHER_CTX;
-
-struct EVP_PKEY_Delete {
- void operator()(EVP_PKEY* p) const {
- EVP_PKEY_free(p);
- }
-};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-struct PKCS8_PRIV_KEY_INFO_Delete {
- void operator()(PKCS8_PRIV_KEY_INFO* p) const {
- PKCS8_PRIV_KEY_INFO_free(p);
- }
-};
-typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
-
-struct RSA_Delete {
- void operator()(RSA* p) const {
- RSA_free(p);
- }
-};
-typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
-
-struct ASN1_BIT_STRING_Delete {
- void operator()(ASN1_BIT_STRING* p) const {
- ASN1_BIT_STRING_free(p);
- }
-};
-typedef UniquePtr<ASN1_BIT_STRING, ASN1_BIT_STRING_Delete> Unique_ASN1_BIT_STRING;
-
-struct ASN1_OBJECT_Delete {
- void operator()(ASN1_OBJECT* p) const {
- ASN1_OBJECT_free(p);
- }
-};
-typedef UniquePtr<ASN1_OBJECT, ASN1_OBJECT_Delete> Unique_ASN1_OBJECT;
-
-struct ASN1_GENERALIZEDTIME_Delete {
- void operator()(ASN1_GENERALIZEDTIME* p) const {
- ASN1_GENERALIZEDTIME_free(p);
- }
-};
-typedef UniquePtr<ASN1_GENERALIZEDTIME, ASN1_GENERALIZEDTIME_Delete> Unique_ASN1_GENERALIZEDTIME;
-
-struct SSL_Delete {
- void operator()(SSL* p) const {
- SSL_free(p);
- }
-};
-typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
-
-struct SSL_CTX_Delete {
- void operator()(SSL_CTX* p) const {
- SSL_CTX_free(p);
- }
-};
-typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
-
-struct X509_Delete {
- void operator()(X509* p) const {
- X509_free(p);
- }
-};
-typedef UniquePtr<X509, X509_Delete> Unique_X509;
-
-class X509Chain {
- public:
- X509Chain(size_t n) : x509s_(n) {}
-
- ~X509Chain() {
- for (const auto& x509 : x509s_) {
- X509_free(x509);
- }
- }
-
- X509*& operator[](size_t n) {
- return x509s_[n];
- }
-
- X509* operator[](size_t n) const {
- return x509s_[n];
- }
-
- X509* release(size_t i) {
- X509* x = x509s_[i];
- x509s_[i] = NULL;
- return x;
- }
-
- private:
- std::vector<X509*> x509s_;
-};
-
-struct X509_NAME_Delete {
- void operator()(X509_NAME* p) const {
- X509_NAME_free(p);
- }
-};
-typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
-
-struct PKCS7_Delete {
- void operator()(PKCS7* p) const {
- PKCS7_free(p);
- }
-};
-typedef UniquePtr<PKCS7, PKCS7_Delete> Unique_PKCS7;
-
-struct sk_SSL_CIPHER_Delete {
- void operator()(STACK_OF(SSL_CIPHER)* p) const {
- // We don't own SSL_CIPHER references, so no need for pop_free
- sk_SSL_CIPHER_free(p);
- }
-};
-typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
-
-struct sk_X509_Delete {
- void operator()(STACK_OF(X509)* p) const {
- sk_X509_pop_free(p, X509_free);
- }
-};
-typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
-
-struct sk_X509_NAME_Delete {
- void operator()(STACK_OF(X509_NAME)* p) const {
- sk_X509_NAME_pop_free(p, X509_NAME_free);
- }
-};
-typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
-
-struct sk_ASN1_OBJECT_Delete {
- void operator()(STACK_OF(ASN1_OBJECT)* p) const {
- sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
- }
-};
-typedef UniquePtr<STACK_OF(ASN1_OBJECT), sk_ASN1_OBJECT_Delete> Unique_sk_ASN1_OBJECT;
-
-struct sk_GENERAL_NAME_Delete {
- void operator()(STACK_OF(GENERAL_NAME)* p) const {
- sk_GENERAL_NAME_pop_free(p, GENERAL_NAME_free);
- }
-};
-typedef UniquePtr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_Delete> Unique_sk_GENERAL_NAME;
-
-/**
- * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
- * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
- * without triggering a warning by not using the result of release().
- */
-#define OWNERSHIP_TRANSFERRED(obj) \
- typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
-
-/**
- * Frees the SSL error state.
- *
- * OpenSSL keeps an "error stack" per thread, and given that this code
- * can be called from arbitrary threads that we don't keep track of,
- * we err on the side of freeing the error state promptly (instead of,
- * say, at thread death).
- */
-static void freeOpenSslErrorState(void) {
- ERR_clear_error();
- ERR_remove_state(0);
-}
-
-/**
- * Throws a OutOfMemoryError with the given string as a message.
- */
-static void jniThrowOutOfMemory(JNIEnv* env, const char* message) {
- jniThrowException(env, "java/lang/OutOfMemoryError", message);
-}
-
-/**
- * Throws a BadPaddingException with the given string as a message.
- */
-static void throwBadPaddingException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwBadPaddingException %s", message);
- jniThrowException(env, "javax/crypto/BadPaddingException", message);
-}
-
-/**
- * Throws a SignatureException with the given string as a message.
- */
-static void throwSignatureException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSignatureException %s", message);
- jniThrowException(env, "java/security/SignatureException", message);
-}
-
-/**
- * Throws a InvalidKeyException with the given string as a message.
- */
-static void throwInvalidKeyException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwInvalidKeyException %s", message);
- jniThrowException(env, "java/security/InvalidKeyException", message);
-}
-
-/**
- * Throws a SignatureException with the given string as a message.
- */
-static void throwIllegalBlockSizeException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwIllegalBlockSizeException %s", message);
- jniThrowException(env, "javax/crypto/IllegalBlockSizeException", message);
-}
-
-/**
- * Throws a NoSuchAlgorithmException with the given string as a message.
- */
-static void throwNoSuchAlgorithmException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwUnknownAlgorithmException %s", message);
- jniThrowException(env, "java/security/NoSuchAlgorithmException", message);
-}
-
-static void throwForAsn1Error(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case ASN1_R_UNABLE_TO_DECODE_RSA_KEY:
- case ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY:
- case ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE:
- case ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:
- case ASN1_R_WRONG_PUBLIC_KEY_TYPE:
- throwInvalidKeyException(env, message);
- break;
- case ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForEvpError(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case EVP_R_BAD_DECRYPT:
- throwBadPaddingException(env, message);
- break;
- case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
- case EVP_R_WRONG_FINAL_BLOCK_LENGTH:
- throwIllegalBlockSizeException(env, message);
- break;
- case EVP_R_BAD_KEY_LENGTH:
- case EVP_R_BN_DECODE_ERROR:
- case EVP_R_BN_PUBKEY_ERROR:
- case EVP_R_INVALID_KEY_LENGTH:
- case EVP_R_MISSING_PARAMETERS:
- case EVP_R_UNSUPPORTED_KEY_SIZE:
- case EVP_R_UNSUPPORTED_KEYLENGTH:
- throwInvalidKeyException(env, message);
- break;
- case EVP_R_WRONG_PUBLIC_KEY_TYPE:
- throwSignatureException(env, message);
- break;
- case EVP_R_UNSUPPORTED_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForRsaError(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case RSA_R_BLOCK_TYPE_IS_NOT_01:
- case RSA_R_BLOCK_TYPE_IS_NOT_02:
- throwBadPaddingException(env, message);
- break;
- case RSA_R_ALGORITHM_MISMATCH:
- case RSA_R_BAD_SIGNATURE:
- case RSA_R_DATA_GREATER_THAN_MOD_LEN:
- case RSA_R_DATA_TOO_LARGE_FOR_MODULUS:
- case RSA_R_INVALID_MESSAGE_LENGTH:
- case RSA_R_WRONG_SIGNATURE_LENGTH:
- throwSignatureException(env, message);
- break;
- case RSA_R_UNKNOWN_ALGORITHM_TYPE:
- throwNoSuchAlgorithmException(env, message);
- break;
- case RSA_R_MODULUS_TOO_LARGE:
- case RSA_R_NO_PUBLIC_EXPONENT:
- throwInvalidKeyException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-static void throwForX509Error(JNIEnv* env, int reason, const char *message) {
- switch (reason) {
- case X509_R_UNSUPPORTED_ALGORITHM:
- throwNoSuchAlgorithmException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
-}
-
-/*
- * Checks this thread's OpenSSL error queue and throws a RuntimeException if
- * necessary.
- *
- * @return true if an exception was thrown, false if not.
- */
-static bool throwExceptionIfNecessary(JNIEnv* env, const char* location __attribute__ ((unused))) {
- const char* file;
- int line;
- const char* data;
- int flags;
- unsigned long error = ERR_get_error_line_data(&file, &line, &data, &flags);
- int result = false;
-
- if (error != 0) {
- char message[256];
- ERR_error_string_n(error, message, sizeof(message));
- int library = ERR_GET_LIB(error);
- int reason = ERR_GET_REASON(error);
- JNI_TRACE("OpenSSL error in %s error=%lx library=%x reason=%x (%s:%d): %s %s",
- location, error, library, reason, file, line, message,
- (flags & ERR_TXT_STRING) ? data : "(no data)");
- switch (library) {
- case ERR_LIB_RSA:
- throwForRsaError(env, reason, message);
- break;
- case ERR_LIB_ASN1:
- throwForAsn1Error(env, reason, message);
- break;
- case ERR_LIB_EVP:
- throwForEvpError(env, reason, message);
- break;
- case ERR_LIB_X509:
- throwForX509Error(env, reason, message);
- break;
- case ERR_LIB_DSA:
- throwInvalidKeyException(env, message);
- break;
- default:
- jniThrowRuntimeException(env, message);
- break;
- }
- result = true;
- }
-
- freeOpenSslErrorState();
- return result;
-}
-
-/**
- * Throws an SocketTimeoutException with the given string as a message.
- */
-static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSocketTimeoutException %s", message);
- jniThrowException(env, "java/net/SocketTimeoutException", message);
-}
-
-/**
- * Throws a javax.net.ssl.SSLException with the given string as a message.
- */
-static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSSLExceptionStr %s", message);
- jniThrowException(env, "javax/net/ssl/SSLException", message);
-}
-
-/**
- * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
- */
-static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
- JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
- jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
-}
-
-/**
- * Throws an SSLException with a message constructed from the current
- * SSL errors. This will also log the errors.
- *
- * @param env the JNI environment
- * @param ssl the possibly NULL SSL
- * @param sslErrorCode error code returned from SSL_get_error() or
- * SSL_ERROR_NONE to probe with ERR_get_error
- * @param message null-ok; general error message
- */
-static void throwSSLExceptionWithSslErrors(
- JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) {
-
- if (message == NULL) {
- message = "SSL error";
- }
-
- // First consult the SSL error code for the general message.
- const char* sslErrorStr = NULL;
- switch (sslErrorCode) {
- case SSL_ERROR_NONE:
- if (ERR_peek_error() == 0) {
- sslErrorStr = "OK";
- } else {
- sslErrorStr = "";
- }
- break;
- case SSL_ERROR_SSL:
- sslErrorStr = "Failure in SSL library, usually a protocol error";
- break;
- case SSL_ERROR_WANT_READ:
- sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_WRITE:
- sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
- break;
- case SSL_ERROR_SYSCALL:
- sslErrorStr = "I/O error during system call";
- break;
- case SSL_ERROR_ZERO_RETURN:
- sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_CONNECT:
- sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
- break;
- case SSL_ERROR_WANT_ACCEPT:
- sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
- break;
- default:
- sslErrorStr = "Unknown SSL error";
- }
-
- // Prepend either our explicit message or a default one.
- char* str;
- if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
- // problem with asprintf, just throw argument message, log everything
- throwSSLExceptionStr(env, message);
- ALOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
- freeOpenSslErrorState();
- return;
- }
-
- char* allocStr = str;
-
- // For protocol errors, SSL might have more information.
- if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
- // Append each error as an additional line to the message.
- for (;;) {
- char errStr[256];
- const char* file;
- int line;
- const char* data;
- int flags;
- unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
- if (err == 0) {
- break;
- }
-
- ERR_error_string_n(err, errStr, sizeof(errStr));
-
- int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
- (allocStr == NULL) ? "" : allocStr,
- errStr,
- file,
- line,
- (flags & ERR_TXT_STRING) ? data : "(no data)",
- flags);
-
- if (ret < 0) {
- break;
- }
-
- free(allocStr);
- allocStr = str;
- }
- // For errors during system calls, errno might be our friend.
- } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
- if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
- free(allocStr);
- allocStr = str;
- }
- // If the error code is invalid, print it.
- } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
- if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
- free(allocStr);
- allocStr = str;
- }
- }
-
- if (sslErrorCode == SSL_ERROR_SSL) {
- throwSSLProtocolExceptionStr(env, allocStr);
- } else {
- throwSSLExceptionStr(env, allocStr);
- }
-
- ALOGV("%s", allocStr);
- free(allocStr);
- freeOpenSslErrorState();
-}
-
-/**
- * Helper function that grabs the casts an ssl pointer and then checks for nullness.
- * If this function returns NULL and <code>throwIfNull</code> is
- * passed as <code>true</code>, then this function will call
- * <code>throwSSLExceptionStr</code> before returning, so in this case of
- * NULL, a caller of this function should simply return and allow JNI
- * to do its thing.
- *
- * @param env the JNI environment
- * @param ssl_address; the ssl_address pointer as an integer
- * @param throwIfNull whether to throw if the SSL pointer is NULL
- * @returns the pointer, which may be NULL
- */
-static SSL_CTX* to_SSL_CTX(JNIEnv* env, jlong ssl_ctx_address, bool throwIfNull) {
- SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
- if ((ssl_ctx == NULL) && throwIfNull) {
- JNI_TRACE("ssl_ctx == null");
- jniThrowNullPointerException(env, "ssl_ctx == null");
- }
- return ssl_ctx;
-}
-
-static SSL* to_SSL(JNIEnv* env, jlong ssl_address, bool throwIfNull) {
- SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
- if ((ssl == NULL) && throwIfNull) {
- JNI_TRACE("ssl == null");
- jniThrowNullPointerException(env, "ssl == null");
- }
- return ssl;
-}
-
-static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, jlong ssl_session_address, bool throwIfNull) {
- SSL_SESSION* ssl_session
- = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
- if ((ssl_session == NULL) && throwIfNull) {
- JNI_TRACE("ssl_session == null");
- jniThrowNullPointerException(env, "ssl_session == null");
- }
- return ssl_session;
-}
-
-/**
- * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
- * fly. Returns true on success. If the return value is false, there is a
- * pending exception.
- */
-static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) {
- JNI_TRACE("arrayToBignum(%p, %p)", source, *dest);
-
- ScopedByteArrayRO sourceBytes(env, source);
- if (sourceBytes.get() == NULL) {
- JNI_TRACE("arrayToBignum(%p) => NULL", source);
- return false;
- }
- *dest = BN_bin2bn(reinterpret_cast<const unsigned char*>(sourceBytes.get()),
- sourceBytes.size(),
- NULL);
- if (*dest == NULL) {
- jniThrowRuntimeException(env, "Conversion to BIGNUM failed");
- JNI_TRACE("arrayToBignum(%p) => threw exception", source);
- return false;
- }
-
- JNI_TRACE("arrayToBignum(%p) => %p", source, *dest);
- return true;
-}
-
-/**
- * Converts an OpenSSL BIGNUM to a Java byte[] array.
- */
-static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source, const char* sourceName) {
- JNI_TRACE("bignumToArray(%p, %s)", source, sourceName);
-
- if (source == NULL) {
- jniThrowNullPointerException(env, sourceName);
- return NULL;
- }
-
- jbyteArray javaBytes = env->NewByteArray(BN_num_bytes(source) + 1);
- ScopedByteArrayRW bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("bignumToArray(%p, %s) => NULL", source, sourceName);
- return NULL;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
-
- // Set the sign for the Java code.
- if (BN_is_negative(source)) {
- *tmp = 0xFF;
- } else {
- *tmp = 0x00;
- }
-
- if (BN_num_bytes(source) > 0 && BN_bn2bin(source, tmp + 1) <= 0) {
- throwExceptionIfNecessary(env, "bignumToArray");
- return NULL;
- }
-
- JNI_TRACE("bignumToArray(%p, %s) => %p", source, sourceName, javaBytes);
- return javaBytes;
-}
-
-/**
- * Converts various OpenSSL ASN.1 types to a jbyteArray with DER-encoded data
- * inside. The "i2d_func" function pointer is a function of the "i2d_<TYPE>"
- * from the OpenSSL ASN.1 API.
- */
-template<typename T, int (*i2d_func)(T*, unsigned char**)>
-jbyteArray ASN1ToByteArray(JNIEnv* env, T* obj) {
- if (obj == NULL) {
- jniThrowNullPointerException(env, "ASN1 input == null");
- JNI_TRACE("ASN1ToByteArray(%p) => null input", obj);
- return NULL;
- }
-
- int derLen = i2d_func(obj, NULL);
- if (derLen < 0) {
- throwExceptionIfNecessary(env, "ASN1ToByteArray");
- JNI_TRACE("ASN1ToByteArray(%p) => measurement failed", obj);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(derLen));
- if (byteArray.get() == NULL) {
- JNI_TRACE("ASN1ToByteArray(%p) => creating byte array failed", obj);
- return NULL;
- }
-
- ScopedByteArrayRW bytes(env, byteArray.get());
- if (bytes.get() == NULL) {
- JNI_TRACE("ASN1ToByteArray(%p) => using byte array failed", obj);
- return NULL;
- }
-
- unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
- int ret = i2d_func(obj, &p);
- if (ret < 0) {
- throwExceptionIfNecessary(env, "ASN1ToByteArray");
- JNI_TRACE("ASN1ToByteArray(%p) => final conversion failed", obj);
- return NULL;
- }
-
- JNI_TRACE("ASN1ToByteArray(%p) => success (%d bytes written)", obj, ret);
- return byteArray.release();
-}
-
-template<typename T, T* (*d2i_func)(T**, const unsigned char**, long)>
-T* ByteArrayToASN1(JNIEnv* env, jbyteArray byteArray) {
- ScopedByteArrayRO bytes(env, byteArray);
- if (bytes.get() == NULL) {
- JNI_TRACE("ByteArrayToASN1(%p) => using byte array failed", byteArray);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- return d2i_func(NULL, &tmp, bytes.size());
-}
-
-/**
- * Converts ASN.1 BIT STRING to a jbooleanArray.
- */
-jbooleanArray ASN1BitStringToBooleanArray(JNIEnv* env, ASN1_BIT_STRING* bitStr) {
- int size = bitStr->length * 8;
- if (bitStr->flags & ASN1_STRING_FLAG_BITS_LEFT) {
- size -= bitStr->flags & 0x07;
- }
-
- ScopedLocalRef<jbooleanArray> bitsRef(env, env->NewBooleanArray(size));
- if (bitsRef.get() == NULL) {
- return NULL;
- }
-
- ScopedBooleanArrayRW bitsArray(env, bitsRef.get());
- for (int i = 0; i < static_cast<int>(bitsArray.size()); i++) {
- bitsArray[i] = ASN1_BIT_STRING_get_bit(bitStr, i);
- }
-
- return bitsRef.release();
-}
-
-/**
- * To avoid the round-trip to ASN.1 and back in X509_dup, we just up the reference count.
- */
-static X509* X509_dup_nocopy(X509* x509) {
- CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
- return x509;
-}
-
-/**
- * BIO for InputStream
- */
-class BIO_Stream {
-public:
- BIO_Stream(jobject stream) :
- mEof(false) {
- JNIEnv* env = getEnv();
- mStream = env->NewGlobalRef(stream);
- }
-
- ~BIO_Stream() {
- JNIEnv* env = getEnv();
-
- env->DeleteGlobalRef(mStream);
- }
-
- bool isEof() const {
- JNI_TRACE("isEof? %s", mEof ? "yes" : "no");
- return mEof;
- }
-
- int flush() {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- return -1;
- }
-
- env->CallVoidMethod(mStream, outputStream_flushMethod);
- if (env->ExceptionCheck()) {
- return -1;
- }
-
- return 1;
- }
-
-protected:
- jobject getStream() {
- return mStream;
- }
-
- void setEof(bool eof) {
- mEof = eof;
- }
-
- JNIEnv* getEnv() {
- JNIEnv* env;
-
- if (gJavaVM->AttachCurrentThread(&env, NULL) < 0) {
- return NULL;
- }
-
- return env;
- }
-
-private:
- jobject mStream;
- bool mEof;
-};
-
-class BIO_InputStream : public BIO_Stream {
-public:
- BIO_InputStream(jobject stream) :
- BIO_Stream(stream) {
- }
-
- int read(char *buf, int len) {
- return read_internal(buf, len, inputStream_readMethod);
- }
-
- int gets(char *buf, int len) {
- if (len > PEM_LINE_LENGTH) {
- len = PEM_LINE_LENGTH;
- }
-
- int read = read_internal(buf, len - 1, openSslInputStream_readLineMethod);
- buf[read] = '\0';
- JNI_TRACE("BIO::gets \"%s\"", buf);
- return read;
- }
-
-private:
- int read_internal(char *buf, int len, jmethodID method) {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- JNI_TRACE("BIO_InputStream::read could not get JNIEnv");
- return -1;
- }
-
- ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
- if (javaBytes.get() == NULL) {
- JNI_TRACE("BIO_InputStream::read failed call to NewByteArray");
- return -1;
- }
-
- jint read = env->CallIntMethod(getStream(), method, javaBytes.get());
- if (env->ExceptionCheck()) {
- JNI_TRACE("BIO_InputStream::read failed call to InputStream#read");
- return -1;
- }
-
- /* Java uses -1 to indicate EOF condition. */
- if (read == -1) {
- setEof(true);
- read = 0;
- } else if (read > 0) {
- env->GetByteArrayRegion(javaBytes.get(), 0, read, reinterpret_cast<jbyte*>(buf));
- }
-
- return read;
- }
-
-public:
- /** Length of PEM-encoded line (64) plus CR plus NULL */
- static const int PEM_LINE_LENGTH = 66;
-};
-
-class BIO_OutputStream : public BIO_Stream {
-public:
- BIO_OutputStream(jobject stream) :
- BIO_Stream(stream) {
- }
-
- int write(const char *buf, int len) {
- JNIEnv* env = getEnv();
- if (env == NULL) {
- JNI_TRACE("BIO_OutputStream::write => could not get JNIEnv");
- return -1;
- }
-
- ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
- if (javaBytes.get() == NULL) {
- JNI_TRACE("BIO_OutputStream::write => failed call to NewByteArray");
- return -1;
- }
-
- env->SetByteArrayRegion(javaBytes.get(), 0, len, reinterpret_cast<const jbyte*>(buf));
-
- env->CallVoidMethod(getStream(), outputStream_writeMethod, javaBytes.get());
- if (env->ExceptionCheck()) {
- JNI_TRACE("BIO_OutputStream::write => failed call to OutputStream#write");
- return -1;
- }
-
- return len;
- }
-};
-
-static int bio_stream_create(BIO *b) {
- b->init = 1;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
- return 1;
-}
-
-static int bio_stream_destroy(BIO *b) {
- if (b == NULL) {
- return 0;
- }
-
- if (b->ptr != NULL) {
- delete static_cast<BIO_Stream*>(b->ptr);
- b->ptr = NULL;
- }
-
- b->init = 0;
- b->flags = 0;
- return 1;
-}
-
-static int bio_stream_read(BIO *b, char *buf, int len) {
- BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
- return stream->read(buf, len);
-}
-
-static int bio_stream_write(BIO *b, const char *buf, int len) {
- BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
- return stream->write(buf, len);
-}
-
-static int bio_stream_puts(BIO *b, const char *buf) {
- BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
- return stream->write(buf, strlen(buf));
-}
-
-static int bio_stream_gets(BIO *b, char *buf, int len) {
- BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
- return stream->gets(buf, len);
-}
-
-static void bio_stream_assign(BIO *b, BIO_Stream* stream) {
- b->ptr = static_cast<void*>(stream);
-}
-
-static long bio_stream_ctrl(BIO *b, int cmd, long, void *) {
- BIO_Stream* stream = static_cast<BIO_Stream*>(b->ptr);
-
- switch (cmd) {
- case BIO_CTRL_EOF:
- return stream->isEof() ? 1 : 0;
- case BIO_CTRL_FLUSH:
- return stream->flush();
- default:
- return 0;
- }
-}
-
-static BIO_METHOD stream_bio_method = {
- ( 100 | 0x0400 ), /* source/sink BIO */
- "InputStream/OutputStream BIO",
- bio_stream_write, /* bio_write */
- bio_stream_read, /* bio_read */
- bio_stream_puts, /* bio_puts */
- bio_stream_gets, /* bio_gets */
- bio_stream_ctrl, /* bio_ctrl */
- bio_stream_create, /* bio_create */
- bio_stream_destroy, /* bio_free */
- NULL, /* no bio_callback_ctrl */
-};
-
-/**
- * Copied from libnativehelper NetworkUtilites.cpp
- */
-static bool setBlocking(int fd, bool blocking) {
- int flags = fcntl(fd, F_GETFL);
- if (flags == -1) {
- return false;
- }
-
- if (!blocking) {
- flags |= O_NONBLOCK;
- } else {
- flags &= ~O_NONBLOCK;
- }
-
- int rc = fcntl(fd, F_SETFL, flags);
- return (rc != -1);
-}
-
-/**
- * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
- * suppose there are not many other ways to do this on a Linux system (modulo
- * isomorphism).
- */
-#define MUTEX_TYPE pthread_mutex_t
-#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
-#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
-#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
-#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
-#define THREAD_ID pthread_self()
-#define THROW_SSLEXCEPTION (-2)
-#define THROW_SOCKETTIMEOUTEXCEPTION (-3)
-#define THROWN_EXCEPTION (-4)
-
-static MUTEX_TYPE* mutex_buf = NULL;
-
-static void locking_function(int mode, int n, const char*, int) {
- if (mode & CRYPTO_LOCK) {
- MUTEX_LOCK(mutex_buf[n]);
- } else {
- MUTEX_UNLOCK(mutex_buf[n]);
- }
-}
-
-static unsigned long id_function(void) {
- return ((unsigned long)THREAD_ID);
-}
-
-int THREAD_setup(void) {
- mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
- if (!mutex_buf) {
- return 0;
- }
-
- for (int i = 0; i < CRYPTO_num_locks(); ++i) {
- MUTEX_SETUP(mutex_buf[i]);
- }
-
- CRYPTO_set_id_callback(id_function);
- CRYPTO_set_locking_callback(locking_function);
-
- return 1;
-}
-
-int THREAD_cleanup(void) {
- if (!mutex_buf) {
- return 0;
- }
-
- CRYPTO_set_id_callback(NULL);
- CRYPTO_set_locking_callback(NULL);
-
- for (int i = 0; i < CRYPTO_num_locks( ); i++) {
- MUTEX_CLEANUP(mutex_buf[i]);
- }
-
- free(mutex_buf);
- mutex_buf = NULL;
-
- return 1;
-}
-
-/**
- * Initialization phase for every OpenSSL job: Loads the Error strings, the
- * crypto algorithms and reset the OpenSSL library
- */
-static void NativeCrypto_clinit(JNIEnv*, jclass)
-{
- SSL_load_error_strings();
- ERR_load_crypto_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- THREAD_setup();
-}
-
-static void NativeCrypto_ENGINE_load_dynamic(JNIEnv*, jclass) {
- JNI_TRACE("ENGINE_load_dynamic()");
-
- ENGINE_load_dynamic();
-}
-
-static jlong NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
- JNI_TRACE("ENGINE_by_id(%p)", idJava);
-
- ScopedUtfChars id(env, idJava);
- if (id.c_str() == NULL) {
- JNI_TRACE("ENGINE_by_id(%p) => id == null", idJava);
- return 0;
- }
- JNI_TRACE("ENGINE_by_id(\"%s\")", id.c_str());
-
- ENGINE* e = ENGINE_by_id(id.c_str());
- if (e == NULL) {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("ENGINE_by_id(\"%s\") => %p", id.c_str(), e);
- return reinterpret_cast<uintptr_t>(e);
-}
-
-static jint NativeCrypto_ENGINE_add(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_add(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_add(e);
-
- /*
- * We tolerate errors, because the most likely error is that
- * the ENGINE is already in the list.
- */
- freeOpenSslErrorState();
-
- JNI_TRACE("ENGINE_add(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_init(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_init(e);
- JNI_TRACE("ENGINE_init(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_finish(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_finish(e);
- JNI_TRACE("ENGINE_finish(%p) => %d", e, ret);
- return ret;
-}
-
-static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jlong engineRef) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_free(%p)", e);
-
- if (e == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
- return 0;
- }
-
- int ret = ENGINE_free(e);
- JNI_TRACE("ENGINE_free(%p) => %d", e, ret);
- return ret;
-}
-
-static jlong NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jlong engineRef,
- jstring idJava) {
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_load_private_key(%p, %p)", e, idJava);
-
- ScopedUtfChars id(env, idJava);
- if (id.c_str() == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "id == NULL");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(ENGINE_load_private_key(e, id.c_str(), NULL, NULL));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "ENGINE_load_private_key");
- return 0;
- }
-
- JNI_TRACE("ENGINE_load_private_key(%p, %p) => %p", e, idJava, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jstring NativeCrypto_ENGINE_get_id(JNIEnv* env, jclass, jlong engineRef)
-{
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_get_id(%p)", e);
-
- if (e == NULL) {
- jniThrowNullPointerException(env, "engine == null");
- JNI_TRACE("ENGINE_get_id(%p) => engine == null", e);
- return NULL;
- }
-
- const char *id = ENGINE_get_id(e);
- ScopedLocalRef<jstring> idJava(env, env->NewStringUTF(id));
-
- JNI_TRACE("ENGINE_get_id(%p) => \"%s\"", e, id);
- return idJava.release();
-}
-
-static jint NativeCrypto_ENGINE_ctrl_cmd_string(JNIEnv* env, jclass, jlong engineRef,
- jstring cmdJava, jstring argJava, jint cmd_optional)
-{
- ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d)", e, cmdJava, argJava, cmd_optional);
-
- if (e == NULL) {
- jniThrowNullPointerException(env, "engine == null");
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d) => engine == null", e, cmdJava, argJava,
- cmd_optional);
- return 0;
- }
-
- ScopedUtfChars cmdChars(env, cmdJava);
- if (cmdChars.c_str() == NULL) {
- return 0;
- }
-
- UniquePtr<ScopedUtfChars> arg;
- const char* arg_c_str = NULL;
- if (argJava != NULL) {
- arg.reset(new ScopedUtfChars(env, argJava));
- arg_c_str = arg->c_str();
- if (arg_c_str == NULL) {
- return 0;
- }
- }
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d)", e, cmdChars.c_str(), arg_c_str,
- cmd_optional);
-
- int ret = ENGINE_ctrl_cmd_string(e, cmdChars.c_str(), arg_c_str, cmd_optional);
- if (ret != 1) {
- throwExceptionIfNecessary(env, "ENGINE_ctrl_cmd_string");
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => threw error", e,
- cmdChars.c_str(), arg_c_str, cmd_optional);
- return 0;
- }
-
- JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => %d", e, cmdChars.c_str(),
- arg_c_str, cmd_optional, ret);
- return ret;
-}
-
-/**
- * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
- * byte[] pub_key, byte[] priv_key);
- */
-static jlong NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
- jbyteArray p, jbyteArray q, jbyteArray g,
- jbyteArray pub_key, jbyteArray priv_key) {
- JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
- p, q, g, pub_key, priv_key);
-
- Unique_DSA dsa(DSA_new());
- if (dsa.get() == NULL) {
- jniThrowRuntimeException(env, "DSA_new failed");
- return 0;
- }
-
- if (!arrayToBignum(env, p, &dsa->p)) {
- return 0;
- }
-
- if (!arrayToBignum(env, q, &dsa->q)) {
- return 0;
- }
-
- if (!arrayToBignum(env, g, &dsa->g)) {
- return 0;
- }
-
- if (pub_key != NULL && !arrayToBignum(env, pub_key, &dsa->pub_key)) {
- return 0;
- }
-
- if (priv_key != NULL && !arrayToBignum(env, priv_key, &dsa->priv_key)) {
- return 0;
- }
-
- if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL
- || (dsa->pub_key == NULL && dsa->priv_key == NULL)) {
- jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(dsa);
- JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
- p, q, g, pub_key, priv_key, pkey.get());
- return reinterpret_cast<jlong>(pkey.release());
-}
-
-/**
- * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
- */
-static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
- jbyteArray n, jbyteArray e, jbyteArray d,
- jbyteArray p, jbyteArray q,
- jbyteArray dmp1, jbyteArray dmq1,
- jbyteArray iqmp) {
- JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p, dmp1=%p, dmq1=%p, iqmp=%p)",
- n, e, d, p, q, dmp1, dmq1, iqmp);
-
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_new failed");
- return 0;
- }
-
- if (e == NULL && d == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "e == NULL && d == NULL");
- JNI_TRACE("NativeCrypto_EVP_PKEY_new_RSA => e == NULL && d == NULL");
- return 0;
- }
-
- if (!arrayToBignum(env, n, &rsa->n)) {
- return 0;
- }
-
- if (e != NULL && !arrayToBignum(env, e, &rsa->e)) {
- return 0;
- }
-
- if (d != NULL && !arrayToBignum(env, d, &rsa->d)) {
- return 0;
- }
-
- if (p != NULL && !arrayToBignum(env, p, &rsa->p)) {
- return 0;
- }
-
- if (q != NULL && !arrayToBignum(env, q, &rsa->q)) {
- return 0;
- }
-
- if (dmp1 != NULL && !arrayToBignum(env, dmp1, &rsa->dmp1)) {
- return 0;
- }
-
- if (dmq1 != NULL && !arrayToBignum(env, dmq1, &rsa->dmq1)) {
- return 0;
- }
-
- if (iqmp != NULL && !arrayToBignum(env, iqmp, &rsa->iqmp)) {
- return 0;
- }
-
-#ifdef WITH_JNI_TRACE
- if (p != NULL && q != NULL) {
- int check = RSA_check_key(rsa.get());
- JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
- }
-#endif
-
- if (rsa->n == NULL || (rsa->e == NULL && rsa->d == NULL)) {
- jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
- return 0;
- }
-
- /*
- * If the private exponent is available, there is the potential to do signing
- * operations. If the public exponent is also available, OpenSSL will do RSA
- * blinding. Enable it if possible.
- */
- if (rsa->d != NULL) {
- if (rsa->e != NULL) {
- JNI_TRACE("EVP_PKEY_new_RSA(...) enabling RSA blinding => %p", rsa.get());
- RSA_blinding_on(rsa.get(), NULL);
- } else {
- JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get());
- RSA_blinding_off(rsa.get());
- }
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_new failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(rsa);
- JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p dmp1=%p, dmq1=%p, iqmp=%p) => %p",
- n, e, d, p, q, dmp1, dmq1, iqmp, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EVP_PKEY_new_EC_KEY(JNIEnv* env, jclass, jlong groupRef,
- jlong pubkeyRef, jbyteArray keyJavaBytes) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* pubkey = reinterpret_cast<const EC_POINT*>(pubkeyRef);
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p)", group, pubkey, keyJavaBytes);
-
- Unique_BIGNUM key(NULL);
- if (keyJavaBytes != NULL) {
- BIGNUM* keyRef;
- if (!arrayToBignum(env, keyJavaBytes, &keyRef)) {
- return 0;
- }
- key.reset(keyRef);
- }
-
- Unique_EC_KEY eckey(EC_KEY_new());
- if (eckey.get() == NULL) {
- jniThrowRuntimeException(env, "EC_KEY_new failed");
- return 0;
- }
-
- if (EC_KEY_set_group(eckey.get(), group) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) > EC_KEY_set_group failed", group, pubkey,
- keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- if (pubkey != NULL) {
- if (EC_KEY_set_public_key(eckey.get(), pubkey) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_public_key");
- return 0;
- }
- }
-
- if (key.get() != NULL) {
- if (EC_KEY_set_private_key(eckey.get(), key.get()) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
- return 0;
- }
- if (pubkey == NULL) {
- Unique_EC_POINT calcPubkey(EC_POINT_new(group));
- if (!EC_POINT_mul(group, calcPubkey.get(), key.get(), NULL, NULL, NULL)) {
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => can't calulate public key", group,
- pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
- return 0;
- }
- EC_KEY_set_public_key(eckey.get(), calcPubkey.get());
- }
- }
-
- if (!EC_KEY_check_key(eckey.get())) {
- JNI_TRACE("EVP_KEY_new_EC_KEY(%p, %p, %p) => invalid key created", group, pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EC_KEY_check_key");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
- throwExceptionIfNecessary(env, "EVP_PKEY_new failed");
- return 0;
- }
- if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
- JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
- jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(eckey);
-
- JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => %p", group, pubkey, keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EVP_PKEY_new_mac_key(JNIEnv* env, jclass, jint pkeyType,
- jbyteArray keyJavaBytes)
-{
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p)", pkeyType, keyJavaBytes);
-
- ScopedByteArrayRO key(env, keyJavaBytes);
- if (key.get() == NULL) {
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(key.get());
- Unique_EVP_PKEY pkey(EVP_PKEY_new_mac_key(pkeyType, (ENGINE *) NULL, tmp, key.size()));
- if (pkey.get() == NULL) {
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => threw error", pkeyType, keyJavaBytes);
- throwExceptionIfNecessary(env, "ENGINE_load_private_key");
- return 0;
- }
-
- JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => %p", pkeyType, keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_type(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_PKEY_type(pkey->type);
- JNI_TRACE("EVP_PKEY_type(%p) => %d", pkey, result);
- return result;
-}
-
-/**
- * private static native int EVP_PKEY_size(int pkey);
- */
-static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_size(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_PKEY_size(pkey);
- JNI_TRACE("EVP_PKEY_size(%p) => %d", pkey, result);
- return result;
-}
-
-static jstring NativeCrypto_EVP_PKEY_print_public(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_print_public(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return NULL;
- }
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- return NULL;
- }
-
- if (EVP_PKEY_print_public(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
- throwExceptionIfNecessary(env, "EVP_PKEY_print_public");
- return NULL;
- }
- // Null terminate this
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- jstring description = env->NewStringUTF(tmp);
-
- JNI_TRACE("EVP_PKEY_print_public(%p) => \"%s\"", pkey, tmp);
- return description;
-}
-
-static jstring NativeCrypto_EVP_PKEY_print_private(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_print_private(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return NULL;
- }
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- return NULL;
- }
-
- if (EVP_PKEY_print_private(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
- throwExceptionIfNecessary(env, "EVP_PKEY_print_private");
- return NULL;
- }
- // Null terminate this
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- jstring description = env->NewStringUTF(tmp);
-
- JNI_TRACE("EVP_PKEY_print_private(%p) => \"%s\"", pkey, tmp);
- return description;
-}
-
-static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_PKEY_free(%p)", pkey);
-
- if (pkey != NULL) {
- EVP_PKEY_free(pkey);
- }
-}
-
-static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jlong pkey1Ref, jlong pkey2Ref) {
- EVP_PKEY* pkey1 = reinterpret_cast<EVP_PKEY*>(pkey1Ref);
- EVP_PKEY* pkey2 = reinterpret_cast<EVP_PKEY*>(pkey2Ref);
- JNI_TRACE("EVP_PKEY_cmp(%p, %p)", pkey1, pkey2);
-
- if (pkey1 == NULL) {
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey1 == NULL", pkey1, pkey2);
- jniThrowNullPointerException(env, "pkey1 == NULL");
- return -1;
- } else if (pkey2 == NULL) {
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey2 == NULL", pkey1, pkey2);
- jniThrowNullPointerException(env, "pkey2 == NULL");
- return -1;
- }
-
- int result = EVP_PKEY_cmp(pkey1, pkey2);
- JNI_TRACE("EVP_PKEY_cmp(%p, %p) => %d", pkey1, pkey2, result);
- return result;
-}
-
-/*
- * static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
- */
-static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("i2d_PKCS8_PRIV_KEY_INFO(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return NULL;
- }
-
- Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey));
- if (pkcs8.get() == NULL) {
- throwExceptionIfNecessary(env, "NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("key=%p i2d_PKCS8_PRIV_KEY_INFO => error from key to PKCS8", pkey);
- return NULL;
- }
-
- return ASN1ToByteArray<PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO>(env, pkcs8.get());
-}
-
-/*
- * static native int d2i_PKCS8_PRIV_KEY_INFO(byte[])
- */
-static jlong NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
- JNI_TRACE("d2i_PKCS8_PRIV_KEY_INFO(%p)", keyJavaBytes);
-
- ScopedByteArrayRO bytes(env, keyJavaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => threw exception", keyJavaBytes);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, bytes.size()));
- if (pkcs8.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from DER to PKCS8", keyJavaBytes);
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
- JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from PKCS8 to key", keyJavaBytes);
- return 0;
- }
-
- JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => %p", keyJavaBytes, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * static native byte[] i2d_PUBKEY(int)
- */
-static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("i2d_PUBKEY(%p)", pkey);
- return ASN1ToByteArray<EVP_PKEY, i2d_PUBKEY>(env, pkey);
-}
-
-/*
- * static native int d2i_PUBKEY(byte[])
- */
-static jlong NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
- JNI_TRACE("d2i_PUBKEY(%p)", javaBytes);
-
- ScopedByteArrayRO bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("d2i_PUBKEY(%p) => threw error", javaBytes);
- return 0;
- }
-
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
- Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, bytes.size()));
- if (pkey.get() == NULL) {
- JNI_TRACE("bytes=%p d2i_PUBKEY => threw exception", javaBytes);
- throwExceptionIfNecessary(env, "d2i_PUBKEY");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * public static native int RSA_generate_key(int modulusBits, byte[] publicExponent);
- */
-static jlong NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
- jbyteArray publicExponent) {
- JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
-
- BIGNUM* eRef;
- if (!arrayToBignum(env, publicExponent, &eRef)) {
- return 0;
- }
- Unique_BIGNUM e(eRef);
-
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate RSA key");
- return 0;
- }
-
- if (RSA_generate_key_ex(rsa.get(), modulusBits, e.get(), NULL) < 0) {
- throwExceptionIfNecessary(env, "RSA_generate_key_ex");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
- return 0;
- }
-
- if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
- jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
- return 0;
- }
-
- OWNERSHIP_TRANSFERRED(rsa);
- JNI_TRACE("RSA_generate_key_ex(n=%d, e=%p) => %p", modulusBits, publicExponent, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jint NativeCrypto_RSA_size(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("RSA_size(%p)", pkey);
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- jniThrowRuntimeException(env, "RSA_size failed");
- return 0;
- }
-
- return static_cast<jint>(RSA_size(rsa.get()));
-}
-
-typedef int RSACryptOperation(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
- int padding);
-
-static jint RSA_crypt_operation(RSACryptOperation operation,
- const char* caller __attribute__ ((unused)), JNIEnv* env, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("%s(%d, %p, %p, %p)", caller, flen, fromJavaBytes, toJavaBytes, pkey);
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- return -1;
- }
-
- ScopedByteArrayRO from(env, fromJavaBytes);
- if (from.get() == NULL) {
- return -1;
- }
-
- ScopedByteArrayRW to(env, toJavaBytes);
- if (to.get() == NULL) {
- return -1;
- }
-
- int resultSize = operation(static_cast<int>(flen),
- reinterpret_cast<const unsigned char*>(from.get()),
- reinterpret_cast<unsigned char*>(to.get()), rsa.get(), padding);
- if (resultSize == -1) {
- JNI_TRACE("%s => failed", caller);
- throwExceptionIfNecessary(env, "RSA_crypt_operation");
- return -1;
- }
-
- JNI_TRACE("%s(%d, %p, %p, %p) => %d", caller, flen, fromJavaBytes, toJavaBytes, pkey,
- resultSize);
- return static_cast<jint>(resultSize);
-}
-
-static jint NativeCrypto_RSA_private_encrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_private_encrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_public_decrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_public_decrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_public_encrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_public_encrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-static jint NativeCrypto_RSA_private_decrypt(JNIEnv* env, jclass, jint flen,
- jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
- return RSA_crypt_operation(RSA_private_decrypt, __FUNCTION__,
- env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
-}
-
-/*
- * public static native byte[][] get_RSA_public_params(int);
- */
-static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_RSA_public_params(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return 0;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_RSA_public_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray n = bignumToArray(env, rsa->n, "n");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, n);
-
- jbyteArray e = bignumToArray(env, rsa->e, "e");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, e);
-
- return joa;
-}
-
-/*
- * public static native byte[][] get_RSA_private_params(int);
- */
-static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_RSA_public_params(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return 0;
- }
-
- Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
- if (rsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_RSA_public_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(8, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray n = bignumToArray(env, rsa->n, "n");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, n);
-
- if (rsa->e != NULL) {
- jbyteArray e = bignumToArray(env, rsa->e, "e");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, e);
- }
-
- if (rsa->d != NULL) {
- jbyteArray d = bignumToArray(env, rsa->d, "d");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, d);
- }
-
- if (rsa->p != NULL) {
- jbyteArray p = bignumToArray(env, rsa->p, "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 3, p);
- }
-
- if (rsa->q != NULL) {
- jbyteArray q = bignumToArray(env, rsa->q, "q");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 4, q);
- }
-
- if (rsa->dmp1 != NULL) {
- jbyteArray dmp1 = bignumToArray(env, rsa->dmp1, "dmp1");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 5, dmp1);
- }
-
- if (rsa->dmq1 != NULL) {
- jbyteArray dmq1 = bignumToArray(env, rsa->dmq1, "dmq1");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 6, dmq1);
- }
-
- if (rsa->iqmp != NULL) {
- jbyteArray iqmp = bignumToArray(env, rsa->iqmp, "iqmp");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 7, iqmp);
- }
-
- return joa;
-}
-
-/*
- * public static native int DSA_generate_key(int, byte[]);
- */
-static jlong NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
- jbyteArray seedJavaBytes, jbyteArray gBytes, jbyteArray pBytes, jbyteArray qBytes) {
- JNI_TRACE("DSA_generate_key(%d, %p, %p, %p, %p)", primeBits, seedJavaBytes,
- gBytes, pBytes, qBytes);
-
- UniquePtr<unsigned char[]> seedPtr;
- unsigned long seedSize = 0;
- if (seedJavaBytes != NULL) {
- ScopedByteArrayRO seed(env, seedJavaBytes);
- if (seed.get() == NULL) {
- return 0;
- }
-
- seedSize = seed.size();
- seedPtr.reset(new unsigned char[seedSize]);
-
- memcpy(seedPtr.get(), seed.get(), seedSize);
- }
-
- Unique_DSA dsa(DSA_new());
- if (dsa.get() == NULL) {
- JNI_TRACE("DSA_generate_key failed");
- jniThrowOutOfMemory(env, "Unable to allocate DSA key");
- freeOpenSslErrorState();
- return 0;
- }
-
- if (gBytes != NULL && pBytes != NULL && qBytes != NULL) {
- JNI_TRACE("DSA_generate_key parameters specified");
-
- if (!arrayToBignum(env, gBytes, &dsa->g)) {
- return 0;
- }
-
- if (!arrayToBignum(env, pBytes, &dsa->p)) {
- return 0;
- }
-
- if (!arrayToBignum(env, qBytes, &dsa->q)) {
- return 0;
- }
- } else {
- JNI_TRACE("DSA_generate_key generating parameters");
-
- if (!DSA_generate_parameters_ex(dsa.get(), primeBits, seedPtr.get(), seedSize, NULL, NULL, NULL)) {
- JNI_TRACE("DSA_generate_key => param generation failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_parameters_ex failed");
- return 0;
- }
- }
-
- if (!DSA_generate_key(dsa.get())) {
- JNI_TRACE("DSA_generate_key failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("DSA_generate_key failed");
- jniThrowRuntimeException(env, "NativeCrypto_DSA_generate_key failed");
- freeOpenSslErrorState();
- return 0;
- }
-
- if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
- JNI_TRACE("DSA_generate_key failed");
- throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
- return 0;
- }
-
- OWNERSHIP_TRANSFERRED(dsa);
- JNI_TRACE("DSA_generate_key(n=%d, e=%p) => %p", primeBits, seedPtr.get(), pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-/*
- * public static native byte[][] get_DSA_params(int);
- */
-static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jlong pkeyRef) {
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("get_DSA_params(%p)", pkey);
-
- Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
- if (dsa.get() == NULL) {
- throwExceptionIfNecessary(env, "get_DSA_params failed");
- return 0;
- }
-
- jobjectArray joa = env->NewObjectArray(5, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- if (dsa->g != NULL) {
- jbyteArray g = bignumToArray(env, dsa->g, "g");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, g);
- }
-
- if (dsa->p != NULL) {
- jbyteArray p = bignumToArray(env, dsa->p, "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, p);
- }
-
- if (dsa->q != NULL) {
- jbyteArray q = bignumToArray(env, dsa->q, "q");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, q);
- }
-
- if (dsa->pub_key != NULL) {
- jbyteArray pub_key = bignumToArray(env, dsa->pub_key, "pub_key");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 3, pub_key);
- }
-
- if (dsa->priv_key != NULL) {
- jbyteArray priv_key = bignumToArray(env, dsa->priv_key, "priv_key");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 4, priv_key);
- }
-
- return joa;
-}
-
-#define EC_CURVE_GFP 1
-#define EC_CURVE_GF2M 2
-
-/**
- * Return group type or 0 if unknown group.
- * EC_GROUP_GFP or EC_GROUP_GF2M
- */
-static int get_EC_GROUP_type(const EC_GROUP* group)
-{
- const EC_METHOD* method = EC_GROUP_method_of(group);
- if (method == EC_GFp_nist_method()
- || method == EC_GFp_mont_method()
- || method == EC_GFp_simple_method()) {
- return EC_CURVE_GFP;
- } else if (method == EC_GF2m_simple_method()) {
- return EC_CURVE_GF2M;
- }
-
- return 0;
-}
-
-static jlong NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava)
-{
- JNI_TRACE("EC_GROUP_new_by_curve_name(%p)", curveNameJava);
-
- ScopedUtfChars curveName(env, curveNameJava);
- if (curveName.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s)", curveName.c_str());
-
- int nid = OBJ_sn2nid(curveName.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID name", curveName.c_str());
- return 0;
- }
-
- EC_GROUP* group = EC_GROUP_new_by_curve_name(nid);
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID %d", curveName.c_str(), nid);
- freeOpenSslErrorState();
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => %p", curveName.c_str(), group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static void NativeCrypto_EC_GROUP_set_asn1_flag(JNIEnv* env, jclass, jlong groupRef,
- jint flag)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d)", group, flag);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_set_asn1_flag => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_set_asn1_flag(group, flag);
- JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d) => success", group, flag);
-}
-
-static void NativeCrypto_EC_GROUP_set_point_conversion_form(JNIEnv* env, jclass,
- jlong groupRef, jint form)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d)", group, form);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_set_point_conversion_form => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_set_point_conversion_form(group, static_cast<point_conversion_form_t>(form));
- JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d) => success", group, form);
-}
-
-static jlong NativeCrypto_EC_GROUP_new_curve(JNIEnv* env, jclass, jint type, jbyteArray pJava,
- jbyteArray aJava, jbyteArray bJava)
-{
- JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p)", type, pJava, aJava, bJava);
-
- BIGNUM* pRef;
- if (!arrayToBignum(env, pJava, &pRef)) {
- return 0;
- }
- Unique_BIGNUM p(pRef);
-
- BIGNUM* aRef;
- if (!arrayToBignum(env, aJava, &aRef)) {
- return 0;
- }
- Unique_BIGNUM a(aRef);
-
- BIGNUM* bRef;
- if (!arrayToBignum(env, bJava, &bRef)) {
- return 0;
- }
- Unique_BIGNUM b(bRef);
-
- EC_GROUP* group;
- switch (type) {
- case EC_CURVE_GFP:
- group = EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- case EC_CURVE_GF2M:
- group = EC_GROUP_new_curve_GF2m(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid group");
- return 0;
- }
-
- if (group == NULL) {
- throwExceptionIfNecessary(env, "EC_GROUP_new_curve");
- }
-
- JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p) => %p", type, pJava, aJava, bJava, group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static jlong NativeCrypto_EC_GROUP_dup(JNIEnv* env, jclass, jlong groupRef) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_dup(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_dup => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return 0;
- }
-
- EC_GROUP* groupDup = EC_GROUP_dup(group);
- JNI_TRACE("EC_GROUP_dup(%p) => %p", group, groupDup);
- return reinterpret_cast<uintptr_t>(groupDup);
-}
-
-static jstring NativeCrypto_EC_GROUP_get_curve_name(JNIEnv* env, jclass, jlong groupRef) {
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_curve_name(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_get_curve_name => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return 0;
- }
-
- int nid = EC_GROUP_get_curve_name(group);
- if (nid == NID_undef) {
- JNI_TRACE("EC_GROUP_get_curve_name(%p) => unnamed curve", group);
- return NULL;
- }
-
- const char* shortName = OBJ_nid2sn(nid);
- JNI_TRACE("EC_GROUP_get_curve_name(%p) => \"%s\"", group, shortName);
- return env->NewStringUTF(shortName);
-}
-
-static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_curve(%p)", group);
-
- Unique_BIGNUM p(BN_new());
- Unique_BIGNUM a(BN_new());
- Unique_BIGNUM b(BN_new());
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_GROUP_get_curve_GFp(group, p.get(), a.get(), b.get(), (BN_CTX*) NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_GROUP_get_curve_GF2m(group, p.get(), a.get(), b.get(), (BN_CTX*)NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid group");
- return NULL;
- }
- if (ret != 1) {
- throwExceptionIfNecessary(env, "EC_GROUP_get_curve");
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(3, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray pArray = bignumToArray(env, p.get(), "p");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, pArray);
-
- jbyteArray aArray = bignumToArray(env, a.get(), "a");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, aArray);
-
- jbyteArray bArray = bignumToArray(env, b.get(), "b");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 2, bArray);
-
- JNI_TRACE("EC_GROUP_get_curve(%p) => %p", group, joa);
- return joa;
-}
-
-static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_order(%p)", group);
-
- Unique_BIGNUM order(BN_new());
- if (order.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_order(%p) => can't create BN", group);
- jniThrowOutOfMemory(env, "BN_new");
- return NULL;
- }
-
- if (EC_GROUP_get_order(group, order.get(), NULL) != 1) {
- JNI_TRACE("EC_GROUP_get_order(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_GROUP_get_order");
- return NULL;
- }
-
- jbyteArray orderArray = bignumToArray(env, order.get(), "order");
- if (env->ExceptionCheck()) {
- return NULL;
- }
-
- JNI_TRACE("EC_GROUP_get_order(%p) => %p", group, orderArray);
- return orderArray;
-}
-
-static jint NativeCrypto_EC_GROUP_get_degree(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_degree(%p)", group);
-
- jint degree = EC_GROUP_get_degree(group);
- if (degree == 0) {
- JNI_TRACE("EC_GROUP_get_degree(%p) => unsupported", group);
- jniThrowRuntimeException(env, "not supported");
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_get_degree(%p) => %d", group, degree);
- return degree;
-}
-
-static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_cofactor(%p)", group);
-
- Unique_BIGNUM cofactor(BN_new());
- if (cofactor.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => can't create BN", group);
- jniThrowOutOfMemory(env, "BN_new");
- return NULL;
- }
-
- if (EC_GROUP_get_cofactor(group, cofactor.get(), NULL) != 1) {
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_GROUP_get_cofactor");
- return NULL;
- }
-
- jbyteArray cofactorArray = bignumToArray(env, cofactor.get(), "cofactor");
- if (env->ExceptionCheck()) {
- return NULL;
- }
-
- JNI_TRACE("EC_GROUP_get_cofactor(%p) => %p", group, cofactorArray);
- return cofactorArray;
-}
-
-static jint NativeCrypto_get_EC_GROUP_type(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("get_EC_GROUP_type(%p)", group);
-
- int type = get_EC_GROUP_type(group);
- if (type == 0) {
- JNI_TRACE("get_EC_GROUP_type(%p) => curve type", group);
- jniThrowRuntimeException(env, "unknown curve type");
- } else {
- JNI_TRACE("get_EC_GROUP_type(%p) => %d", group, type);
- }
- return type;
-}
-
-static void NativeCrypto_EC_GROUP_clear_free(JNIEnv* env, jclass, jlong groupRef)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_clear_free(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_GROUP_clear_free => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_GROUP_clear_free(group);
- JNI_TRACE("EC_GROUP_clear_free(%p) => success", group);
-}
-
-static jboolean NativeCrypto_EC_GROUP_cmp(JNIEnv* env, jclass, jlong group1Ref, jlong group2Ref)
-{
- const EC_GROUP* group1 = reinterpret_cast<const EC_GROUP*>(group1Ref);
- const EC_GROUP* group2 = reinterpret_cast<const EC_GROUP*>(group2Ref);
- JNI_TRACE("EC_GROUP_cmp(%p, %p)", group1, group2);
-
- if (group1 == NULL || group2 == NULL) {
- JNI_TRACE("EC_GROUP_cmp(%p, %p) => group1 == null || group2 == null", group1, group2);
- jniThrowNullPointerException(env, "group1 == null || group2 == null");
- return false;
- }
-
- int ret = EC_GROUP_cmp(group1, group2, (BN_CTX*)NULL);
-
- JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", group1, group2, ret);
- return ret == 0;
-}
-
-static void NativeCrypto_EC_GROUP_set_generator(JNIEnv* env, jclass, jlong groupRef, jlong pointRef, jbyteArray njavaBytes, jbyteArray hjavaBytes)
-{
- EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
- const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p)", group, point, njavaBytes, hjavaBytes);
-
- if (group == NULL || point == NULL) {
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => group == null || point == null",
- group, point, njavaBytes, hjavaBytes);
- jniThrowNullPointerException(env, "group == null || point == null");
- return;
- }
-
- BIGNUM* nRef;
- if (!arrayToBignum(env, njavaBytes, &nRef)) {
- return;
- }
- Unique_BIGNUM n(nRef);
-
- BIGNUM* hRef;
- if (!arrayToBignum(env, hjavaBytes, &hRef)) {
- return;
- }
- Unique_BIGNUM h(hRef);
-
- int ret = EC_GROUP_set_generator(group, point, n.get(), h.get());
- if (ret == 0) {
- throwExceptionIfNecessary(env, "EC_GROUP_set_generator");
- }
-
- JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => %d", group, point, njavaBytes, hjavaBytes, ret);
-}
-
-static jlong NativeCrypto_EC_GROUP_get_generator(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_GROUP_get_generator(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_get_generator(%p) => group == null", group);
- jniThrowNullPointerException(env, "group == null");
- return 0;
- }
-
- const EC_POINT* generator = EC_GROUP_get0_generator(group);
-
- Unique_EC_POINT dup(EC_POINT_dup(generator, group));
- if (dup.get() == NULL) {
- JNI_TRACE("EC_GROUP_get_generator(%p) => oom error", group);
- jniThrowOutOfMemory(env, "unable to dupe generator");
- return 0;
- }
-
- JNI_TRACE("EC_GROUP_get_generator(%p) => %p", group, dup.get());
- return reinterpret_cast<uintptr_t>(dup.release());
-}
-
-static jlong NativeCrypto_EC_POINT_new(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_POINT_new(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_new(%p) => group == null", group);
- jniThrowNullPointerException(env, "group == null");
- return 0;
- }
-
- EC_POINT* point = EC_POINT_new(group);
- if (point == NULL) {
- jniThrowOutOfMemory(env, "Unable create an EC_POINT");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(point);
-}
-
-static void NativeCrypto_EC_POINT_clear_free(JNIEnv* env, jclass, jlong groupRef) {
- EC_POINT* group = reinterpret_cast<EC_POINT*>(groupRef);
- JNI_TRACE("EC_POINT_clear_free(%p)", group);
-
- if (group == NULL) {
- JNI_TRACE("EC_POINT_clear_free => group == NULL");
- jniThrowNullPointerException(env, "group == NULL");
- return;
- }
-
- EC_POINT_clear_free(group);
- JNI_TRACE("EC_POINT_clear_free(%p) => success", group);
-}
-
-static jboolean NativeCrypto_EC_POINT_cmp(JNIEnv* env, jclass, jlong groupRef, jlong point1Ref, jlong point2Ref)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* point1 = reinterpret_cast<const EC_POINT*>(point1Ref);
- const EC_POINT* point2 = reinterpret_cast<const EC_POINT*>(point2Ref);
- JNI_TRACE("EC_POINT_cmp(%p, %p, %p)", group, point1, point2);
-
- if (group == NULL || point1 == NULL || point2 == NULL) {
- JNI_TRACE("EC_POINT_cmp(%p, %p, %p) => group == null || point1 == null || point2 == null",
- group, point1, point2);
- jniThrowNullPointerException(env, "group == null || point1 == null || point2 == null");
- return false;
- }
-
- int ret = EC_POINT_cmp(group, point1, point2, (BN_CTX*)NULL);
-
- JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", point1, point2, ret);
- return ret == 0;
-}
-
-static void NativeCrypto_EC_POINT_set_affine_coordinates(JNIEnv* env, jclass,
- jlong groupRef, jlong pointRef, jbyteArray xjavaBytes, jbyteArray yjavaBytes)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- EC_POINT* point = reinterpret_cast<EC_POINT*>(pointRef);
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p)", group, point, xjavaBytes,
- yjavaBytes);
-
- if (group == NULL || point == NULL) {
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => group == null || point == null",
- group, point, xjavaBytes, yjavaBytes);
- jniThrowNullPointerException(env, "group == null || point == null");
- return;
- }
-
- BIGNUM* xRef;
- if (!arrayToBignum(env, xjavaBytes, &xRef)) {
- return;
- }
- Unique_BIGNUM x(xRef);
-
- BIGNUM* yRef;
- if (!arrayToBignum(env, yjavaBytes, &yRef)) {
- return;
- }
- Unique_BIGNUM y(yRef);
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_POINT_set_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_POINT_set_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid curve type");
- return;
- }
-
- if (ret != 1) {
- throwExceptionIfNecessary(env, "EC_POINT_set_affine_coordinates");
- }
-
- JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => %d", group, point,
- xjavaBytes, yjavaBytes, ret);
-}
-
-static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jclass, jlong groupRef,
- jlong pointRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
-
- Unique_BIGNUM x(BN_new());
- Unique_BIGNUM y(BN_new());
-
- int ret;
- switch (get_EC_GROUP_type(group)) {
- case EC_CURVE_GFP:
- ret = EC_POINT_get_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
- break;
- case EC_CURVE_GF2M:
- ret = EC_POINT_get_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
- break;
- default:
- jniThrowRuntimeException(env, "invalid curve type");
- return NULL;
- }
- if (ret != 1) {
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
- throwExceptionIfNecessary(env, "EC_POINT_get_affine_coordinates");
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- jbyteArray xBytes = bignumToArray(env, x.get(), "x");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 0, xBytes);
-
- jbyteArray yBytes = bignumToArray(env, y.get(), "y");
- if (env->ExceptionCheck()) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, 1, yBytes);
-
- JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p) => %p", group, point, joa);
- return joa;
-}
-
-static jlong NativeCrypto_EC_KEY_generate_key(JNIEnv* env, jclass, jlong groupRef)
-{
- const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
- JNI_TRACE("EC_KEY_generate_key(%p)", group);
-
- Unique_EC_KEY eckey(EC_KEY_new());
- if (eckey.get() == NULL) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_new() oom", group);
- jniThrowOutOfMemory(env, "Unable to create an EC_KEY");
- return 0;
- }
-
- if (EC_KEY_set_group(eckey.get(), group) != 1) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_set_group error", group);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- if (EC_KEY_generate_key(eckey.get()) != 1) {
- JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_generate_key error", group);
- throwExceptionIfNecessary(env, "EC_KEY_set_group");
- return 0;
- }
-
- Unique_EVP_PKEY pkey(EVP_PKEY_new());
- if (pkey.get() == NULL) {
- JNI_TRACE("EC_KEY_generate_key(%p) => threw error", group);
- throwExceptionIfNecessary(env, "EC_KEY_generate_key");
- return 0;
- }
- if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
- jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
- return 0;
- }
- OWNERSHIP_TRANSFERRED(eckey);
-
- JNI_TRACE("EC_KEY_generate_key(%p) => %p", group, pkey.get());
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jlong NativeCrypto_EC_KEY_get0_group(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get0_group(%p)", pkey);
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("EC_KEY_get0_group(%p) => pkey == null", pkey);
- return 0;
- }
-
- if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
- jniThrowRuntimeException(env, "not EC key");
- JNI_TRACE("EC_KEY_get0_group(%p) => not EC key (type == %d)", pkey,
- EVP_PKEY_type(pkey->type));
- return 0;
- }
-
- const EC_GROUP* group = EC_KEY_get0_group(pkey->pkey.ec);
- JNI_TRACE("EC_KEY_get0_group(%p) => %p", pkey, group);
- return reinterpret_cast<uintptr_t>(group);
-}
-
-static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get_private_key(%p)", pkey);
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
- return NULL;
- }
-
- const BIGNUM *privkey = EC_KEY_get0_private_key(eckey.get());
-
- jbyteArray privBytes = bignumToArray(env, privkey, "privkey");
- if (env->ExceptionCheck()) {
- JNI_TRACE("EC_KEY_get_private_key(%p) => threw error", pkey);
- return NULL;
- }
-
- JNI_TRACE("EC_KEY_get_private_key(%p) => %p", pkey, privBytes);
- return privBytes;
-}
-
-static jlong NativeCrypto_EC_KEY_get_public_key(JNIEnv* env, jclass, jlong pkeyRef)
-{
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EC_KEY_get_public_key(%p)", pkey);
-
- Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
- if (eckey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
- return 0;
- }
-
- Unique_EC_POINT dup(EC_POINT_dup(EC_KEY_get0_public_key(eckey.get()),
- EC_KEY_get0_group(eckey.get())));
- if (dup.get() == NULL) {
- JNI_TRACE("EC_KEY_get_public_key(%p) => can't dup public key", pkey);
- jniThrowRuntimeException(env, "EC_POINT_dup");
- return 0;
- }
-
- JNI_TRACE("EC_KEY_get_public_key(%p) => %p", pkey, dup.get());
- return reinterpret_cast<uintptr_t>(dup.release());
-}
-
-static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass,
- jbyteArray outArray, jint outOffset, jlong pubkeyRef, jlong privkeyRef)
-{
- EVP_PKEY* pubPkey = reinterpret_cast<EVP_PKEY*>(pubkeyRef);
- EVP_PKEY* privPkey = reinterpret_cast<EVP_PKEY*>(privkeyRef);
- JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p)", outArray, outOffset, pubPkey, privPkey);
-
- ScopedByteArrayRW out(env, outArray);
- if (out.get() == NULL) {
- JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p) can't get output buffer",
- outArray, outOffset, pubPkey, privPkey);
- return -1;
- }
-
- if ((outOffset < 0) || ((size_t) outOffset >= out.size())) {
- jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
- return -1;
- }
-
- Unique_EC_KEY pubkey(EVP_PKEY_get1_EC_KEY(pubPkey));
- if (pubkey.get() == NULL) {
- JNI_TRACE("ECDH_compute_key(%p) => can't get public key", pubPkey);
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
- return -1;
- }
-
- const EC_POINT* pubkeyPoint = EC_KEY_get0_public_key(pubkey.get());
- if (pubkeyPoint == NULL) {
- JNI_TRACE("ECDH_compute_key(%p) => can't get public key point", pubPkey);
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
- return -1;
- }
-
- Unique_EC_KEY privkey(EVP_PKEY_get1_EC_KEY(privPkey));
- if (privkey.get() == NULL) {
- throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY private");
- return -1;
- }
-
- int outputLength = ECDH_compute_key(
- &out[outOffset],
- out.size() - outOffset,
- pubkeyPoint,
- privkey.get(),
- NULL // No KDF
- );
- if (outputLength == -1) {
- throwExceptionIfNecessary(env, "ECDH_compute_key");
- return -1;
- }
-
- return outputLength;
-}
-
-static jlong NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
- JNI_TRACE("EVP_MD_CTX_create()");
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable create a EVP_MD_CTX");
- return 0;
- }
-
- JNI_TRACE("EVP_MD_CTX_create() => %p", ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-static void NativeCrypto_EVP_MD_CTX_init(JNIEnv*, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_init(%p)", ctx);
-
- if (ctx != NULL) {
- EVP_MD_CTX_init(ctx);
- }
-}
-
-static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
-
- if (ctx != NULL) {
- EVP_MD_CTX_destroy(ctx);
- }
-}
-
-static jlong NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- return 0;
- }
-
- EVP_MD_CTX* copy = EVP_MD_CTX_create();
- if (copy == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate copy of EVP_MD_CTX");
- return 0;
- }
-
- EVP_MD_CTX_init(copy);
- int result = EVP_MD_CTX_copy_ex(copy, ctx);
- if (result == 0) {
- EVP_MD_CTX_destroy(copy);
- jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
- freeOpenSslErrorState();
- return 0;
- }
-
- JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
- return reinterpret_cast<uintptr_t>(copy);
-}
-
-/*
- * public static native int EVP_DigestFinal(int, byte[], int)
- */
-static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray hash, jint offset) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
-
- if (ctx == NULL || hash == NULL) {
- jniThrowNullPointerException(env, "ctx == null || hash == null");
- return -1;
- }
-
- ScopedByteArrayRW hashBytes(env, hash);
- if (hashBytes.get() == NULL) {
- return -1;
- }
- unsigned int bytesWritten = -1;
- int ok = EVP_DigestFinal(ctx,
- reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
- &bytesWritten);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal");
- }
- EVP_MD_CTX_destroy(ctx);
-
- JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, bytesWritten);
- return bytesWritten;
-}
-
-/*
- * public static native int EVP_DigestInit(int)
- */
-static jlong NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jlong evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_DigestInit(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_DigestInit ctx=%p", ctx.get());
-
- int ok = EVP_DigestInit(ctx.get(), evp_md);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit");
- if (exception) {
- return 0;
- }
- }
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native int EVP_get_digestbyname(java.lang.String)
- */
-static jlong NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s)", algorithmChars.c_str());
-
- const EVP_MD* evp_md = EVP_get_digestbyname(algorithmChars.c_str());
- if (evp_md == NULL) {
- jniThrowRuntimeException(env, "Hash algorithm not found");
- return 0;
- }
-
- JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %p", algorithmChars.c_str(), evp_md);
- return reinterpret_cast<uintptr_t>(evp_md);
-}
-
-/*
- * public static native int EVP_MD_size(int)
- */
-static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, jint evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_MD_size(evp_md);
- JNI_TRACE("NativeCrypto_EVP_MD_size(%p) => %d", evp_md, result);
- return result;
-}
-
-/*
- * public static int void EVP_MD_block_size(int)
- */
-static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, jlong evpMdRef) {
- EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
- JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md);
-
- if (evp_md == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- int result = EVP_MD_block_size(evp_md);
- JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p) => %d", evp_md, result);
- return result;
-}
-
-/*
- * public static native void EVP_DigestUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (offset < 0 || length < 0) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
- return;
- }
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_DigestUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate");
- }
-}
-
-static void NativeCrypto_EVP_DigestSignInit(JNIEnv* env, jclass, jlong evpMdCtxRef,
- const jlong evpMdRef, jlong pkeyRef) {
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- const EVP_MD* md = reinterpret_cast<const EVP_MD*>(evpMdRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("EVP_DigestSignInit(%p, %p, %p)", mdCtx, md, pkey);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return;
- }
-
- if (md == NULL) {
- jniThrowNullPointerException(env, "md == null");
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- return;
- }
-
- if (EVP_DigestSignInit(mdCtx, (EVP_PKEY_CTX **) NULL, md, (ENGINE *) NULL, pkey) <= 0) {
- JNI_TRACE("ctx=%p EVP_DigestSignInit => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignInit");
- return;
- }
-
- JNI_TRACE("EVP_DigestSignInit(%p, %p, %p) => success", mdCtx, md, pkey);
-}
-
-static void NativeCrypto_EVP_DigestSignUpdate(JNIEnv* env, jclass, jint evpMdCtxRef,
- jbyteArray inJavaBytes, jint inOffset, jint inLength)
-{
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- JNI_TRACE("EVP_DigestSignUpdate(%p, %p, %d, %d)", mdCtx, inJavaBytes, inOffset, inLength);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return;
- }
-
- ScopedByteArrayRO inBytes(env, inJavaBytes);
- if (inBytes.get() == NULL) {
- return;
- }
-
- if (inOffset < 0 || size_t(inOffset) > inBytes.size()) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "inOffset");
- return;
- }
-
- const ssize_t inEnd = inOffset + inLength;
- if (inEnd < 0 || size_t(inEnd) >= inBytes.size()) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "inLength");
- return;
- }
-
- const unsigned char *tmp = reinterpret_cast<const unsigned char *>(inBytes.get());
- if (!EVP_DigestSignUpdate(mdCtx, tmp + inOffset, inLength)) {
- JNI_TRACE("ctx=%p EVP_DigestSignUpdate => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignUpdate");
- }
-
- JNI_TRACE("EVP_DigestSignUpdate(%p, %p, %d, %d) => success", mdCtx, inJavaBytes, inOffset,
- inLength);
-}
-
-static jbyteArray NativeCrypto_EVP_DigestSignFinal(JNIEnv* env, jclass, jlong evpMdCtxRef)
-{
- EVP_MD_CTX* mdCtx = reinterpret_cast<EVP_MD_CTX*>(evpMdCtxRef);
- JNI_TRACE("EVP_DigestSignFinal(%p)", mdCtx);
-
- if (mdCtx == NULL) {
- jniThrowNullPointerException(env, "mdCtx == null");
- return NULL;
- }
-
- const size_t expectedSize = EVP_MD_CTX_size(mdCtx);
- ScopedLocalRef<jbyteArray> outJavaBytes(env, env->NewByteArray(expectedSize));
- if (outJavaBytes.get() == NULL) {
- return NULL;
- }
- ScopedByteArrayRW outBytes(env, outJavaBytes.get());
- if (outBytes.get() == NULL) {
- return NULL;
- }
- unsigned char *tmp = reinterpret_cast<unsigned char*>(outBytes.get());
- size_t len;
- if (!EVP_DigestSignFinal(mdCtx, tmp, &len)) {
- JNI_TRACE("ctx=%p EVP_DigestSignFinal => threw exception", mdCtx);
- throwExceptionIfNecessary(env, "EVP_DigestSignFinal");
- return 0;
- }
-
- if (len != expectedSize) {
- jniThrowRuntimeException(env, "hash size unexpected");
- return 0;
- }
-
- JNI_TRACE("EVP_DigestSignFinal(%p) => %p", mdCtx, outJavaBytes.get());
- return outJavaBytes.release();
-}
-
-static jlong NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_SignInit ctx=%p", ctx.get());
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_SignInit algorithmChars=%s", algorithmChars.c_str());
-
- const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
- if (digest == NULL) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => hash not found", algorithmChars.c_str());
- throwExceptionIfNecessary(env, "Hash algorithm not found");
- return 0;
- }
-
- int ok = EVP_SignInit(ctx.get(), digest);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignInit");
- if (exception) {
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => threw exception", algorithmChars.c_str());
- return 0;
- }
- }
-
- JNI_TRACE("NativeCrypto_EVP_SignInit(%s) => %p", algorithmChars.c_str(), ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native void EVP_SignUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_SignUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_SignUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignUpdate");
- }
-}
-
-/*
- * public static native int EVP_SignFinal(int, byte[], int, int)
- */
-static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray signature,
- jint offset, jlong pkeyRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p)", ctx, signature, offset, pkey);
-
- if (ctx == NULL || pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedByteArrayRW signatureBytes(env, signature);
- if (signatureBytes.get() == NULL) {
- return -1;
- }
- unsigned int bytesWritten = -1;
- int ok = EVP_SignFinal(ctx,
- reinterpret_cast<unsigned char*>(signatureBytes.get() + offset),
- &bytesWritten,
- pkey);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignFinal");
- }
- JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p) => %u",
- ctx, signature, offset, pkey, bytesWritten);
-
- return bytesWritten;
-}
-
-/*
- * public static native int EVP_VerifyInit(java.lang.String)
- */
-static jlong NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p)", algorithm);
-
- if (algorithm == NULL) {
- jniThrowNullPointerException(env, NULL);
- return 0;
- }
-
- Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate EVP_MD_CTX");
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_VerifyInit ctx=%p", ctx.get());
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("NativeCrypto_EVP_VerifyInit algorithmChars=%s", algorithmChars.c_str());
-
- const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
- if (digest == NULL) {
- jniThrowRuntimeException(env, "Hash algorithm not found");
- return 0;
- }
-
- int ok = EVP_VerifyInit(ctx.get(), digest);
- if (ok == 0) {
- bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit");
- if (exception) {
- return 0;
- }
- }
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-/*
- * public static native void EVP_VerifyUpdate(int, byte[], int, int)
- */
-static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jlong ctxRef,
- jbyteArray buffer, jint offset, jint length) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
-
- if (ctx == NULL || buffer == NULL) {
- jniThrowNullPointerException(env, NULL);
- return;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return;
- }
- int ok = EVP_VerifyUpdate(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length);
- if (ok == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
- }
-}
-
-/*
- * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
- */
-static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jlong ctxRef, jbyteArray buffer,
- jint offset, jint length, jlong pkeyRef) {
- EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
- ctx, buffer, offset, length, pkey);
-
- if (ctx == NULL || buffer == NULL || pkey == NULL) {
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedByteArrayRO bufferBytes(env, buffer);
- if (bufferBytes.get() == NULL) {
- return -1;
- }
- int ok = EVP_VerifyFinal(ctx,
- reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
- length,
- pkey);
- if (ok < 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
- }
-
- /*
- * For DSA keys, OpenSSL appears to have a bug where it returns
- * errors for any result != 1. See dsa_ossl.c in dsa_do_verify
- */
- freeOpenSslErrorState();
-
- JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
- ctx, buffer, offset, length, pkey, ok);
-
- return ok;
-}
-
-static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
- JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
- if (algorithm == NULL) {
- JNI_TRACE("EVP_get_cipherbyname(%p) => threw exception algorithm == null", algorithm);
- jniThrowNullPointerException(env, NULL);
- return -1;
- }
-
- ScopedUtfChars algorithmChars(env, algorithm);
- if (algorithmChars.c_str() == NULL) {
- return 0;
- }
- JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm = %s", algorithm, algorithmChars.c_str());
-
- const EVP_CIPHER* evp_cipher = EVP_get_cipherbyname(algorithmChars.c_str());
- if (evp_cipher == NULL) {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("EVP_get_cipherbyname(%s) => %p", algorithmChars.c_str(), evp_cipher);
- return reinterpret_cast<uintptr_t>(evp_cipher);
-}
-
-static void NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jlong ctxRef, jlong evpCipherRef,
- jbyteArray keyArray, jbyteArray ivArray, jboolean encrypting) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
- JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d)", ctx, evpCipher, keyArray, ivArray,
- encrypting ? 1 : 0);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("EVP_CipherUpdate => ctx == null");
- return;
- }
-
- // The key can be null if we need to set extra parameters.
- UniquePtr<unsigned char[]> keyPtr;
- if (keyArray != NULL) {
- ScopedByteArrayRO keyBytes(env, keyArray);
- if (keyBytes.get() == NULL) {
- return;
- }
-
- keyPtr.reset(new unsigned char[keyBytes.size()]);
- memcpy(keyPtr.get(), keyBytes.get(), keyBytes.size());
- }
-
- // The IV can be null if we're using ECB.
- UniquePtr<unsigned char[]> ivPtr;
- if (ivArray != NULL) {
- ScopedByteArrayRO ivBytes(env, ivArray);
- if (ivBytes.get() == NULL) {
- return;
- }
-
- ivPtr.reset(new unsigned char[ivBytes.size()]);
- memcpy(ivPtr.get(), ivBytes.get(), ivBytes.size());
- }
-
- if (!EVP_CipherInit_ex(ctx, evpCipher, NULL, keyPtr.get(), ivPtr.get(), encrypting ? 1 : 0)) {
- throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
- JNI_TRACE("EVP_CipherInit_ex => error initializing cipher");
- return;
- }
-
- JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d) => success", ctx, evpCipher, keyArray, ivArray,
- encrypting ? 1 : 0);
-}
-
-/*
- * public static native int EVP_CipherUpdate(int ctx, byte[] out, int outOffset, byte[] in,
- * int inOffset);
- */
-static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
- jint outOffset, jbyteArray inArray, jint inOffset, jint inLength) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d)", ctx, outArray, outOffset, inArray, inOffset);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CipherUpdate => ctx == null", ctx);
- return 0;
- }
-
- ScopedByteArrayRO inBytes(env, inArray);
- if (inBytes.get() == NULL) {
- return 0;
- }
- const size_t inSize = inBytes.size();
- if (size_t(inOffset + inLength) > inSize) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "in.length < (inSize + inOffset)");
- return 0;
- }
-
- ScopedByteArrayRW outBytes(env, outArray);
- if (outBytes.get() == NULL) {
- return 0;
- }
- const size_t outSize = outBytes.size();
- if (size_t(outOffset + inLength) > outSize) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "out.length < inSize + outOffset + blockSize - 1");
- return 0;
- }
-
- JNI_TRACE("ctx=%p EVP_CipherUpdate in=%p in.length=%d inOffset=%d inLength=%d out=%p out.length=%d outOffset=%d",
- ctx, inBytes.get(), inBytes.size(), inOffset, inLength, outBytes.get(), outBytes.size(), outOffset);
-
- unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
- const unsigned char* in = reinterpret_cast<const unsigned char*>(inBytes.get());
-
- int outl;
- if (!EVP_CipherUpdate(ctx, out + outOffset, &outl, in + inOffset, inLength)) {
- throwExceptionIfNecessary(env, "EVP_CipherUpdate");
- JNI_TRACE("ctx=%p EVP_CipherUpdate => threw error", ctx);
- return 0;
- }
-
- JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d) => %d", ctx, outArray, outOffset, inArray,
- inOffset, outl);
- return outl;
-}
-
-static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
- jint outOffset) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CipherFinal_ex(%p, %p, %d)", ctx, outArray, outOffset);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CipherFinal_ex => ctx == null", ctx);
- return 0;
- }
-
- ScopedByteArrayRW outBytes(env, outArray);
- if (outBytes.get() == NULL) {
- return 0;
- }
-
- unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
-
- int outl;
- if (!EVP_CipherFinal_ex(ctx, out + outOffset, &outl)) {
- throwExceptionIfNecessary(env, "EVP_CipherFinal_ex");
- JNI_TRACE("ctx=%p EVP_CipherFinal_ex => threw error", ctx);
- return 0;
- }
-
- JNI_TRACE("EVP_CipherFinal(%p, %p, %d) => %d", ctx, outArray, outOffset, outl);
- return outl;
-}
-
-static jint NativeCrypto_EVP_CIPHER_iv_length(JNIEnv* env, jclass, jlong evpCipherRef) {
- const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
- JNI_TRACE("EVP_CIPHER_iv_length(%p)", evpCipher);
-
- if (evpCipher == NULL) {
- jniThrowNullPointerException(env, "evpCipher == null");
- JNI_TRACE("EVP_CIPHER_iv_length => evpCipher == null");
- return 0;
- }
-
- const int ivLength = EVP_CIPHER_iv_length(evpCipher);
- JNI_TRACE("EVP_CIPHER_iv_length(%p) => %d", evpCipher, ivLength);
- return ivLength;
-}
-
-static jlong NativeCrypto_EVP_CIPHER_CTX_new(JNIEnv* env, jclass) {
- JNI_TRACE("EVP_CIPHER_CTX_new()");
-
- Unique_EVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
- if (ctx.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate cipher context");
- JNI_TRACE("EVP_CipherInit_ex => context allocation error");
- return 0;
- }
-
- JNI_TRACE("EVP_CIPHER_CTX_new() => %p", ctx.get());
- return reinterpret_cast<uintptr_t>(ctx.release());
-}
-
-static jint NativeCrypto_EVP_CIPHER_CTX_block_size(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_block_size(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_block_size => ctx == null", ctx);
- return 0;
- }
-
- int blockSize = EVP_CIPHER_CTX_block_size(ctx);
- JNI_TRACE("EVP_CIPHER_CTX_block_size(%p) => %d", ctx, blockSize);
- return blockSize;
-}
-
-static jint NativeCrypto_get_EVP_CIPHER_CTX_buf_len(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p)", ctx);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p get_EVP_CIPHER_CTX_buf_len => ctx == null", ctx);
- return 0;
- }
-
- int buf_len = ctx->buf_len;
- JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p) => %d", ctx, buf_len);
- return buf_len;
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_set_padding(JNIEnv* env, jclass, jlong ctxRef, jboolean enablePaddingBool) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- jint enablePadding = enablePaddingBool ? 1 : 0;
- JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d)", ctx, enablePadding);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_padding => ctx == null", ctx);
- return;
- }
-
- EVP_CIPHER_CTX_set_padding(ctx, enablePadding); // Not void, but always returns 1.
- JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d) => success", ctx, enablePadding);
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_set_key_length(JNIEnv* env, jclass, jlong ctxRef,
- jint keySizeBits) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d)", ctx, keySizeBits);
-
- if (ctx == NULL) {
- jniThrowNullPointerException(env, "ctx == null");
- JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_key_length => ctx == null", ctx);
- return;
- }
-
- if (!EVP_CIPHER_CTX_set_key_length(ctx, keySizeBits)) {
- throwExceptionIfNecessary(env, "NativeCrypto_EVP_CIPHER_CTX_set_key_length");
- JNI_TRACE("NativeCrypto_EVP_CIPHER_CTX_set_key_length => threw error");
- return;
- }
- JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d) => success", ctx, keySizeBits);
-}
-
-static void NativeCrypto_EVP_CIPHER_CTX_cleanup(JNIEnv* env, jclass, jlong ctxRef) {
- EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
- JNI_TRACE("EVP_CIPHER_CTX_cleanup(%p)", ctx);
-
- if (ctx != NULL) {
- if (!EVP_CIPHER_CTX_cleanup(ctx)) {
- throwExceptionIfNecessary(env, "EVP_CIPHER_CTX_cleanup");
- JNI_TRACE("EVP_CIPHER_CTX_cleanup => threw error");
- return;
- }
- }
- JNI_TRACE("EVP_CIPHER_CTX_cleanup(%p) => success", ctx);
-}
-
-/**
- * public static native void RAND_seed(byte[]);
- */
-static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
- JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
- ScopedByteArrayRO randseed(env, seed);
- if (randseed.get() == NULL) {
- return;
- }
- RAND_seed(randseed.get(), randseed.size());
-}
-
-static jint NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
- JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
- ScopedUtfChars file(env, filename);
- if (file.c_str() == NULL) {
- return -1;
- }
- int result = RAND_load_file(file.c_str(), max_bytes);
- JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
- return result;
-}
-
-static void NativeCrypto_RAND_bytes(JNIEnv* env, jclass, jbyteArray output) {
- JNI_TRACE("NativeCrypto_RAND_bytes(%p)", output);
-
- ScopedByteArrayRW outputBytes(env, output);
- if (outputBytes.get() == NULL) {
- return;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(outputBytes.get());
- if (RAND_bytes(tmp, outputBytes.size()) <= 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_RAND_bytes");
- JNI_TRACE("tmp=%p NativeCrypto_RAND_bytes => threw error", tmp);
- return;
- }
-
- JNI_TRACE("NativeCrypto_RAND_bytes(%p) => success", output);
-}
-
-static jint NativeCrypto_OBJ_txt2nid(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return 0;
- }
-
- int nid = OBJ_txt2nid(oid.c_str());
- JNI_TRACE("OBJ_txt2nid(%s) => %d", oid.c_str(), nid);
- return nid;
-}
-
-static jstring NativeCrypto_OBJ_txt2nid_longName(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid_longName(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- JNI_TRACE("OBJ_txt2nid_longName(%s)", oid.c_str());
-
- int nid = OBJ_txt2nid(oid.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("OBJ_txt2nid_longName(%s) => NID_undef", oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- const char* longName = OBJ_nid2ln(nid);
- JNI_TRACE("OBJ_txt2nid_longName(%s) => %s", oid.c_str(), longName);
- return env->NewStringUTF(longName);
-}
-
-static jstring ASN1_OBJECT_to_OID_string(JNIEnv* env, ASN1_OBJECT* obj) {
- /*
- * The OBJ_obj2txt API doesn't "measure" if you pass in NULL as the buffer.
- * Just make a buffer that's large enough here. The documentation recommends
- * 80 characters.
- */
- char output[128];
- int ret = OBJ_obj2txt(output, sizeof(output), obj, 1);
- if (ret < 0) {
- throwExceptionIfNecessary(env, "ASN1_OBJECT_to_OID_string");
- return NULL;
- } else if (size_t(ret) >= sizeof(output)) {
- jniThrowRuntimeException(env, "ASN1_OBJECT_to_OID_string buffer too small");
- return NULL;
- }
-
- JNI_TRACE("ASN1_OBJECT_to_OID_string(%p) => %s", obj, output);
- return env->NewStringUTF(output);
-}
-
-static jlong NativeCrypto_create_BIO_InputStream(JNIEnv* env, jclass, jobject streamObj) {
- JNI_TRACE("create_BIO_InputStream(%p)", streamObj);
-
- if (streamObj == NULL) {
- jniThrowNullPointerException(env, "stream == null");
- return 0;
- }
-
- Unique_BIO bio(BIO_new(&stream_bio_method));
- if (bio.get() == NULL) {
- return 0;
- }
-
- bio_stream_assign(bio.get(), new BIO_InputStream(streamObj));
-
- JNI_TRACE("create_BIO_InputStream(%p) => %p", streamObj, bio.get());
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
-}
-
-static jlong NativeCrypto_create_BIO_OutputStream(JNIEnv* env, jclass, jobject streamObj) {
- JNI_TRACE("create_BIO_OutputStream(%p)", streamObj);
-
- if (streamObj == NULL) {
- jniThrowNullPointerException(env, "stream == null");
- return 0;
- }
-
- Unique_BIO bio(BIO_new(&stream_bio_method));
- if (bio.get() == NULL) {
- return 0;
- }
-
- bio_stream_assign(bio.get(), new BIO_OutputStream(streamObj));
-
- JNI_TRACE("create_BIO_OutputStream(%p) => %p", streamObj, bio.get());
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
-}
-
-static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_read(%p, %p)", bio, outputJavaBytes);
-
- if (outputJavaBytes == NULL) {
- jniThrowNullPointerException(env, "output == null");
- JNI_TRACE("BIO_read(%p, %p) => output == null", bio, outputJavaBytes);
- return 0;
- }
-
- int outputSize = env->GetArrayLength(outputJavaBytes);
-
- UniquePtr<unsigned char[]> buffer(new unsigned char[outputSize]);
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate buffer for read");
- return 0;
- }
-
- int read = BIO_read(bio, buffer.get(), outputSize);
- if (read <= 0) {
- jniThrowException(env, "java/io/IOException", "BIO_read");
- JNI_TRACE("BIO_read(%p, %p) => threw IO exception", bio, outputJavaBytes);
- return 0;
- }
-
- env->SetByteArrayRegion(outputJavaBytes, 0, read, reinterpret_cast<jbyte*>(buffer.get()));
- JNI_TRACE("BIO_read(%p, %p) => %d", bio, outputJavaBytes, read);
- return read;
-}
-
-static void NativeCrypto_BIO_write(JNIEnv* env, jclass, jlong bioRef, jbyteArray inputJavaBytes,
- jint offset, jint length) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_write(%p, %p, %d, %d)", bio, inputJavaBytes, offset, length);
-
- if (inputJavaBytes == NULL) {
- jniThrowNullPointerException(env, "input == null");
- return;
- }
-
- if (offset < 0 || length < 0) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException", "offset < 0 || length < 0");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
- return;
- }
-
- int inputSize = env->GetArrayLength(inputJavaBytes);
- if (inputSize < offset + length) {
- jniThrowException(env, "java/lang/IndexOutOfBoundsException",
- "input.length < offset + length");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
- return;
- }
-
- UniquePtr<unsigned char[]> buffer(new unsigned char[length]);
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate buffer for write");
- return;
- }
-
- env->GetByteArrayRegion(inputJavaBytes, offset, length, reinterpret_cast<jbyte*>(buffer.get()));
- if (BIO_write(bio, buffer.get(), length) != length) {
- freeOpenSslErrorState();
- jniThrowException(env, "java/io/IOException", "BIO_write");
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => IO error", bio, inputJavaBytes, offset, length);
- return;
- }
-
- JNI_TRACE("BIO_write(%p, %p, %d, %d) => success", bio, inputJavaBytes, offset, length);
-}
-
-static void NativeCrypto_BIO_free(JNIEnv* env, jclass, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("BIO_free(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- return;
- }
-
- BIO_free(bio);
-}
-
-static jstring X509_NAME_to_jstring(JNIEnv* env, X509_NAME* name, unsigned long flags) {
- JNI_TRACE("X509_NAME_to_jstring(%p)", name);
-
- Unique_BIO buffer(BIO_new(BIO_s_mem()));
- if (buffer.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate BIO");
- JNI_TRACE("X509_NAME_to_jstring(%p) => threw error", name);
- return NULL;
- }
-
- /* Don't interpret the string. */
- flags &= ~(ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_MSB);
-
- /* Write in given format and null terminate. */
- X509_NAME_print_ex(buffer.get(), name, 0, flags);
- BIO_write(buffer.get(), "\0", 1);
-
- char *tmp;
- BIO_get_mem_data(buffer.get(), &tmp);
- JNI_TRACE("X509_NAME_to_jstring(%p) => \"%s\"", name, tmp);
- return env->NewStringUTF(tmp);
-}
-
-
-/**
- * Converts GENERAL_NAME items to the output format expected in
- * X509Certificate#getSubjectAlternativeNames and
- * X509Certificate#getIssuerAlternativeNames return.
- */
-static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) {
- switch (gen->type) {
- case GEN_EMAIL:
- case GEN_DNS:
- case GEN_URI: {
- // This must not be a T61String and must not contain NULLs.
- const char* data = reinterpret_cast<const char*>(ASN1_STRING_data(gen->d.ia5));
- ssize_t len = ASN1_STRING_length(gen->d.ia5);
- if ((len == static_cast<ssize_t>(strlen(data)))
- && (ASN1_PRINTABLE_type(ASN1_STRING_data(gen->d.ia5), len) != V_ASN1_T61STRING)) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI \"%s\"", gen, data);
- return env->NewStringUTF(data);
- } else {
- jniThrowException(env, "java/security/cert/CertificateParsingException",
- "Invalid dNSName encoding");
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI invalid", gen);
- return NULL;
- }
- }
- case GEN_DIRNAME:
- /* Write in RFC 2253 format */
- return X509_NAME_to_jstring(env, gen->d.directoryName, XN_FLAG_RFC2253);
- case GEN_IPADD: {
- const void *ip = reinterpret_cast<const void *>(gen->d.ip->data);
- if (gen->d.ip->length == 4) {
- // IPv4
- UniquePtr<char[]> buffer(new char[INET_ADDRSTRLEN]);
- if (inet_ntop(AF_INET, ip, buffer.get(), INET_ADDRSTRLEN) != NULL) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 %s", gen, buffer.get());
- return env->NewStringUTF(buffer.get());
- } else {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 failed %s", gen, strerror(errno));
- }
- } else if (gen->d.ip->length == 16) {
- // IPv6
- UniquePtr<char[]> buffer(new char[INET6_ADDRSTRLEN]);
- if (inet_ntop(AF_INET6, ip, buffer.get(), INET6_ADDRSTRLEN) != NULL) {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 %s", gen, buffer.get());
- return env->NewStringUTF(buffer.get());
- } else {
- JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 failed %s", gen, strerror(errno));
- }
- }
-
- /* Invalid IP encodings are pruned out without throwing an exception. */
- return NULL;
- }
- case GEN_RID:
- return ASN1_OBJECT_to_OID_string(env, gen->d.registeredID);
- case GEN_OTHERNAME:
- case GEN_X400:
- default:
- return ASN1ToByteArray<GENERAL_NAME, i2d_GENERAL_NAME>(env, gen);
- }
-
- return NULL;
-}
-
-#define GN_STACK_SUBJECT_ALT_NAME 1
-#define GN_STACK_ISSUER_ALT_NAME 2
-
-static jobjectArray NativeCrypto_get_X509_GENERAL_NAME_stack(JNIEnv* env, jclass, jlong x509Ref,
- jint type) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d)", x509, type);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => x509 == null", x509, type);
- return NULL;
- }
-
- X509_check_ca(x509);
-
- STACK_OF(GENERAL_NAME)* gn_stack;
- Unique_sk_GENERAL_NAME stackHolder;
- if (type == GN_STACK_SUBJECT_ALT_NAME) {
- gn_stack = x509->altname;
- } else if (type == GN_STACK_ISSUER_ALT_NAME) {
- stackHolder.reset(
- static_cast<STACK_OF(GENERAL_NAME)*>(X509_get_ext_d2i(x509, NID_issuer_alt_name,
- NULL, NULL)));
- gn_stack = stackHolder.get();
- } else {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => unknown type", x509, type);
- return NULL;
- }
-
- int count = sk_GENERAL_NAME_num(gn_stack);
- if (count <= 0) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => null (no entries)", x509, type);
- return NULL;
- }
-
- /*
- * Keep track of how many originally so we can ignore any invalid
- * values later.
- */
- const int origCount = count;
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, objectArrayClass, NULL));
- for (int i = 0, j = 0; i < origCount; i++, j++) {
- GENERAL_NAME* gen = sk_GENERAL_NAME_value(gn_stack, i);
- ScopedLocalRef<jobject> val(env, GENERAL_NAME_to_jobject(env, gen));
- if (env->ExceptionCheck()) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => threw exception parsing gen name",
- x509, type);
- return NULL;
- }
-
- /*
- * If it's NULL, we'll have to skip this, reduce the number of total
- * entries, and fix up the array later.
- */
- if (val.get() == NULL) {
- j--;
- count--;
- continue;
- }
-
- ScopedLocalRef<jobjectArray> item(env, env->NewObjectArray(2, objectClass, NULL));
-
- ScopedLocalRef<jobject> type(env, env->CallStaticObjectMethod(integerClass,
- integer_valueOfMethod, gen->type));
- env->SetObjectArrayElement(item.get(), 0, type.get());
- env->SetObjectArrayElement(item.get(), 1, val.get());
-
- env->SetObjectArrayElement(joa.get(), j, item.get());
- }
-
- if (count == 0) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to 0; returning NULL",
- x509, type, origCount);
- joa.reset(NULL);
- } else if (origCount != count) {
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to %d", x509, type,
- origCount, count);
-
- ScopedLocalRef<jobjectArray> joa_copy(env, env->NewObjectArray(count, objectArrayClass,
- NULL));
-
- for (int i = 0; i < count; i++) {
- ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(joa.get(), i));
- env->SetObjectArrayElement(joa_copy.get(), i, item.get());
- }
-
- joa.reset(joa_copy.release());
- }
-
- JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => %d entries", x509, type, count);
- return joa.release();
-}
-
-static jlong NativeCrypto_X509_get_notBefore(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_notBefore(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_notBefore(%p) => x509 == null", x509);
- return 0;
- }
-
- ASN1_TIME* notBefore = X509_get_notBefore(x509);
- JNI_TRACE("X509_get_notBefore(%p) => %p", x509, notBefore);
- return reinterpret_cast<uintptr_t>(notBefore);
-}
-
-static jlong NativeCrypto_X509_get_notAfter(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_notAfter(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_notAfter(%p) => x509 == null", x509);
- return 0;
- }
-
- ASN1_TIME* notAfter = X509_get_notAfter(x509);
- JNI_TRACE("X509_get_notAfter(%p) => %p", x509, notAfter);
- return reinterpret_cast<uintptr_t>(notAfter);
-}
-
-static long NativeCrypto_X509_get_version(JNIEnv*, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_version(%p)", x509);
-
- long version = X509_get_version(x509);
- JNI_TRACE("X509_get_version(%p) => %ld", x509, version);
- return version;
-}
-
-template<typename T>
-static jbyteArray get_X509Type_serialNumber(JNIEnv* env, T* x509Type, ASN1_INTEGER* (*get_serial_func)(T*)) {
- JNI_TRACE("get_X509Type_serialNumber(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509Type == null");
- JNI_TRACE("get_X509Type_serialNumber(%p) => x509Type == null", x509Type);
- return NULL;
- }
-
- ASN1_INTEGER* serialNumber = get_serial_func(x509Type);
- Unique_BIGNUM serialBn(ASN1_INTEGER_to_BN(serialNumber, NULL));
- if (serialBn.get() == NULL) {
- JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> serialArray(env, bignumToArray(env, serialBn.get(), "serialBn"));
- if (env->ExceptionCheck()) {
- JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
- return NULL;
- }
-
- JNI_TRACE("X509_get_serialNumber(%p) => %p", x509Type, serialArray.get());
- return serialArray.release();
-}
-
-/* OpenSSL includes set_serialNumber but not get. */
-#if !defined(X509_REVOKED_get_serialNumber)
-static ASN1_INTEGER* X509_REVOKED_get_serialNumber(X509_REVOKED* x) {
- return x->serialNumber;
-}
-#endif
-
-static jbyteArray NativeCrypto_X509_get_serialNumber(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_serialNumber(%p)", x509);
- return get_X509Type_serialNumber<X509>(env, x509, X509_get_serialNumber);
-}
-
-static jbyteArray NativeCrypto_X509_REVOKED_get_serialNumber(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_serialNumber(%p)", revoked);
- return get_X509Type_serialNumber<X509_REVOKED>(env, revoked, X509_REVOKED_get_serialNumber);
-}
-
-static void NativeCrypto_X509_verify(JNIEnv* env, jclass, jlong x509Ref, jlong pkeyRef) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("X509_verify(%p, %p)", x509, pkey);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_verify(%p, %p) => x509 == null", x509, pkey);
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("X509_verify(%p, %p) => pkey == null", x509, pkey);
- return;
- }
-
- if (X509_verify(x509, pkey) != 1) {
- throwExceptionIfNecessary(env, "X509_verify");
- JNI_TRACE("X509_verify(%p, %p) => verify failure", x509, pkey);
- } else {
- JNI_TRACE("X509_verify(%p, %p) => verify success", x509, pkey);
- }
-}
-
-static jbyteArray NativeCrypto_get_X509_cert_info_enc(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_cert_info_enc(%p)", x509);
- return ASN1ToByteArray<X509_CINF, i2d_X509_CINF>(env, x509->cert_info);
-}
-
-static jint NativeCrypto_get_X509_ex_flags(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_flags(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_flags(%p) => x509 == null", x509);
- return 0;
- }
-
- X509_check_ca(x509);
-
- return x509->ex_flags;
-}
-
-static jboolean NativeCrypto_X509_check_issued(JNIEnv*, jclass, jlong x509Ref1, jlong x509Ref2) {
- X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
- X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
- JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
-
- int ret = X509_check_issued(x509_1, x509_2);
- JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
- return ret;
-}
-
-static void get_X509_signature(X509 *x509, ASN1_BIT_STRING** signature) {
- *signature = x509->signature;
-}
-
-static void get_X509_CRL_signature(X509_CRL *crl, ASN1_BIT_STRING** signature) {
- *signature = crl->signature;
-}
-
-template<typename T>
-static jbyteArray get_X509Type_signature(JNIEnv* env, T* x509Type, void (*get_signature_func)(T*, ASN1_BIT_STRING**)) {
- JNI_TRACE("get_X509Type_signature(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509Type == null");
- JNI_TRACE("get_X509Type_signature(%p) => x509Type == null", x509Type);
- return NULL;
- }
-
- ASN1_BIT_STRING* signature;
- get_signature_func(x509Type, &signature);
-
- ScopedLocalRef<jbyteArray> signatureArray(env, env->NewByteArray(signature->length));
- if (env->ExceptionCheck()) {
- JNI_TRACE("get_X509Type_signature(%p) => threw exception", x509Type);
- return NULL;
- }
-
- ScopedByteArrayRW signatureBytes(env, signatureArray.get());
- if (signatureBytes.get() == NULL) {
- JNI_TRACE("get_X509Type_signature(%p) => using byte array failed", x509Type);
- return NULL;
- }
-
- memcpy(signatureBytes.get(), signature->data, signature->length);
-
- JNI_TRACE("get_X509Type_signature(%p) => %p (%d bytes)", x509Type, signatureArray.get(),
- signature->length);
- return signatureArray.release();
-}
-
-static jbyteArray NativeCrypto_get_X509_signature(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_signature(%p)", x509);
- return get_X509Type_signature<X509>(env, x509, get_X509_signature);
-}
-
-static jbyteArray NativeCrypto_get_X509_CRL_signature(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_signature(%p)", crl);
- return get_X509Type_signature<X509_CRL>(env, crl, get_X509_CRL_signature);
-}
-
-static jlong NativeCrypto_X509_CRL_get0_by_cert(JNIEnv* env, jclass, jlong x509crlRef, jlong x509Ref) {
- X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p)", x509crl, x509);
-
- if (x509crl == NULL) {
- jniThrowNullPointerException(env, "x509crl == null");
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509crl == null", x509crl, x509);
- return 0;
- } else if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509 == null", x509crl, x509);
- return 0;
- }
-
- X509_REVOKED* revoked = NULL;
- int ret = X509_CRL_get0_by_cert(x509crl, &revoked, x509);
- if (ret == 0) {
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => none", x509crl, x509);
- return 0;
- }
-
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, x509, revoked);
- return reinterpret_cast<uintptr_t>(revoked);
-}
-
-static jlong NativeCrypto_X509_CRL_get0_by_serial(JNIEnv* env, jclass, jlong x509crlRef, jbyteArray serialArray) {
- X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p)", x509crl, serialArray);
-
- if (x509crl == NULL) {
- jniThrowNullPointerException(env, "x509crl == null");
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => crl == null", x509crl, serialArray);
- return 0;
- }
-
- Unique_BIGNUM serialBn(BN_new());
- if (serialBn.get() == NULL) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN allocation failed", x509crl, serialArray);
- return 0;
- }
-
- BIGNUM* serialBare = serialBn.get();
- if (!arrayToBignum(env, serialArray, &serialBare)) {
- if (!env->ExceptionCheck()) {
- jniThrowNullPointerException(env, "serial == null");
- }
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
- return 0;
- }
-
- Unique_ASN1_INTEGER serialInteger(BN_to_ASN1_INTEGER(serialBn.get(), NULL));
- if (serialInteger.get() == NULL) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
- return 0;
- }
-
- X509_REVOKED* revoked = NULL;
- int ret = X509_CRL_get0_by_serial(x509crl, &revoked, serialInteger.get());
- if (ret == 0) {
- JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => none", x509crl, serialArray);
- return 0;
- }
-
- JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, serialArray, revoked);
- return reinterpret_cast<uintptr_t>(revoked);
-}
-
-
-/* This appears to be missing from OpenSSL. */
-#if !defined(X509_REVOKED_dup)
-X509_REVOKED* X509_REVOKED_dup(X509_REVOKED* x) {
- return reinterpret_cast<X509_REVOKED*>(ASN1_item_dup(ASN1_ITEM_rptr(X509_REVOKED), x));
-}
-#endif
-
-static jlongArray NativeCrypto_X509_CRL_get_REVOKED(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_REVOKED(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- return NULL;
- }
-
- STACK_OF(X509_REVOKED)* stack = X509_CRL_get_REVOKED(crl);
- if (stack == NULL) {
- JNI_TRACE("X509_CRL_get_REVOKED(%p) => stack is null", crl);
- return NULL;
- }
-
- size_t size = sk_X509_REVOKED_num(stack);
-
- ScopedLocalRef<jlongArray> revokedArray(env, env->NewLongArray(size));
- ScopedLongArrayRW revoked(env, revokedArray.get());
- for (size_t i = 0; i < size; i++) {
- X509_REVOKED* item = reinterpret_cast<X509_REVOKED*>(sk_X509_REVOKED_value(stack, i));
- revoked[i] = reinterpret_cast<uintptr_t>(X509_REVOKED_dup(item));
- }
-
- JNI_TRACE("X509_CRL_get_REVOKED(%p) => %p [size=%d]", stack, revokedArray.get(), size);
- return revokedArray.release();
-}
-
-static jbyteArray NativeCrypto_i2d_X509_CRL(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("i2d_X509_CRL(%p)", crl);
- return ASN1ToByteArray<X509_CRL, i2d_X509_CRL>(env, crl);
-}
-
-static void NativeCrypto_X509_CRL_free(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_free(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_free(%p) => crl == null", crl);
- return;
- }
-
- X509_CRL_free(crl);
-}
-
-static void NativeCrypto_X509_CRL_print(JNIEnv* env, jclass, jlong bioRef, jlong x509CrlRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_print(%p, %p)", bio, crl);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_CRL_print(%p, %p) => bio == null", bio, crl);
- return;
- }
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_print(%p, %p) => crl == null", bio, crl);
- return;
- }
-
- if (!X509_CRL_print(bio, crl)) {
- throwExceptionIfNecessary(env, "X509_CRL_print");
- JNI_TRACE("X509_CRL_print(%p, %p) => threw error", bio, crl);
- } else {
- JNI_TRACE("X509_CRL_print(%p, %p) => success", bio, crl);
- }
-}
-
-static jstring NativeCrypto_get_X509_CRL_sig_alg_oid(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_sig_alg_oid(%p)", crl);
-
- if (crl == NULL || crl->sig_alg == NULL) {
- jniThrowNullPointerException(env, "crl == NULL || crl->sig_alg == NULL");
- JNI_TRACE("get_X509_CRL_sig_alg_oid(%p) => crl == NULL", crl);
- return NULL;
- }
-
- return ASN1_OBJECT_to_OID_string(env, crl->sig_alg->algorithm);
-}
-
-static jbyteArray NativeCrypto_get_X509_CRL_sig_alg_parameter(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => crl == null", crl);
- return NULL;
- }
-
- if (crl->sig_alg->parameter == NULL) {
- JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => null", crl);
- return NULL;
- }
-
- return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, crl->sig_alg->parameter);
-}
-
-static jbyteArray NativeCrypto_X509_CRL_get_issuer_name(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_issuer_name(%p)", crl);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_CRL_get_issuer(crl));
-}
-
-static long NativeCrypto_X509_CRL_get_version(JNIEnv*, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_version(%p)", crl);
-
- long version = X509_CRL_get_version(crl);
- JNI_TRACE("X509_CRL_get_version(%p) => %ld", crl, version);
- return version;
-}
-
-template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
- X509_EXTENSION* (*get_ext_func)(T*, int)>
-static X509_EXTENSION *X509Type_get_ext(JNIEnv* env, T* x509Type, jstring oidString) {
- JNI_TRACE("X509Type_get_ext(%p)", x509Type);
-
- if (x509Type == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- return NULL;
- }
-
- ScopedUtfChars oid(env, oidString);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- Unique_ASN1_OBJECT asn1(OBJ_txt2obj(oid.c_str(), 1));
- if (asn1.get() == NULL) {
- JNI_TRACE("X509Type_get_ext(%p, %s) => oid conversion failed", x509Type, oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- int extIndex = get_ext_by_OBJ_func(x509Type, asn1.get(), -1);
- if (extIndex == -1) {
- JNI_TRACE("X509Type_get_ext(%p, %s) => ext not found", x509Type, oid.c_str());
- return NULL;
- }
-
- X509_EXTENSION* ext = get_ext_func(x509Type, extIndex);
- JNI_TRACE("X509Type_get_ext(%p, %s) => %p", x509Type, oid.c_str(), ext);
- return ext;
-}
-
-template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
- X509_EXTENSION* (*get_ext_func)(T*, int)>
-static jbyteArray X509Type_get_ext_oid(JNIEnv* env, T* x509Type, jstring oidString) {
- X509_EXTENSION* ext = X509Type_get_ext<T, get_ext_by_OBJ_func, get_ext_func>(env, x509Type,
- oidString);
- if (ext == NULL) {
- JNI_TRACE("X509Type_get_ext_oid(%p, %p) => fetching extension failed", x509Type, oidString);
- return NULL;
- }
-
- JNI_TRACE("X509Type_get_ext_oid(%p, %p) => %p", x509Type, oidString, ext->value);
- return ASN1ToByteArray<ASN1_OCTET_STRING, i2d_ASN1_OCTET_STRING>(env, ext->value);
-}
-
-static jint NativeCrypto_X509_CRL_get_ext(JNIEnv* env, jclass, jlong x509CrlRef, jstring oid) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_ext(%p, %p)", crl, oid);
- X509_EXTENSION* ext = X509Type_get_ext<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(
- env, crl, oid);
- JNI_TRACE("X509_CRL_get_ext(%p, %p) => %p", crl, oid, ext);
- return reinterpret_cast<uintptr_t>(ext);
-}
-
-static jint NativeCrypto_X509_REVOKED_get_ext(JNIEnv* env, jclass, jlong x509RevokedRef,
- jstring oid) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_ext(%p, %p)", revoked, oid);
- X509_EXTENSION* ext = X509Type_get_ext<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ,
- X509_REVOKED_get_ext>(env, revoked, oid);
- JNI_TRACE("X509_REVOKED_get_ext(%p, %p) => %p", revoked, oid, ext);
- return reinterpret_cast<uintptr_t>(ext);
-}
-
-static jlong NativeCrypto_X509_REVOKED_dup(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_dup(%p)", revoked);
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_dup(%p) => revoked == null", revoked);
- return 0;
- }
-
- X509_REVOKED* dup = X509_REVOKED_dup(revoked);
- JNI_TRACE("X509_REVOKED_dup(%p) => %p", revoked, dup);
- return reinterpret_cast<uintptr_t>(dup);
-}
-
-static jlong NativeCrypto_get_X509_REVOKED_revocationDate(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p)", revoked);
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => revoked == null", revoked);
- return 0;
- }
-
- JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => %p", revoked, revoked->revocationDate);
- return reinterpret_cast<uintptr_t>(revoked->revocationDate);
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wwrite-strings"
-static void NativeCrypto_X509_REVOKED_print(JNIEnv* env, jclass, jlong bioRef, jlong x509RevokedRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_print(%p, %p)", bio, revoked);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_REVOKED_print(%p, %p) => bio == null", bio, revoked);
- return;
- }
-
- if (revoked == NULL) {
- jniThrowNullPointerException(env, "revoked == null");
- JNI_TRACE("X509_REVOKED_print(%p, %p) => revoked == null", bio, revoked);
- return;
- }
-
- BIO_printf(bio, "Serial Number: ");
- i2a_ASN1_INTEGER(bio, revoked->serialNumber);
- BIO_printf(bio, "\nRevocation Date: ");
- ASN1_TIME_print(bio, revoked->revocationDate);
- BIO_printf(bio, "\n");
- X509V3_extensions_print(bio, "CRL entry extensions", revoked->extensions, 0, 0);
-}
-#pragma GCC diagnostic pop
-
-static jbyteArray NativeCrypto_get_X509_CRL_crl_enc(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("get_X509_CRL_crl_enc(%p)", crl);
- return ASN1ToByteArray<X509_CRL_INFO, i2d_X509_CRL_INFO>(env, crl->crl);
-}
-
-static void NativeCrypto_X509_CRL_verify(JNIEnv* env, jclass, jlong x509CrlRef, jlong pkeyRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("X509_CRL_verify(%p, %p)", crl, pkey);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_verify(%p, %p) => crl == null", crl, pkey);
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("X509_CRL_verify(%p, %p) => pkey == null", crl, pkey);
- return;
- }
-
- if (X509_CRL_verify(crl, pkey) != 1) {
- throwExceptionIfNecessary(env, "X509_CRL_verify");
- JNI_TRACE("X509_CRL_verify(%p, %p) => verify failure", crl, pkey);
- } else {
- JNI_TRACE("X509_CRL_verify(%p, %p) => verify success", crl, pkey);
- }
-}
-
-static jlong NativeCrypto_X509_CRL_get_lastUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_lastUpdate(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_lastUpdate(%p) => crl == null", crl);
- return 0;
- }
-
- ASN1_TIME* lastUpdate = X509_CRL_get_lastUpdate(crl);
- JNI_TRACE("X509_CRL_get_lastUpdate(%p) => %p", crl, lastUpdate);
- return reinterpret_cast<uintptr_t>(lastUpdate);
-}
-
-static jlong NativeCrypto_X509_CRL_get_nextUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_nextUpdate(%p)", crl);
-
- if (crl == NULL) {
- jniThrowNullPointerException(env, "crl == null");
- JNI_TRACE("X509_CRL_get_nextUpdate(%p) => crl == null", crl);
- return 0;
- }
-
- ASN1_TIME* nextUpdate = X509_CRL_get_nextUpdate(crl);
- JNI_TRACE("X509_CRL_get_nextUpdate(%p) => %p", crl, nextUpdate);
- return reinterpret_cast<uintptr_t>(nextUpdate);
-}
-
-static jbyteArray NativeCrypto_i2d_X509_REVOKED(JNIEnv* env, jclass, jlong x509RevokedRef) {
- X509_REVOKED* x509Revoked =
- reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("i2d_X509_REVOKED(%p)", x509Revoked);
- return ASN1ToByteArray<X509_REVOKED, i2d_X509_REVOKED>(env, x509Revoked);
-}
-
-static jint NativeCrypto_X509_supported_extension(JNIEnv* env, jclass, jlong x509ExtensionRef) {
- X509_EXTENSION* ext = reinterpret_cast<X509_EXTENSION*>(static_cast<uintptr_t>(x509ExtensionRef));
-
- if (ext == NULL) {
- jniThrowNullPointerException(env, "ext == NULL");
- return 0;
- }
-
- return X509_supported_extension(ext);
-}
-
-static inline void get_ASN1_TIME_data(char **data, int* output, size_t len) {
- char c = **data;
- **data = '\0';
- *data -= len;
- *output = atoi(*data);
- *(*data + len) = c;
-}
-
-static void NativeCrypto_ASN1_TIME_to_Calendar(JNIEnv* env, jclass, jlong asn1TimeRef, jobject calendar) {
- ASN1_TIME* asn1Time = reinterpret_cast<ASN1_TIME*>(static_cast<uintptr_t>(asn1TimeRef));
- JNI_TRACE("ASN1_TIME_to_Calendar(%p, %p)", asn1Time, calendar);
-
- if (asn1Time == NULL) {
- jniThrowNullPointerException(env, "asn1Time == null");
- return;
- }
-
- Unique_ASN1_GENERALIZEDTIME gen(ASN1_TIME_to_generalizedtime(asn1Time, NULL));
- if (gen.get() == NULL) {
- jniThrowNullPointerException(env, "asn1Time == null");
- return;
- }
-
- if (gen->length < 14 || gen->data == NULL) {
- jniThrowNullPointerException(env, "gen->length < 14 || gen->data == NULL");
- return;
- }
-
- int sec, min, hour, mday, mon, year;
-
- char *p = (char*) &gen->data[14];
-
- get_ASN1_TIME_data(&p, &sec, 2);
- get_ASN1_TIME_data(&p, &min, 2);
- get_ASN1_TIME_data(&p, &hour, 2);
- get_ASN1_TIME_data(&p, &mday, 2);
- get_ASN1_TIME_data(&p, &mon, 2);
- get_ASN1_TIME_data(&p, &year, 4);
-
- env->CallVoidMethod(calendar, calendar_setMethod, year, mon - 1, mday, hour, min, sec);
-}
-
-static jstring NativeCrypto_OBJ_txt2nid_oid(JNIEnv* env, jclass, jstring oidStr) {
- JNI_TRACE("OBJ_txt2nid_oid(%p)", oidStr);
-
- ScopedUtfChars oid(env, oidStr);
- if (oid.c_str() == NULL) {
- return NULL;
- }
-
- JNI_TRACE("OBJ_txt2nid_oid(%s)", oid.c_str());
-
- int nid = OBJ_txt2nid(oid.c_str());
- if (nid == NID_undef) {
- JNI_TRACE("OBJ_txt2nid_oid(%s) => NID_undef", oid.c_str());
- freeOpenSslErrorState();
- return NULL;
- }
-
- Unique_ASN1_OBJECT obj(OBJ_nid2obj(nid));
- if (obj.get() == NULL) {
- throwExceptionIfNecessary(env, "OBJ_nid2obj");
- return NULL;
- }
-
- ScopedLocalRef<jstring> ouputStr(env, ASN1_OBJECT_to_OID_string(env, obj.get()));
- JNI_TRACE("OBJ_txt2nid_oid(%s) => %p", oid.c_str(), ouputStr.get());
- return ouputStr.release();
-}
-
-static jstring NativeCrypto_X509_NAME_print_ex(JNIEnv* env, jclass, jlong x509NameRef, jlong jflags) {
- X509_NAME* x509name = reinterpret_cast<X509_NAME*>(static_cast<uintptr_t>(x509NameRef));
- unsigned long flags = static_cast<unsigned long>(jflags);
- JNI_TRACE("X509_NAME_print_ex(%p, %ld)", x509name, flags);
-
- if (x509name == NULL) {
- jniThrowNullPointerException(env, "x509name == null");
- JNI_TRACE("X509_NAME_print_ex(%p, %ld) => x509name == null", x509name, flags);
- return NULL;
- }
-
- return X509_NAME_to_jstring(env, x509name, flags);
-}
-
-template <typename T, T* (*d2i_func)(BIO*, T**)>
-static jlong d2i_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("d2i_ASN1Object_to_jlong(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- return 0;
- }
-
- T* x = d2i_func(bio, NULL);
- if (x == NULL) {
- throwExceptionIfNecessary(env, "d2i_ASN1Object_to_jlong");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jlong NativeCrypto_d2i_X509_CRL_bio(JNIEnv* env, jclass, jlong bioRef) {
- return d2i_ASN1Object_to_jlong<X509_CRL, d2i_X509_CRL_bio>(env, bioRef);
-}
-
-static jlong NativeCrypto_d2i_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
- return d2i_ASN1Object_to_jlong<X509, d2i_X509_bio>(env, bioRef);
-}
-
-static jlong NativeCrypto_d2i_X509(JNIEnv* env, jclass, jbyteArray certBytes) {
- X509* x = ByteArrayToASN1<X509, d2i_X509>(env, certBytes);
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jbyteArray NativeCrypto_i2d_X509(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("i2d_X509(%p)", x509);
- return ASN1ToByteArray<X509, i2d_X509>(env, x509);
-}
-
-static jbyteArray NativeCrypto_i2d_X509_PUBKEY(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("i2d_X509_PUBKEY(%p)", x509);
- return ASN1ToByteArray<X509_PUBKEY, i2d_X509_PUBKEY>(env, X509_get_X509_PUBKEY(x509));
-}
-
-
-template<typename T, T* (*PEM_read_func)(BIO*, T**, pem_password_cb*, void*)>
-static jlong PEM_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => bio == null", bio);
- return 0;
- }
-
- T* x = PEM_read_func(bio, NULL, NULL, NULL);
- if (x == NULL) {
- throwExceptionIfNecessary(env, "PEM_ASN1Object_to_jlong");
- // Sometimes the PEM functions fail without pushing an error
- if (!env->ExceptionCheck()) {
- jniThrowRuntimeException(env, "Failure parsing PEM");
- }
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => threw exception", bio);
- return 0;
- }
-
- JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => %p", bio, x);
- return reinterpret_cast<uintptr_t>(x);
-}
-
-static jlong NativeCrypto_PEM_read_bio_X509(JNIEnv* env, jclass, jlong bioRef) {
- JNI_TRACE("PEM_read_bio_X509(0x%llx)", bioRef);
- return PEM_ASN1Object_to_jlong<X509, PEM_read_bio_X509>(env, bioRef);
-}
-
-static jlong NativeCrypto_PEM_read_bio_X509_CRL(JNIEnv* env, jclass, jlong bioRef) {
- JNI_TRACE("PEM_read_bio_X509_CRL(0x%llx)", bioRef);
- return PEM_ASN1Object_to_jlong<X509_CRL, PEM_read_bio_X509_CRL>(env, bioRef);
-}
-
-static STACK_OF(X509)* PKCS7_get_certs(PKCS7* pkcs7) {
- if (PKCS7_type_is_signed(pkcs7)) {
- return pkcs7->d.sign->cert;
- } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
- return pkcs7->d.signed_and_enveloped->cert;
- } else {
- JNI_TRACE("PKCS7_get_certs(%p) => unknown PKCS7 type", pkcs7);
- return NULL;
- }
-}
-
-static STACK_OF(X509_CRL)* PKCS7_get_CRLs(PKCS7* pkcs7) {
- if (PKCS7_type_is_signed(pkcs7)) {
- return pkcs7->d.sign->crl;
- } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
- return pkcs7->d.signed_and_enveloped->crl;
- } else {
- JNI_TRACE("PKCS7_get_CRLs(%p) => unknown PKCS7 type", pkcs7);
- return NULL;
- }
-}
-
-template <typename T, typename T_stack>
-static jlongArray PKCS7_to_ItemArray(JNIEnv* env, T_stack* stack, T* (*dup_func)(T*))
-{
- if (stack == NULL) {
- return NULL;
- }
-
- ScopedLocalRef<jlongArray> ref_array(env, NULL);
- size_t size = sk_num(reinterpret_cast<_STACK*>(stack));
- ref_array.reset(env->NewLongArray(size));
- ScopedLongArrayRW items(env, ref_array.get());
- for (size_t i = 0; i < size; i++) {
- T* item = reinterpret_cast<T*>(sk_value(reinterpret_cast<_STACK*>(stack), i));
- items[i] = reinterpret_cast<uintptr_t>(dup_func(item));
- }
-
- JNI_TRACE("PKCS7_to_ItemArray(%p) => %p [size=%d]", stack, ref_array.get(), size);
- return ref_array.release();
-}
-
-#define PKCS7_CERTS 1
-#define PKCS7_CRLS 2
-
-static jlongArray NativeCrypto_PEM_read_bio_PKCS7(JNIEnv* env, jclass, jlong bioRef, jint which) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p)", bio);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => bio == null", bio);
- return 0;
- }
-
- Unique_PKCS7 pkcs7(PEM_read_bio_PKCS7(bio, NULL, NULL, NULL));
- if (pkcs7.get() == NULL) {
- throwExceptionIfNecessary(env, "PEM_read_bio_PKCS7_CRLs");
- JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => threw exception", bio);
- return 0;
- }
-
- switch (which) {
- case PKCS7_CERTS:
- return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
- case PKCS7_CRLS:
- return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
- X509_CRL_dup);
- default:
- jniThrowRuntimeException(env, "unknown PKCS7 field");
- return NULL;
- }
-}
-
-static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, jint which) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("d2i_PKCS7_bio(%p, %d)", bio, which);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("d2i_PKCS7_bio(%p, %d) => bio == null", bio, which);
- return 0;
- }
-
- Unique_PKCS7 pkcs7(d2i_PKCS7_bio(bio, NULL));
- if (pkcs7.get() == NULL) {
- throwExceptionIfNecessary(env, "d2i_PKCS7_bio");
- JNI_TRACE("d2i_PKCS7_bio(%p, %d) => threw exception", bio, which);
- return 0;
- }
-
- switch (which) {
- case PKCS7_CERTS:
- return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
- case PKCS7_CRLS:
- return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
- X509_CRL_dup);
- default:
- jniThrowRuntimeException(env, "unknown PKCS7 field");
- return NULL;
- }
-}
-
-static jbyteArray NativeCrypto_i2d_PKCS7(JNIEnv* env, jclass, jlongArray certsArray) {
- JNI_TRACE("i2d_PKCS7(%p)", certsArray);
-
- Unique_PKCS7 pkcs7(PKCS7_new());
- if (pkcs7.get() == NULL) {
- jniThrowNullPointerException(env, "pkcs7 == null");
- JNI_TRACE("i2d_PKCS7(%p) => pkcs7 == null", certsArray);
- return NULL;
- }
-
- if (PKCS7_set_type(pkcs7.get(), NID_pkcs7_signed) != 1) {
- throwExceptionIfNecessary(env, "PKCS7_set_type");
- return NULL;
- }
-
- ScopedLongArrayRO certs(env, certsArray);
- for (size_t i = 0; i < certs.size(); i++) {
- X509* item = reinterpret_cast<X509*>(certs[i]);
- if (PKCS7_add_certificate(pkcs7.get(), item) != 1) {
- throwExceptionIfNecessary(env, "i2d_PKCS7");
- return NULL;
- }
- }
-
- JNI_TRACE("i2d_PKCS7(%p) => %d certs", certsArray, certs.size());
- return ASN1ToByteArray<PKCS7, i2d_PKCS7>(env, pkcs7.get());
-}
-
-typedef STACK_OF(X509) PKIPATH;
-
-ASN1_ITEM_TEMPLATE(PKIPATH) =
- ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PkiPath, X509)
-ASN1_ITEM_TEMPLATE_END(PKIPATH)
-
-static jlongArray NativeCrypto_ASN1_seq_unpack_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- JNI_TRACE("ASN1_seq_unpack_X509_bio(%p)", bio);
-
- Unique_sk_X509 path((PKIPATH*) ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKIPATH), bio, NULL));
- if (path.get() == NULL) {
- throwExceptionIfNecessary(env, "ASN1_seq_unpack_X509_bio");
- return NULL;
- }
-
- size_t size = sk_X509_num(path.get());
-
- ScopedLocalRef<jlongArray> certArray(env, env->NewLongArray(size));
- ScopedLongArrayRW certs(env, certArray.get());
- for (size_t i = 0; i < size; i++) {
- X509* item = reinterpret_cast<X509*>(sk_X509_shift(path.get()));
- certs[i] = reinterpret_cast<uintptr_t>(item);
- }
-
- JNI_TRACE("ASN1_seq_unpack_X509_bio(%p) => returns %d items", bio, size);
- return certArray.release();
-}
-
-static jbyteArray NativeCrypto_ASN1_seq_pack_X509(JNIEnv* env, jclass, jlongArray certs) {
- JNI_TRACE("ASN1_seq_pack_X509(%p)", certs);
- ScopedLongArrayRO certsArray(env, certs);
- if (certsArray.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to get certs array", certs);
- return NULL;
- }
-
- Unique_sk_X509 certStack(sk_X509_new_null());
- if (certStack.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to make cert stack", certs);
- return NULL;
- }
-
- for (size_t i = 0; i < certsArray.size(); i++) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(certsArray[i]));
- sk_X509_push(certStack.get(), X509_dup_nocopy(x509));
- }
-
- int len;
- Unique_OPENSSL_str encoded(ASN1_seq_pack(
- reinterpret_cast<STACK_OF(OPENSSL_BLOCK)*>(
- reinterpret_cast<uintptr_t>(certStack.get())),
- reinterpret_cast<int (*)(void*, unsigned char**)>(i2d_X509), NULL, &len));
- if (encoded.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => trouble encoding", certs);
- return NULL;
- }
-
- ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
- if (byteArray.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => creating byte array failed", certs);
- return NULL;
- }
-
- ScopedByteArrayRW bytes(env, byteArray.get());
- if (bytes.get() == NULL) {
- JNI_TRACE("ASN1_seq_pack_X509(%p) => using byte array failed", certs);
- return NULL;
- }
-
- unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
- memcpy(p, encoded.get(), len);
-
- return byteArray.release();
-}
-
-static void NativeCrypto_X509_free(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_free(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_free(%p) => x509 == null", x509);
- return;
- }
-
- X509_free(x509);
-}
-
-static jint NativeCrypto_X509_cmp(JNIEnv* env, jclass, jlong x509Ref1, jlong x509Ref2) {
- X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
- X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
- JNI_TRACE("X509_cmp(%p, %p)", x509_1, x509_2);
-
- if (x509_1 == NULL) {
- jniThrowNullPointerException(env, "x509_1 == null");
- JNI_TRACE("X509_cmp(%p, %p) => x509_1 == null", x509_1, x509_2);
- return -1;
- }
-
- if (x509_2 == NULL) {
- jniThrowNullPointerException(env, "x509_2 == null");
- JNI_TRACE("X509_cmp(%p, %p) => x509_2 == null", x509_1, x509_2);
- return -1;
- }
-
- int ret = X509_cmp(x509_1, x509_2);
- JNI_TRACE("X509_cmp(%p, %p) => %d", x509_1, x509_2, ret);
- return ret;
-}
-
-static jint NativeCrypto_get_X509_hashCode(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_hashCode(%p) => x509 == null", x509);
- return 0;
- }
-
- // Force caching extensions.
- X509_check_ca(x509);
-
- jint hashCode = 0L;
- for (int i = 0; i < SHA_DIGEST_LENGTH; i++) {
- hashCode = 31 * hashCode + x509->sha1_hash[i];
- }
- return hashCode;
-}
-
-static void NativeCrypto_X509_print_ex(JNIEnv* env, jclass, jlong bioRef, jlong x509Ref,
- jlong nmflagJava, jlong certflagJava) {
- BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- long nmflag = static_cast<long>(nmflagJava);
- long certflag = static_cast<long>(certflagJava);
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld)", bio, x509, nmflag, certflag);
-
- if (bio == NULL) {
- jniThrowNullPointerException(env, "bio == null");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => bio == null", bio, x509, nmflag, certflag);
- return;
- }
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => x509 == null", bio, x509, nmflag, certflag);
- return;
- }
-
- if (!X509_print_ex(bio, x509, nmflag, certflag)) {
- throwExceptionIfNecessary(env, "X509_print_ex");
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => threw error", bio, x509, nmflag, certflag);
- } else {
- JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => success", bio, x509, nmflag, certflag);
- }
-}
-
-static jlong NativeCrypto_X509_get_pubkey(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_pubkey(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("X509_get_pubkey(%p) => x509 == null", x509);
- return 0;
- }
-
- Unique_EVP_PKEY pkey(X509_get_pubkey(x509));
- if (pkey.get() == NULL) {
- throwExceptionIfNecessary(env, "X509_get_pubkey");
- return 0;
- }
-
- return reinterpret_cast<uintptr_t>(pkey.release());
-}
-
-static jbyteArray NativeCrypto_X509_get_issuer_name(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_issuer_name(%p)", x509);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_issuer_name(x509));
-}
-
-static jbyteArray NativeCrypto_X509_get_subject_name(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_subject_name(%p)", x509);
- return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_subject_name(x509));
-}
-
-static jstring NativeCrypto_get_X509_pubkey_oid(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_pubkey_oid(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_pubkey_oid(%p) => x509 == null", x509);
- return NULL;
- }
-
- X509_PUBKEY* pubkey = X509_get_X509_PUBKEY(x509);
- return ASN1_OBJECT_to_OID_string(env, pubkey->algor->algorithm);
-}
-
-static jstring NativeCrypto_get_X509_sig_alg_oid(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_sig_alg_oid(%p)", x509);
-
- if (x509 == NULL || x509->sig_alg == NULL) {
- jniThrowNullPointerException(env, "x509 == NULL || x509->sig_alg == NULL");
- JNI_TRACE("get_X509_sig_alg_oid(%p) => x509 == NULL", x509);
- return NULL;
- }
-
- return ASN1_OBJECT_to_OID_string(env, x509->sig_alg->algorithm);
-}
-
-static jbyteArray NativeCrypto_get_X509_sig_alg_parameter(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_sig_alg_parameter(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_sig_alg_parameter(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->sig_alg->parameter == NULL) {
- JNI_TRACE("get_X509_sig_alg_parameter(%p) => null", x509);
- return NULL;
- }
-
- return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, x509->sig_alg->parameter);
-}
-
-static jbooleanArray NativeCrypto_get_X509_issuerUID(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_issuerUID(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_issuerUID(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->cert_info->issuerUID == NULL) {
- JNI_TRACE("get_X509_issuerUID(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, x509->cert_info->issuerUID);
-}
-static jbooleanArray NativeCrypto_get_X509_subjectUID(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_subjectUID(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_subjectUID(%p) => x509 == null", x509);
- return NULL;
- }
-
- if (x509->cert_info->subjectUID == NULL) {
- JNI_TRACE("get_X509_subjectUID(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, x509->cert_info->subjectUID);
-}
-
-static jbooleanArray NativeCrypto_get_X509_ex_kusage(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_kusage(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_kusage(%p) => x509 == null", x509);
- return NULL;
- }
-
- Unique_ASN1_BIT_STRING bitStr(static_cast<ASN1_BIT_STRING*>(
- X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL)));
- if (bitStr.get() == NULL) {
- JNI_TRACE("get_X509_ex_kusage(%p) => null", x509);
- return NULL;
- }
-
- return ASN1BitStringToBooleanArray(env, bitStr.get());
-}
-
-static jobjectArray NativeCrypto_get_X509_ex_xkusage(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_xkusage(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_xkusage(%p) => x509 == null", x509);
- return NULL;
- }
-
- Unique_sk_ASN1_OBJECT objArray(static_cast<STACK_OF(ASN1_OBJECT)*>(
- X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL)));
- if (objArray.get() == NULL) {
- JNI_TRACE("get_X509_ex_xkusage(%p) => null", x509);
- return NULL;
- }
-
- size_t size = sk_ASN1_OBJECT_num(objArray.get());
- ScopedLocalRef<jobjectArray> exKeyUsage(env, env->NewObjectArray(size, stringClass, NULL));
- if (exKeyUsage.get() == NULL) {
- return NULL;
- }
-
- for (size_t i = 0; i < size; i++) {
- ScopedLocalRef<jstring> oidStr(env, ASN1_OBJECT_to_OID_string(env,
- sk_ASN1_OBJECT_value(objArray.get(), i)));
- env->SetObjectArrayElement(exKeyUsage.get(), i, oidStr.get());
- }
-
- JNI_TRACE("get_X509_ex_xkusage(%p) => success (%d entries)", x509, size);
- return exKeyUsage.release();
-}
-
-static jint NativeCrypto_get_X509_ex_pathlen(JNIEnv* env, jclass, jlong x509Ref) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509_ex_pathlen(%p)", x509);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509_ex_pathlen(%p) => x509 == null", x509);
- return 0;
- }
-
- /* Just need to do this to cache the ex_* values. */
- X509_check_ca(x509);
-
- JNI_TRACE("get_X509_ex_pathlen(%p) => %ld", x509, x509->ex_pathlen);
- return x509->ex_pathlen;
-}
-
-static jbyteArray NativeCrypto_X509_get_ext_oid(JNIEnv* env, jclass, jlong x509Ref,
- jstring oidString) {
- X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("X509_get_ext_oid(%p, %p)", x509, oidString);
- return X509Type_get_ext_oid<X509, X509_get_ext_by_OBJ, X509_get_ext>(env, x509, oidString);
-}
-
-static jbyteArray NativeCrypto_X509_CRL_get_ext_oid(JNIEnv* env, jclass, jlong x509CrlRef,
- jstring oidString) {
- X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
- JNI_TRACE("X509_CRL_get_ext_oid(%p, %p)", crl, oidString);
- return X509Type_get_ext_oid<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl,
- oidString);
-}
-
-static jbyteArray NativeCrypto_X509_REVOKED_get_ext_oid(JNIEnv* env, jclass, jlong x509RevokedRef,
- jstring oidString) {
- X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
- JNI_TRACE("X509_REVOKED_get_ext_oid(%p, %p)", revoked, oidString);
- return X509Type_get_ext_oid<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ, X509_REVOKED_get_ext>(
- env, revoked, oidString);
-}
-
-template<typename T, int (*get_ext_by_critical_func)(T*, int, int), X509_EXTENSION* (*get_ext_func)(T*, int)>
-static jobjectArray get_X509Type_ext_oids(JNIEnv* env, jlong x509Ref, jint critical) {
- T* x509 = reinterpret_cast<T*>(static_cast<uintptr_t>(x509Ref));
- JNI_TRACE("get_X509Type_ext_oids(%p, %d)", x509, critical);
-
- if (x509 == NULL) {
- jniThrowNullPointerException(env, "x509 == null");
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => x509 == null", x509, critical);
- return NULL;
- }
-
- int lastPos = -1;
- int count = 0;
- while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
- count++;
- }
-
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) has %d entries", x509, critical, count);
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, stringClass, NULL));
- if (joa.get() == NULL) {
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => fail to allocate result array", x509, critical);
- return NULL;
- }
-
- lastPos = -1;
- count = 0;
- while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
- X509_EXTENSION* ext = get_ext_func(x509, lastPos);
-
- ScopedLocalRef<jstring> extOid(env, ASN1_OBJECT_to_OID_string(env, ext->object));
- if (extOid.get() == NULL) {
- JNI_TRACE("get_X509Type_ext_oids(%p) => couldn't get OID", x509);
- return NULL;
- }
-
- env->SetObjectArrayElement(joa.get(), count++, extOid.get());
- }
-
- JNI_TRACE("get_X509Type_ext_oids(%p, %d) => success", x509, critical);
- return joa.release();
-}
-
-static jobjectArray NativeCrypto_get_X509_ext_oids(JNIEnv* env, jclass, jlong x509Ref,
- jint critical) {
- JNI_TRACE("get_X509_ext_oids(0x%llx, %d)", x509Ref, critical);
- return get_X509Type_ext_oids<X509, X509_get_ext_by_critical, X509_get_ext>(env, x509Ref,
- critical);
-}
-
-static jobjectArray NativeCrypto_get_X509_CRL_ext_oids(JNIEnv* env, jclass, jlong x509CrlRef,
- jint critical) {
- JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509CrlRef, critical);
- return get_X509Type_ext_oids<X509_CRL, X509_CRL_get_ext_by_critical, X509_CRL_get_ext>(env,
- x509CrlRef, critical);
-}
-
-static jobjectArray NativeCrypto_get_X509_REVOKED_ext_oids(JNIEnv* env, jclass, jlong x509RevokedRef,
- jint critical) {
- JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509RevokedRef, critical);
- return get_X509Type_ext_oids<X509_REVOKED, X509_REVOKED_get_ext_by_critical,
- X509_REVOKED_get_ext>(env, x509RevokedRef, critical);
-}
-
-#ifdef WITH_JNI_TRACE
-/**
- * Based on example logging call back from SSL_CTX_set_info_callback man page
- */
-static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
-{
- int w = where & ~SSL_ST_MASK;
- const char* str;
- if (w & SSL_ST_CONNECT) {
- str = "SSL_connect";
- } else if (w & SSL_ST_ACCEPT) {
- str = "SSL_accept";
- } else {
- str = "undefined";
- }
-
- if (where & SSL_CB_LOOP) {
- JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (where & SSL_CB_ALERT) {
- str = (where & SSL_CB_READ) ? "read" : "write";
- JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
- s,
- str,
- SSL_alert_type_string(ret),
- SSL_alert_desc_string(ret),
- SSL_alert_type_string_long(ret),
- SSL_alert_desc_string_long(ret));
- } else if (where & SSL_CB_EXIT) {
- if (ret == 0) {
- JNI_TRACE("ssl=%p %s:failed exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (ret < 0) {
- JNI_TRACE("ssl=%p %s:error exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else if (ret == 1) {
- JNI_TRACE("ssl=%p %s:ok exit in %s %s",
- s, str, SSL_state_string(s), SSL_state_string_long(s));
- } else {
- JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
- s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
- }
- } else if (where & SSL_CB_HANDSHAKE_START) {
- JNI_TRACE("ssl=%p handshake start in %s %s",
- s, SSL_state_string(s), SSL_state_string_long(s));
- } else if (where & SSL_CB_HANDSHAKE_DONE) {
- JNI_TRACE("ssl=%p handshake done in %s %s",
- s, SSL_state_string(s), SSL_state_string_long(s));
- } else {
- JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
- s, str, where, SSL_state_string(s), SSL_state_string_long(s));
- }
-}
-#endif
-
-/**
- * Returns an array containing all the X509 certificate's bytes.
- */
-static jobjectArray getCertificateBytes(JNIEnv* env, const STACK_OF(X509)* chain)
-{
- if (chain == NULL) {
- // Chain can be NULL if the associated cipher doesn't do certs.
- return NULL;
- }
-
- int count = sk_X509_num(chain);
- if (count <= 0) {
- return NULL;
- }
-
- jobjectArray joa = env->NewObjectArray(count, byteArrayClass, NULL);
- if (joa == NULL) {
- return NULL;
- }
-
- for (int i = 0; i < count; i++) {
- X509* cert = sk_X509_value(chain, i);
-
- ScopedLocalRef<jbyteArray> byteArray(env, ASN1ToByteArray<X509, i2d_X509>(env, cert));
- if (byteArray.get() == NULL) {
- return NULL;
- }
- env->SetObjectArrayElement(joa, i, byteArray.get());
- }
-
- return joa;
-}
-
-/**
- * Returns an array containing all the X500 principal's bytes.
- */
-static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
-{
- if (names == NULL) {
- return NULL;
- }
-
- int count = sk_X509_NAME_num(names);
- if (count <= 0) {
- return NULL;
- }
-
- ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, byteArrayClass, NULL));
- if (joa.get() == NULL) {
- return NULL;
- }
-
- for (int i = 0; i < count; i++) {
- X509_NAME* principal = sk_X509_NAME_value(names, i);
-
- ScopedLocalRef<jbyteArray> byteArray(env, ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env,
- principal));
- if (byteArray.get() == NULL) {
- return NULL;
- }
- env->SetObjectArrayElement(joa.get(), i, byteArray.get());
- }
-
- return joa.release();
-}
-
-/**
- * Our additional application data needed for getting synchronization right.
- * This maybe warrants a bit of lengthy prose:
- *
- * (1) We use a flag to reflect whether we consider the SSL connection alive.
- * Any read or write attempt loops will be cancelled once this flag becomes 0.
- *
- * (2) We use an int to count the number of threads that are blocked by the
- * underlying socket. This may be at most two (one reader and one writer), since
- * the Java layer ensures that no more threads will enter the native code at the
- * same time.
- *
- * (3) The pipe is used primarily as a means of cancelling a blocking select()
- * when we want to close the connection (aka "emergency button"). It is also
- * necessary for dealing with a possible race condition situation: There might
- * be cases where both threads see an SSL_ERROR_WANT_READ or
- * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
- * If one leaves the select() successfully before the other enters it, the
- * "success" event is already consumed and the second thread will be blocked,
- * possibly forever (depending on network conditions).
- *
- * The idea for solving the problem looks like this: Whenever a thread is
- * successful in moving around data on the network, and it knows there is
- * another thread stuck in a select(), it will write a byte to the pipe, waking
- * up the other thread. A thread that returned from select(), on the other hand,
- * knows whether it's been woken up by the pipe. If so, it will consume the
- * byte, and the original state of affairs has been restored.
- *
- * The pipe may seem like a bit of overhead, but it fits in nicely with the
- * other file descriptors of the select(), so there's only one condition to wait
- * for.
- *
- * (4) Finally, a mutex is needed to make sure that at most one thread is in
- * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
- * requirement. We use the same mutex to guard the field for counting the
- * waiting threads.
- *
- * Note: The current implementation assumes that we don't have to deal with
- * problems induced by multiple cores or processors and their respective
- * memory caches. One possible problem is that of inconsistent views on the
- * "aliveAndKicking" field. This could be worked around by also enclosing all
- * accesses to that field inside a lock/unlock sequence of our mutex, but
- * currently this seems a bit like overkill. Marking volatile at the very least.
- *
- * During handshaking, additional fields are used to up-call into
- * Java to perform certificate verification and handshake
- * completion. These are also used in any renegotiation.
- *
- * (5) the JNIEnv so we can invoke the Java callback
- *
- * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
- *
- * (7) a java.io.FileDescriptor wrapper to check for socket close
- *
- * We store the NPN protocols list so we can either send it (from the server) or
- * select a protocol (on the client). We eagerly acquire a pointer to the array
- * data so the callback doesn't need to acquire resources that it cannot
- * release.
- *
- * Because renegotiation can be requested by the peer at any time,
- * care should be taken to maintain an appropriate JNIEnv on any
- * downcall to openssl since it could result in an upcall to Java. The
- * current code does try to cover these cases by conditionally setting
- * the JNIEnv on calls that can read and write to the SSL such as
- * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
- *
- * Finally, we have two emphemeral keys setup by OpenSSL callbacks:
- *
- * (8) a set of ephemeral RSA keys that is lazily generated if a peer
- * wants to use an exportable RSA cipher suite.
- *
- * (9) a set of ephemeral EC keys that is lazily generated if a peer
- * wants to use an TLS_ECDHE_* cipher suite.
- *
- */
-class AppData {
- public:
- volatile int aliveAndKicking;
- int waitingThreads;
- int fdsEmergency[2];
- MUTEX_TYPE mutex;
- JNIEnv* env;
- jobject sslHandshakeCallbacks;
- jobject fileDescriptor;
- jbyteArray npnProtocolsArray;
- jbyte* npnProtocolsData;
- size_t npnProtocolsLength;
- jbyteArray alpnProtocolsArray;
- jbyte* alpnProtocolsData;
- size_t alpnProtocolsLength;
- Unique_RSA ephemeralRsa;
- Unique_EC_KEY ephemeralEc;
-
- /**
- * Creates the application data context for the SSL*.
- */
- public:
- static AppData* create() {
- UniquePtr<AppData> appData(new AppData());
- if (pipe(appData.get()->fdsEmergency) == -1) {
- ALOGE("AppData::create pipe(2) failed: %s", strerror(errno));
- return NULL;
- }
- if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
- ALOGE("AppData::create fcntl(2) failed: %s", strerror(errno));
- return NULL;
- }
- if (MUTEX_SETUP(appData.get()->mutex) == -1) {
- ALOGE("pthread_mutex_init(3) failed: %s", strerror(errno));
- return NULL;
- }
- return appData.release();
- }
-
- ~AppData() {
- aliveAndKicking = 0;
- if (fdsEmergency[0] != -1) {
- close(fdsEmergency[0]);
- }
- if (fdsEmergency[1] != -1) {
- close(fdsEmergency[1]);
- }
- clearCallbackState();
- MUTEX_CLEANUP(mutex);
- }
-
- private:
- AppData() :
- aliveAndKicking(1),
- waitingThreads(0),
- env(NULL),
- sslHandshakeCallbacks(NULL),
- npnProtocolsArray(NULL),
- npnProtocolsData(NULL),
- npnProtocolsLength(-1),
- alpnProtocolsArray(NULL),
- alpnProtocolsData(NULL),
- alpnProtocolsLength(-1),
- ephemeralRsa(NULL),
- ephemeralEc(NULL) {
- fdsEmergency[0] = -1;
- fdsEmergency[1] = -1;
- }
-
- public:
- /**
- * Used to set the SSL-to-Java callback state before each SSL_*
- * call that may result in a callback. It should be cleared after
- * the operation returns with clearCallbackState.
- *
- * @param env The JNIEnv
- * @param shc The SSLHandshakeCallbacks
- * @param fd The FileDescriptor
- * @param npnProtocols NPN protocols so that they may be advertised (by the
- * server) or selected (by the client). Has no effect
- * unless NPN is enabled.
- * @param alpnProtocols ALPN protocols so that they may be advertised (by the
- * server) or selected (by the client). Passing non-NULL
- * enables ALPN.
- */
- bool setCallbackState(JNIEnv* e, jobject shc, jobject fd, jbyteArray npnProtocols,
- jbyteArray alpnProtocols) {
- NetFd netFd(e, fd);
- if (netFd.isClosed()) {
- return false;
- }
- env = e;
- sslHandshakeCallbacks = shc;
- fileDescriptor = fd;
- if (npnProtocols != NULL) {
- npnProtocolsData = e->GetByteArrayElements(npnProtocols, NULL);
- if (npnProtocolsData == NULL) {
- clearCallbackState();
- return false;
- }
- npnProtocolsArray = npnProtocols;
- npnProtocolsLength = e->GetArrayLength(npnProtocols);
- }
- if (alpnProtocols != NULL) {
- alpnProtocolsData = e->GetByteArrayElements(alpnProtocols, NULL);
- if (alpnProtocolsData == NULL) {
- clearCallbackState();
- return false;
- }
- alpnProtocolsArray = alpnProtocols;
- alpnProtocolsLength = e->GetArrayLength(alpnProtocols);
- }
- return true;
- }
-
- void clearCallbackState() {
- sslHandshakeCallbacks = NULL;
- fileDescriptor = NULL;
- if (npnProtocolsArray != NULL) {
- env->ReleaseByteArrayElements(npnProtocolsArray, npnProtocolsData, JNI_ABORT);
- npnProtocolsArray = NULL;
- npnProtocolsData = NULL;
- npnProtocolsLength = -1;
- }
- if (alpnProtocolsArray != NULL) {
- env->ReleaseByteArrayElements(alpnProtocolsArray, alpnProtocolsData, JNI_ABORT);
- alpnProtocolsArray = NULL;
- alpnProtocolsData = NULL;
- alpnProtocolsLength = -1;
- }
- env = NULL;
- }
-
-};
-
-/**
- * Dark magic helper function that checks, for a given SSL session, whether it
- * can SSL_read() or SSL_write() without blocking. Takes into account any
- * concurrent attempts to close the SSLSocket from the Java side. This is
- * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
- * while thread #2 is sitting in a blocking read or write. The type argument
- * specifies whether we are waiting for readability or writability. It expects
- * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
- * only need to wait in case one of these problems occurs.
- *
- * @param env
- * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
- * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
- * @param appData The application data structure with mutex info etc.
- * @param timeout_millis The timeout value for select call, with the special value
- * 0 meaning no timeout at all (wait indefinitely). Note: This is
- * the Java semantics of the timeout value, not the usual
- * select() semantics.
- * @return The result of the inner select() call,
- * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
- * additional errors
- */
-static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout_millis) {
- // This loop is an expanded version of the NET_FAILURE_RETRY
- // macro. It cannot simply be used in this case because select
- // cannot be restarted without recreating the fd_sets and timeout
- // structure.
- int result;
- fd_set rfds;
- fd_set wfds;
- do {
- NetFd fd(env, fdObject);
- if (fd.isClosed()) {
- result = THROWN_EXCEPTION;
- break;
- }
- int intFd = fd.get();
- JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout_millis=%d",
- (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout_millis);
-
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
-
- if (type == SSL_ERROR_WANT_READ) {
- FD_SET(intFd, &rfds);
- } else {
- FD_SET(intFd, &wfds);
- }
-
- FD_SET(appData->fdsEmergency[0], &rfds);
-
- int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0];
-
- // Build a struct for the timeout data if we actually want a timeout.
- timeval tv;
- timeval* ptv;
- if (timeout_millis > 0) {
- tv.tv_sec = timeout_millis / 1000;
- tv.tv_usec = (timeout_millis % 1000) * 1000;
- ptv = &tv;
- } else {
- ptv = NULL;
- }
-
- AsynchronousSocketCloseMonitor monitor(intFd);
- result = select(maxFd + 1, &rfds, &wfds, NULL, ptv);
- JNI_TRACE("sslSelect %s fd=%d appData=%p timeout_millis=%d => %d",
- (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
- fd.get(), appData, timeout_millis, result);
- if (result == -1) {
- if (fd.isClosed()) {
- result = THROWN_EXCEPTION;
- break;
- }
- if (errno != EINTR) {
- break;
- }
- }
- } while (result == -1);
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- if (result > 0) {
- // We have been woken up by a token in the emergency pipe. We
- // can't be sure the token is still in the pipe at this point
- // because it could have already been read by the thread that
- // originally wrote it if it entered sslSelect and acquired
- // the mutex before we did. Thus we cannot safely read from
- // the pipe in a blocking way (so we make the pipe
- // non-blocking at creation).
- if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
- char token;
- do {
- read(appData->fdsEmergency[0], &token, 1);
- } while (errno == EINTR);
- }
- }
-
- // Tell the world that there is now one thread less waiting for the
- // underlying network.
- appData->waitingThreads--;
-
- MUTEX_UNLOCK(appData->mutex);
-
- return result;
-}
-
-/**
- * Helper function that wakes up a thread blocked in select(), in case there is
- * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
- * before closing the connection.
- *
- * @param data The application data structure with mutex info etc.
- */
-static void sslNotify(AppData* appData) {
- // Write a byte to the emergency pipe, so a concurrent select() can return.
- // Note we have to restore the errno of the original system call, since the
- // caller relies on it for generating error messages.
- int errnoBackup = errno;
- char token = '*';
- do {
- errno = 0;
- write(appData->fdsEmergency[1], &token, 1);
- } while (errno == EINTR);
- errno = errnoBackup;
-}
-
-static AppData* toAppData(const SSL* ssl) {
- return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
-}
-
-/**
- * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
- */
-static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
-{
- /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
- SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx()));
- JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in cert_verify_callback");
- JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
- return 0;
- }
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID
- = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V");
-
- jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted);
-
- const char* authMethod = SSL_authentication_method(ssl);
- JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
- ssl, authMethod);
- jstring authMethodString = env->NewStringUTF(authMethod);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString);
-
- int result = (env->ExceptionCheck()) ? 0 : 1;
- JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
- return result;
-}
-
-/**
- * Call back to watch for handshake to be completed. This is necessary
- * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
- * returns before the handshake is completed in this case.
- */
-static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) {
- JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
-#ifdef WITH_JNI_TRACE
- info_callback_LOG(ssl, where, ret);
-#endif
- if (!(where & SSL_CB_HANDSHAKE_DONE)) {
- JNI_TRACE("ssl=%p info_callback ignored", ssl);
- return;
- }
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in info_callback");
- JNI_TRACE("ssl=%p info_callback env error", ssl);
- return;
- }
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
- return;
- }
-
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V");
-
- JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID);
-
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p info_callback exception", ssl);
- }
- JNI_TRACE("ssl=%p info_callback completed", ssl);
-}
-
-/**
- * Call back to ask for a client certificate. There are three possible exit codes:
- *
- * 1 is success. x509Out and pkeyOut should point to the correct private key and certificate.
- * 0 is unable to find key. x509Out and pkeyOut should be NULL.
- * -1 is error and it doesn't matter what x509Out and pkeyOut are.
- */
-static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
- JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
-
- /* Clear output of key and certificate in case of early exit due to error. */
- *x509Out = NULL;
- *pkeyOut = NULL;
-
- AppData* appData = toAppData(ssl);
- JNIEnv* env = appData->env;
- if (env == NULL) {
- ALOGE("AppData->env missing in client_cert_cb");
- JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
- return 0;
- }
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p client_cert_cb already pending exception => 0", ssl);
- return -1;
- }
- jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
-
- jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
- jmethodID methodID
- = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
-
- // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
- char ssl2_ctype = SSL3_CT_RSA_SIGN;
- const char* ctype = NULL;
- int ctype_num = 0;
- jobjectArray issuers = NULL;
- switch (ssl->version) {
- case SSL2_VERSION:
- ctype = &ssl2_ctype;
- ctype_num = 1;
- break;
- case SSL3_VERSION:
- case TLS1_VERSION:
- case TLS1_1_VERSION:
- case TLS1_2_VERSION:
- case DTLS1_VERSION:
- ctype = ssl->s3->tmp.ctype;
- ctype_num = ssl->s3->tmp.ctype_num;
- issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
- break;
- }
-#ifdef WITH_JNI_TRACE
- for (int i = 0; i < ctype_num; i++) {
- JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
- }
-#endif
-
- jbyteArray keyTypes = env->NewByteArray(ctype_num);
- if (keyTypes == NULL) {
- JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
- return 0;
- }
- env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
-
- JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
- "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
- env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
-
- if (env->ExceptionCheck()) {
- JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
- return -1;
- }
-
- // Check for values set from Java
- X509* certificate = SSL_get_certificate(ssl);
- EVP_PKEY* privatekey = SSL_get_privatekey(ssl);
- int result = 0;
- if (certificate != NULL && privatekey != NULL) {
- *x509Out = certificate;
- *pkeyOut = privatekey;
- result = 1;
- } else {
- // Some error conditions return NULL, so make sure it doesn't linger.
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
- return result;
-}
-
-static RSA* rsaGenerateKey(int keylength) {
- Unique_BIGNUM bn(BN_new());
- if (bn.get() == NULL) {
- return NULL;
- }
- int setWordResult = BN_set_word(bn.get(), RSA_F4);
- if (setWordResult != 1) {
- return NULL;
- }
- Unique_RSA rsa(RSA_new());
- if (rsa.get() == NULL) {
- return NULL;
- }
- int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
- if (generateResult != 1) {
- return NULL;
- }
- return rsa.release();
-}
-
-/**
- * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
- */
-static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
-
- AppData* appData = toAppData(ssl);
- if (appData->ephemeralRsa.get() == NULL) {
- JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
- appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
- }
- JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
- return appData->ephemeralRsa.get();
-}
-
-static DH* dhGenerateParameters(int keylength) {
-
- /*
- * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
- * different options for generating DH keys. One is generating the
- * keys using a single set of DH parameters. However, generating
- * DH parameters is slow enough (minutes) that they suggest doing
- * it once at install time. The other is to generate DH keys from
- * DSA parameters. Generating DSA parameters is faster than DH
- * parameters, but to prevent small subgroup attacks, they needed
- * to be regenerated for each set of DH keys. Setting the
- * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
- * for new DH parameters every type it needs to generate DH keys.
- */
-#if 0
- // Slow path that takes minutes but could be cached
- Unique_DH dh(DH_new());
- if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
- return NULL;
- }
- return dh.release();
-#else
- // Faster path but must have SSL_OP_SINGLE_DH_USE set
- Unique_DSA dsa(DSA_new());
- if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
- return NULL;
- }
- DH* dh = DSA_dup_DH(dsa.get());
- return dh;
-#endif
-}
-
-/**
- * Call back to ask for Diffie-Hellman parameters
- */
-static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
- DH* tmp_dh = dhGenerateParameters(keylength);
- JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
- return tmp_dh;
-}
-
-static EC_KEY* ecGenerateKey(int keylength __attribute__ ((unused))) {
- // TODO selected curve based on keylength
- Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
- if (ec.get() == NULL) {
- return NULL;
- }
- return ec.release();
-}
-
-/**
- * Call back to ask for an ephemeral EC key for TLS_ECDHE_* cipher suites
- */
-static EC_KEY* tmp_ecdh_callback(SSL* ssl __attribute__ ((unused)),
- int is_export __attribute__ ((unused)),
- int keylength) {
- JNI_TRACE("ssl=%p tmp_ecdh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
- AppData* appData = toAppData(ssl);
- if (appData->ephemeralEc.get() == NULL) {
- JNI_TRACE("ssl=%p tmp_ecdh_callback generating ephemeral EC key", ssl);
- appData->ephemeralEc.reset(ecGenerateKey(keylength));
- }
- JNI_TRACE("ssl=%p tmp_ecdh_callback => %p", ssl, appData->ephemeralEc.get());
- return appData->ephemeralEc.get();
-}
-
-/*
- * public static native int SSL_CTX_new();
- */
-static jlong NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
- Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
- if (sslCtx.get() == NULL) {
- throwExceptionIfNecessary(env, "SSL_CTX_new");
- return 0;
- }
- SSL_CTX_set_options(sslCtx.get(),
- SSL_OP_ALL
- // Note: We explicitly do not allow SSLv2 to be used.
- | SSL_OP_NO_SSLv2
- // We also disable session tickets for better compatibility b/2682876
- | SSL_OP_NO_TICKET
- // We also disable compression for better compatibility b/2710492 b/2710497
- | SSL_OP_NO_COMPRESSION
- // Because dhGenerateParameters uses DSA_generate_parameters_ex
- | SSL_OP_SINGLE_DH_USE
- // Because ecGenerateParameters uses a fixed named curve
- | SSL_OP_SINGLE_ECDH_USE);
-
- int mode = SSL_CTX_get_mode(sslCtx.get());
- /*
- * Turn on "partial write" mode. This means that SSL_write() will
- * behave like Posix write() and possibly return after only
- * writing a partial buffer. Note: The alternative, perhaps
- * surprisingly, is not that SSL_write() always does full writes
- * but that it will force you to retry write calls having
- * preserved the full state of the original call. (This is icky
- * and undesirable.)
- */
- mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
-
- // Reuse empty buffers within the SSL_CTX to save memory
- mode |= SSL_MODE_RELEASE_BUFFERS;
-
- SSL_CTX_set_mode(sslCtx.get(), mode);
-
- SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
- SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
- SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
- SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
- SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
- SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback);
-
- JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
- return (jlong) sslCtx.release();
-}
-
-/**
- * public static native void SSL_CTX_free(int ssl_ctx)
- */
-static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
- jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_free(ssl_ctx);
-}
-
-static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
- jlong ssl_ctx_address, jbyteArray sid_ctx)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
- if (ssl_ctx == NULL) {
- return;
- }
-
- ScopedByteArrayRO buf(env, sid_ctx);
- if (buf.get() == NULL) {
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx);
- return;
- }
-
- unsigned int length = buf.size();
- if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "length > SSL_MAX_SSL_SESSION_ID_LENGTH");
- JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length);
- return;
- }
- const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get());
- int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length);
- if (result == 0) {
- throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context");
- return;
- }
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx);
-}
-
-/**
- * public static native int SSL_new(int ssl_ctx) throws SSLException;
- */
-static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
- if (ssl_ctx == NULL) {
- return 0;
- }
- Unique_SSL ssl(SSL_new(ssl_ctx));
- if (ssl.get() == NULL) {
- throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
- "Unable to create SSL structure");
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
- return 0;
- }
-
- /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
- * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
- * (by default disabled), the server will send a certificate which will
- * be checked. The result of the certificate verification process can be
- * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
- * function. The handshake will be continued regardless of the
- * verification result.
- */
- SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
-
- JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
- return (jlong) ssl.release();
-}
-
-
-static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl);
- if (ssl == NULL) {
- return;
- }
-
- long ret = SSL_enable_tls_channel_id(ssl);
- if (ret != 1L) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl);
- return;
- }
-}
-
-static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl);
- if (ssl == NULL) {
- return NULL;
- }
-
- // Channel ID is 64 bytes long. Unfortunately, OpenSSL doesn't declare this length
- // as a constant anywhere.
- jbyteArray javaBytes = env->NewByteArray(64);
- ScopedByteArrayRW bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => NULL", ssl);
- return NULL;
- }
-
- unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
- // Unfortunately, the SSL_get_tls_channel_id method below always returns 64 (upon success)
- // regardless of the number of bytes copied into the output buffer "tmp". Thus, the correctness
- // of this code currently relies on the "tmp" buffer being exactly 64 bytes long.
- long ret = SSL_get_tls_channel_id(ssl, tmp, 64);
- if (ret == 0) {
- // Channel ID either not set or did not verify
- JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => not available", ssl);
- return NULL;
- } else if (ret != 64) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret);
- return NULL;
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id() => %p", ssl, javaBytes);
- return javaBytes;
-}
-
-static void NativeCrypto_SSL_set1_tls_channel_id(JNIEnv* env, jclass,
- jlong ssl_address, jlong pkeyRef)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id privatekey=%p", ssl, pkey);
- if (ssl == NULL) {
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => pkey == null", ssl);
- return;
- }
-
- // SSL_set1_tls_channel_id requires ssl->server to be set to 0.
- // Unfortunately, the default value is 1 and it's only changed to 0 just
- // before the handshake starts (see NativeCrypto_SSL_do_handshake).
- ssl->server = 0;
- long ret = SSL_set1_tls_channel_id(ssl, pkey);
-
- if (ret != 1L) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(
- env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl);
- return;
- }
- // SSL_set1_tls_channel_id expects to take ownership of the EVP_PKEY, but
- // we have an external reference from the caller such as an OpenSSLKey,
- // so we manually increment the reference count here.
- CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
-
- JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => ok", ssl);
-}
-
-static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
- JNI_TRACE("ssl=%p SSL_use_PrivateKey privatekey=%p", ssl, pkey);
- if (ssl == NULL) {
- return;
- }
-
- if (pkey == NULL) {
- jniThrowNullPointerException(env, "pkey == null");
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => pkey == null", ssl);
- return;
- }
-
- int ret = SSL_use_PrivateKey(ssl, pkey);
- if (ret != 1) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl);
- return;
- }
- // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY,
- // but we have an external reference from the caller such as an
- // OpenSSLKey, so we manually increment the reference count here.
- CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
-
- JNI_TRACE("ssl=%p SSL_use_PrivateKey => ok", ssl);
-}
-
-static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray certificates)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
- if (ssl == NULL) {
- return;
- }
-
- if (certificates == NULL) {
- jniThrowNullPointerException(env, "certificates == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
- return;
- }
-
- int length = env->GetArrayLength(certificates);
- if (length == 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
- return;
- }
-
- X509Chain certificatesX509(length);
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jbyteArray> certificate(env,
- reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
- if (certificate.get() == NULL) {
- jniThrowNullPointerException(env, "certificates element == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
- return;
- }
-
- ScopedByteArrayRO buf(env, certificate.get());
- if (buf.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
- return;
- }
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
- certificatesX509[i] = d2i_X509(NULL, &tmp, buf.size());
-
- if (certificatesX509[i] == NULL) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
- return;
- }
- }
-
- int ret = SSL_use_certificate(ssl, certificatesX509[0]);
- if (ret == 1) {
- certificatesX509.release(0);
- } else {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
- return;
- }
-
- Unique_sk_X509 chain(sk_X509_new_null());
- if (chain.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
- return;
- }
- for (int i = 1; i < length; i++) {
- if (!sk_X509_push(chain.get(), certificatesX509.release(i))) {
- jniThrowOutOfMemory(env, "Unable to push certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
- return;
- }
- }
- int chainResult = SSL_use_certificate_chain(ssl, chain.get());
- if (chainResult == 0) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
- ssl);
- return;
- } else {
- OWNERSHIP_TRANSFERRED(chain);
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
-}
-
-static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
- if (ssl == NULL) {
- return;
- }
- int ret = SSL_check_private_key(ssl);
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
-}
-
-static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray principals)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
- if (ssl == NULL) {
- return;
- }
-
- if (principals == NULL) {
- jniThrowNullPointerException(env, "principals == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
- return;
- }
-
- int length = env->GetArrayLength(principals);
- if (length == 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
- return;
- }
-
- Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
- if (principalsStack.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate principal stack");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
- return;
- }
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jbyteArray> principal(env,
- reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
- if (principal.get() == NULL) {
- jniThrowNullPointerException(env, "principals element == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
- return;
- }
-
- ScopedByteArrayRO buf(env, principal.get());
- if (buf.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
- return;
- }
- const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
- Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
-
- if (principalX509Name.get() == NULL) {
- ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
- ssl);
- return;
- }
-
- if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
- jniThrowOutOfMemory(env, "Unable to push principal");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
- return;
- }
- }
-
- SSL_set_client_CA_list(ssl, principalsStack.release());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
-}
-
-/**
- * public static native long SSL_get_mode(int ssl);
- */
-static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
- if (ssl == NULL) {
- return 0;
- }
- long mode = SSL_get_mode(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
- return mode;
-}
-
-/**
- * public static native long SSL_set_mode(int ssl, long mode);
- */
-static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
- jlong ssl_address, jlong mode) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_set_mode(ssl, mode);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_clear_mode(int ssl, long mode);
- */
-static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
- jlong ssl_address, jlong mode) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_clear_mode(ssl, mode);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_get_options(int ssl);
- */
-static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
- jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
- if (ssl == NULL) {
- return 0;
- }
- long options = SSL_get_options(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
- return options;
-}
-
-/**
- * public static native long SSL_set_options(int ssl, long options);
- */
-static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
- jlong ssl_address, jlong options) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_set_options(ssl, options);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * public static native long SSL_clear_options(int ssl, long options);
- */
-static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
- jlong ssl_address, jlong options) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
- if (ssl == NULL) {
- return 0;
- }
- long result = SSL_clear_options(ssl, options);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
- return result;
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
- jlong ssl_address, jobjectArray cipherSuites)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
- if (ssl == NULL) {
- return;
- }
- if (cipherSuites == NULL) {
- jniThrowNullPointerException(env, "cipherSuites == null");
- return;
- }
-
- Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
- if (cipherstack.get() == NULL) {
- jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
- return;
- }
-
- const SSL_METHOD* ssl_method = ssl->method;
- int num_ciphers = ssl_method->num_ciphers();
-
- int length = env->GetArrayLength(cipherSuites);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
- for (int i = 0; i < length; i++) {
- ScopedLocalRef<jstring> cipherSuite(env,
- reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
- ScopedUtfChars c(env, cipherSuite.get());
- if (c.c_str() == NULL) {
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
- bool found = false;
- for (int j = 0; j < num_ciphers; j++) {
- const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
- if ((strcmp(c.c_str(), cipher->name) == 0)
- && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
- if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
- jniThrowOutOfMemory(env, "Unable to push cipher");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
- return;
- }
- found = true;
- }
- }
- if (!found) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "Could not find cipher suite.");
- return;
- }
- }
-
- int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
- if (rc == 0) {
- freeOpenSslErrorState();
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "Illegal cipher suite strings.");
- } else {
- OWNERSHIP_TRANSFERRED(cipherstack);
- }
-}
-
-/**
- * Sets certificate expectations, especially for server to request client auth
- */
-static void NativeCrypto_SSL_set_verify(JNIEnv* env,
- jclass, jlong ssl_address, jint mode)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
- if (ssl == NULL) {
- return;
- }
- SSL_set_verify(ssl, (int)mode, NULL);
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
- jlong ssl_address, jlong ssl_session_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
- if (ssl == NULL) {
- return;
- }
-
- int ret = SSL_set_session(ssl, ssl_session);
- if (ret != 1) {
- /*
- * Translate the error, and throw if it turns out to be a real
- * problem.
- */
- int sslErrorCode = SSL_get_error(ssl, ret);
- if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
- SSL_clear(ssl);
- }
- }
-}
-
-/**
- * Sets the ciphers suites that are enabled in the SSL
- */
-static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
- jlong ssl_address, jboolean creation_enabled)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
- ssl, creation_enabled);
- if (ssl == NULL) {
- return;
- }
- SSL_set_session_creation_enabled(ssl, creation_enabled);
-}
-
-static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
- jlong ssl_address, jstring hostname)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
- ssl, hostname);
- if (ssl == NULL) {
- return;
- }
-
- ScopedUtfChars hostnameChars(env, hostname);
- if (hostnameChars.c_str() == NULL) {
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
- ssl, hostnameChars.c_str());
-
- int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
- return;
- }
- JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
-}
-
-static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
- return env->NewStringUTF(servername);
-}
-
-/**
- * A common selection path for both NPN and ALPN since they're essentially the
- * same protocol. The list of protocols in "primary" is considered the order
- * which should take precedence.
- */
-static int proto_select(SSL* ssl __attribute__ ((unused)),
- unsigned char **out, unsigned char *outLength,
- const unsigned char *primary, const unsigned int primaryLength,
- const unsigned char *secondary, const unsigned int secondaryLength) {
- if (primary != NULL) {
- JNI_TRACE("primary=%p, length=%d", primary, primaryLength);
-
- int status = SSL_select_next_proto(out, outLength, primary, primaryLength, secondary,
- secondaryLength);
- switch (status) {
- case OPENSSL_NPN_NEGOTIATED:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN negotiated", ssl);
- return SSL_TLSEXT_ERR_OK;
- break;
- case OPENSSL_NPN_UNSUPPORTED:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN unsupported", ssl);
- break;
- case OPENSSL_NPN_NO_OVERLAP:
- JNI_TRACE("ssl=%p proto_select NPN/ALPN no overlap", ssl);
- break;
- }
- } else {
- if (out != NULL && outLength != NULL) {
- *out = NULL;
- *outLength = 0;
- }
- JNI_TRACE("protocols=NULL");
- }
- return SSL_TLSEXT_ERR_NOACK;
-}
-
-/**
- * Callback for the server to select an ALPN protocol.
- */
-static int alpn_select_callback(SSL* ssl, const unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen, void *) {
- JNI_TRACE("ssl=%p alpn_select_callback", ssl);
-
- AppData* appData = toAppData(ssl);
- JNI_TRACE("AppData=%p", appData);
-
- return proto_select(ssl, const_cast<unsigned char **>(out), outlen,
- reinterpret_cast<unsigned char*>(appData->alpnProtocolsData),
- appData->alpnProtocolsLength, in, inlen);
-}
-
-/**
- * Callback for the client to select an NPN protocol.
- */
-static int next_proto_select_callback(SSL* ssl, unsigned char** out, unsigned char* outlen,
- const unsigned char* in, unsigned int inlen, void*)
-{
- JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
-
- AppData* appData = toAppData(ssl);
- JNI_TRACE("AppData=%p", appData);
-
- // Enable False Start on the client if the server understands NPN
- // http://www.imperialviolet.org/2012/04/11/falsestart.html
- SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
-
- return proto_select(ssl, out, outlen, in, inlen,
- reinterpret_cast<unsigned char*>(appData->npnProtocolsData),
- appData->npnProtocolsLength);
-}
-
-/**
- * Callback for the server to advertise available protocols.
- */
-static int next_protos_advertised_callback(SSL* ssl,
- const unsigned char **out, unsigned int *outlen, void *)
-{
- JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
- AppData* appData = toAppData(ssl);
- unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
- if (npnProtocols != NULL) {
- *out = npnProtocols;
- *outlen = appData->npnProtocolsLength;
- return SSL_TLSEXT_ERR_OK;
- } else {
- *out = NULL;
- *outlen = 0;
- return SSL_TLSEXT_ERR_NOACK;
- }
-}
-
-static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client
- SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
-}
-
-static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
-{
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return;
- }
- SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client
- SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server
-}
-
-static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
- jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const jbyte* npn;
- unsigned npnLength;
- SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
- if (npnLength == 0) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(npnLength);
- if (result != NULL) {
- env->SetByteArrayRegion(result, 0, npnLength, npn);
- }
- return result;
-}
-
-static int NativeCrypto_SSL_CTX_set_alpn_protos(JNIEnv* env, jclass, jlong ssl_ctx_address,
- jbyteArray protos) {
- SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
- if (ssl_ctx == NULL) {
- return 0;
- }
-
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p", ssl_ctx, protos);
-
- if (protos == NULL) {
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=NULL", ssl_ctx);
- return 1;
- }
-
- ScopedByteArrayRO protosBytes(env, protos);
- if (protosBytes.get() == NULL) {
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => protosBytes == NULL", ssl_ctx,
- protos);
- return 0;
- }
-
- const unsigned char *tmp = reinterpret_cast<const unsigned char*>(protosBytes.get());
- int ret = SSL_CTX_set_alpn_protos(ssl_ctx, tmp, protosBytes.size());
- JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => ret=%d", ssl_ctx, protos, ret);
- return ret;
-}
-
-static jbyteArray NativeCrypto_SSL_get0_alpn_selected(JNIEnv* env, jclass,
- jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p SSL_get0_alpn_selected", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- const jbyte* npn;
- unsigned npnLength;
- SSL_get0_alpn_selected(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
- if (npnLength == 0) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(npnLength);
- if (result != NULL) {
- env->SetByteArrayRegion(result, 0, npnLength, npn);
- }
- return result;
-}
-
-#ifdef WITH_JNI_TRACE_KEYS
-static inline char hex_char(unsigned char in)
-{
- if (in < 10) {
- return '0' + in;
- } else if (in <= 0xF0) {
- return 'A' + in - 10;
- } else {
- return '?';
- }
-}
-
-static void hex_string(char **dest, unsigned char* input, int len)
-{
- *dest = (char*) malloc(len * 2 + 1);
- char *output = *dest;
- for (int i = 0; i < len; i++) {
- *output++ = hex_char(input[i] >> 4);
- *output++ = hex_char(input[i] & 0xF);
- }
- *output = '\0';
-}
-
-static void debug_print_session_key(SSL_SESSION* session)
-{
- char *session_id_str;
- char *master_key_str;
- const char *key_type;
- char *keyline;
-
- hex_string(&session_id_str, session->session_id, session->session_id_length);
- hex_string(&master_key_str, session->master_key, session->master_key_length);
-
- X509* peer = SSL_SESSION_get0_peer(session);
- EVP_PKEY* pkey = X509_PUBKEY_get(peer->cert_info->key);
- switch (EVP_PKEY_type(pkey->type)) {
- case EVP_PKEY_RSA:
- key_type = "RSA";
- break;
- case EVP_PKEY_DSA:
- key_type = "DSA";
- break;
- case EVP_PKEY_EC:
- key_type = "EC";
- break;
- default:
- key_type = "Unknown";
- break;
- }
-
- asprintf(&keyline, "%s Session-ID:%s Master-Key:%s\n", key_type, session_id_str,
- master_key_str);
- JNI_TRACE("ssl_session=%p %s", session, keyline);
-
- free(session_id_str);
- free(master_key_str);
- free(keyline);
-}
-#endif /* WITH_JNI_TRACE_KEYS */
-
-/**
- * Perform SSL handshake
- */
-static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jint timeout_millis, jboolean client_mode, jbyteArray npnProtocols,
- jbyteArray alpnProtocols) {
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
- ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
- if (ssl == NULL) {
- return 0;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
- return 0;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
- return 0;
- }
-
- NetFd fd(env, fdObject);
- if (fd.isClosed()) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
- return 0;
- }
-
- int ret = SSL_set_fd(ssl, fd.get());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
-
- if (ret != 1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
- "Error setting the file descriptor");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
- return 0;
- }
-
- /*
- * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
- * forever and we can use select() to find out if the socket is ready.
- */
- if (!setBlocking(fd.get(), false)) {
- throwSSLExceptionStr(env, "Unable to make socket non blocking");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
- return 0;
- }
-
- /*
- * Create our special application data.
- */
- AppData* appData = AppData::create();
- if (appData == NULL) {
- throwSSLExceptionStr(env, "Unable to create application data");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
- return 0;
- }
-
- SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
- JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
-
- if (client_mode) {
- SSL_set_connect_state(ssl);
- } else {
- SSL_set_accept_state(ssl);
- if (alpnProtocols != NULL) {
- SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, NULL);
- }
- }
-
- ret = 0;
- while (appData->aliveAndKicking) {
- errno = 0;
-
- if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
- return 0;
- }
- ret = SSL_do_handshake(ssl);
- appData->clearCallbackState();
- // cert_verify_callback threw exception
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
- return 0;
- }
- // success case
- if (ret == 1) {
- break;
- }
- // retry case
- if (errno == EINTR) {
- continue;
- }
- // error case
- int sslError = SSL_get_error(ssl, ret);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
- ssl, ret, errno, sslError, timeout_millis);
-
- /*
- * If SSL_do_handshake doesn't succeed due to the socket being
- * either unreadable or unwritable, we use sslSelect to
- * wait for it to become ready. If that doesn't happen
- * before the specified timeout or an error occurs, we
- * cancel the handshake. Otherwise we try the SSL_connect
- * again.
- */
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
-
- if (selectResult == THROWN_EXCEPTION) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
- return 0;
- }
- if (selectResult == -1) {
- throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
- return 0;
- }
- if (selectResult == 0) {
- throwSocketTimeoutException(env, "SSL handshake timed out");
- SSL_clear(ssl);
- freeOpenSslErrorState();
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
- return 0;
- }
- } else {
- // ALOGE("Unknown error %d during handshake", error);
- break;
- }
- }
-
- // clean error. See SSL_do_handshake(3SSL) man page.
- if (ret == 0) {
- /*
- * The other side closed the socket before the handshake could be
- * completed, but everything is within the bounds of the TLS protocol.
- * We still might want to find out the real reason of the failure.
- */
- int sslError = SSL_get_error(ssl, ret);
- if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
- throwSSLExceptionStr(env, "Connection closed by peer");
- } else {
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
- }
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
- return 0;
- }
-
- // unclean error. See SSL_do_handshake(3SSL) man page.
- if (ret < 0) {
- /*
- * Translate the error and throw exception. We are sure it is an error
- * at this point.
- */
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
- return 0;
- }
- SSL_SESSION* ssl_session = SSL_get1_session(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
-#ifdef WITH_JNI_TRACE_KEYS
- debug_print_session_key(ssl_session);
-#endif
- return (jlong) ssl_session;
-}
-
-/**
- * Perform SSL renegotiation
- */
-static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
- if (ssl == NULL) {
- return;
- }
- int result = SSL_renegotiate(ssl);
- if (result != 1) {
- throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
- return;
- }
- // first call asks client to perform renegotiation
- int ret = SSL_do_handshake(ssl);
- if (ret != 1) {
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError,
- "Problem with SSL_do_handshake after SSL_renegotiate");
- return;
- }
- // if client agrees, set ssl state and perform renegotiation
- ssl->state = SSL_ST_ACCEPT;
- SSL_do_handshake(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
-}
-
-/**
- * public static native byte[][] SSL_get_certificate(int ssl);
- */
-static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- X509* certificate = SSL_get_certificate(ssl);
- if (certificate == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- // SSL_get_certificate can return NULL during an error as well.
- freeOpenSslErrorState();
- return NULL;
- }
-
- Unique_sk_X509 chain(sk_X509_new_null());
- if (chain.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
- return NULL;
- }
- if (!sk_X509_push(chain.get(), X509_dup_nocopy(certificate))) {
- jniThrowOutOfMemory(env, "Unable to push local certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- return NULL;
- }
- STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
- for (int i=0; i<sk_X509_num(cert_chain); i++) {
- if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) {
- jniThrowOutOfMemory(env, "Unable to push local certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
- return NULL;
- }
- }
-
- jobjectArray objectArray = getCertificateBytes(env, chain.get());
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
- return objectArray;
-}
-
-// Fills a byte[][] with the peer certificates in the chain.
-static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
- if (ssl == NULL) {
- return NULL;
- }
- STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
- Unique_sk_X509 chain_copy(NULL);
- if (ssl->server) {
- X509* x509 = SSL_get_peer_certificate(ssl);
- if (x509 == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
- return NULL;
- }
- chain_copy.reset(sk_X509_new_null());
- if (chain_copy.get() == NULL) {
- jniThrowOutOfMemory(env, "Unable to allocate peer certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
- return NULL;
- }
- size_t chain_size = sk_X509_num(chain);
- for (size_t i = 0; i < chain_size; i++) {
- if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(sk_X509_value(chain, i)))) {
- jniThrowOutOfMemory(env, "Unable to push server's peer certificate chain");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate chain push error", ssl);
- return NULL;
- }
- }
- if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(x509))) {
- jniThrowOutOfMemory(env, "Unable to push server's peer certificate");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
- return NULL;
- }
- chain = chain_copy.get();
- }
- jobjectArray objectArray = getCertificateBytes(env, chain);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
- return objectArray;
-}
-
-/**
- * Helper function which does the actual reading. The Java layer guarantees that
- * at most one thread will enter this function at any given time.
- *
- * @param ssl non-null; the SSL context
- * @param buf non-null; buffer to read into
- * @param len length of the buffer, in bytes
- * @param sslReturnCode original SSL return code
- * @param sslErrorCode filled in with the SSL error code in case of error
- * @return number of bytes read on success, -1 if the connection was
- * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
- */
-static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode, int read_timeout_millis) {
- JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
-
- if (len == 0) {
- // Don't bother doing anything in this case.
- return 0;
- }
-
- BIO* bio = SSL_get_rbio(ssl);
-
- AppData* appData = toAppData(ssl);
- if (appData == NULL) {
- return THROW_SSLEXCEPTION;
- }
-
- while (appData->aliveAndKicking) {
- errno = 0;
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- MUTEX_UNLOCK(appData->mutex);
- return THROWN_EXCEPTION;
- }
- int result = SSL_read(ssl, buf, len);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
- return THROWN_EXCEPTION;
- }
- int sslError = SSL_ERROR_NONE;
- if (result <= 0) {
- sslError = SSL_get_error(ssl, result);
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError);
-#ifdef WITH_JNI_TRACE_DATA
- for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
- int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
- JNI_TRACE("ssl=%p sslRead data: %d:\n%.*s", ssl, n, n, buf+i);
- }
-#endif
-
- // If we have been successful in moving data around, check whether it
- // might make sense to wake up other blocked threads, so they can give
- // it a try, too.
- if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
- && appData->waitingThreads > 0) {
- sslNotify(appData);
- }
-
- // If we are blocked by the underlying socket, tell the world that
- // there will be one more waiting thread now.
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- }
-
- MUTEX_UNLOCK(appData->mutex);
-
- switch (sslError) {
- // Successfully read at least one byte.
- case SSL_ERROR_NONE: {
- return result;
- }
-
- // Read zero bytes. End of stream reached.
- case SSL_ERROR_ZERO_RETURN: {
- return -1;
- }
-
- // Need to wait for availability of underlying layer, then retry.
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, read_timeout_millis);
- if (selectResult == THROWN_EXCEPTION) {
- return THROWN_EXCEPTION;
- }
- if (selectResult == -1) {
- *sslReturnCode = -1;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- if (selectResult == 0) {
- return THROW_SOCKETTIMEOUTEXCEPTION;
- }
-
- break;
- }
-
- // A problem occurred during a system call, but this is not
- // necessarily an error.
- case SSL_ERROR_SYSCALL: {
- // Connection closed without proper shutdown. Tell caller we
- // have reached end-of-stream.
- if (result == 0) {
- return -1;
- }
-
- // System call has been interrupted. Simply retry.
- if (errno == EINTR) {
- break;
- }
-
- // Note that for all other system call errors we fall through
- // to the default case, which results in an Exception.
- }
-
- // Everything else is basically an error.
- default: {
- *sslReturnCode = result;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- }
- }
-
- return -1;
-}
-
-/**
- * OpenSSL read function (2): read into buffer at offset n chunks.
- * Returns 1 (success) or value <= 0 (failure).
- */
-static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jbyteArray b, jint offset, jint len,
- jint read_timeout_millis)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d",
- ssl, fdObject, shc, b, offset, len, read_timeout_millis);
- if (ssl == NULL) {
- return 0;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
- return 0;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
- return 0;
- }
-
- ScopedByteArrayRW bytes(env, b);
- if (bytes.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
- return 0;
- }
- int returnCode = 0;
- int sslErrorCode = SSL_ERROR_NONE;;
-
- int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
- &returnCode, &sslErrorCode, read_timeout_millis);
-
- int result;
- switch (ret) {
- case THROW_SSLEXCEPTION:
- // See sslRead() regarding improper failure to handle normal cases.
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
- result = -1;
- break;
- case THROW_SOCKETTIMEOUTEXCEPTION:
- throwSocketTimeoutException(env, "Read timed out");
- result = -1;
- break;
- case THROWN_EXCEPTION:
- // SocketException thrown by NetFd.isClosed
- // or RuntimeException thrown by callback
- result = -1;
- break;
- default:
- result = ret;
- break;
- }
-
- JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
- return result;
-}
-
-/**
- * Helper function which does the actual writing. The Java layer guarantees that
- * at most one thread will enter this function at any given time.
- *
- * @param ssl non-null; the SSL context
- * @param buf non-null; buffer to write
- * @param len length of the buffer, in bytes
- * @param sslReturnCode original SSL return code
- * @param sslErrorCode filled in with the SSL error code in case of error
- * @return number of bytes read on success, -1 if the connection was
- * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
- */
-static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
- int* sslReturnCode, int* sslErrorCode, int write_timeout_millis) {
- JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d",
- ssl, buf, len, write_timeout_millis);
-
- if (len == 0) {
- // Don't bother doing anything in this case.
- return 0;
- }
-
- BIO* bio = SSL_get_wbio(ssl);
-
- AppData* appData = toAppData(ssl);
- if (appData == NULL) {
- return THROW_SSLEXCEPTION;
- }
-
- int count = len;
-
- while (appData->aliveAndKicking && ((len > 0) || (ssl->s3->wbuf.left > 0))) {
- errno = 0;
-
- if (MUTEX_LOCK(appData->mutex) == -1) {
- return -1;
- }
-
- unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
-
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- MUTEX_UNLOCK(appData->mutex);
- return THROWN_EXCEPTION;
- }
- JNI_TRACE("ssl=%p sslWrite SSL_write len=%d left=%d", ssl, len, ssl->s3->wbuf.left);
- int result = SSL_write(ssl, buf, len);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
- return THROWN_EXCEPTION;
- }
- int sslError = SSL_ERROR_NONE;
- if (result <= 0) {
- sslError = SSL_get_error(ssl, result);
- freeOpenSslErrorState();
- }
- JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d left=%d",
- ssl, result, sslError, ssl->s3->wbuf.left);
-#ifdef WITH_JNI_TRACE_DATA
- for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
- int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
- JNI_TRACE("ssl=%p sslWrite data: %d:\n%.*s", ssl, n, n, buf+i);
- }
-#endif
-
- // If we have been successful in moving data around, check whether it
- // might make sense to wake up other blocked threads, so they can give
- // it a try, too.
- if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
- && appData->waitingThreads > 0) {
- sslNotify(appData);
- }
-
- // If we are blocked by the underlying socket, tell the world that
- // there will be one more waiting thread now.
- if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
- appData->waitingThreads++;
- }
-
- MUTEX_UNLOCK(appData->mutex);
-
- switch (sslError) {
- // Successfully wrote at least one byte.
- case SSL_ERROR_NONE: {
- buf += result;
- len -= result;
- break;
- }
-
- // Wrote zero bytes. End of stream reached.
- case SSL_ERROR_ZERO_RETURN: {
- return -1;
- }
-
- // Need to wait for availability of underlying layer, then retry.
- // The concept of a write timeout doesn't really make sense, and
- // it's also not standard Java behavior, so we wait forever here.
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE: {
- int selectResult = sslSelect(env, sslError, fdObject, appData, write_timeout_millis);
- if (selectResult == THROWN_EXCEPTION) {
- return THROWN_EXCEPTION;
- }
- if (selectResult == -1) {
- *sslReturnCode = -1;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- if (selectResult == 0) {
- return THROW_SOCKETTIMEOUTEXCEPTION;
- }
-
- break;
- }
-
- // A problem occurred during a system call, but this is not
- // necessarily an error.
- case SSL_ERROR_SYSCALL: {
- // Connection closed without proper shutdown. Tell caller we
- // have reached end-of-stream.
- if (result == 0) {
- return -1;
- }
-
- // System call has been interrupted. Simply retry.
- if (errno == EINTR) {
- break;
- }
-
- // Note that for all other system call errors we fall through
- // to the default case, which results in an Exception.
- }
-
- // Everything else is basically an error.
- default: {
- *sslReturnCode = result;
- *sslErrorCode = sslError;
- return THROW_SSLEXCEPTION;
- }
- }
- }
- JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
-
- return count;
-}
-
-/**
- * OpenSSL write function (2): write into buffer at offset n chunks.
- */
-static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
- jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d",
- ssl, fdObject, shc, b, offset, len, write_timeout_millis);
- if (ssl == NULL) {
- return;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
- return;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
- return;
- }
-
- ScopedByteArrayRO bytes(env, b);
- if (bytes.get() == NULL) {
- JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
- return;
- }
- int returnCode = 0;
- int sslErrorCode = SSL_ERROR_NONE;
- int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
- len, &returnCode, &sslErrorCode, write_timeout_millis);
-
- switch (ret) {
- case THROW_SSLEXCEPTION:
- // See sslWrite() regarding improper failure to handle normal cases.
- throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
- break;
- case THROW_SOCKETTIMEOUTEXCEPTION:
- throwSocketTimeoutException(env, "Write timed out");
- break;
- case THROWN_EXCEPTION:
- // SocketException thrown by NetFd.isClosed
- break;
- default:
- break;
- }
-}
-
-/**
- * Interrupt any pending I/O before closing the socket.
- */
-static void NativeCrypto_SSL_interrupt(
- JNIEnv* env, jclass, jlong ssl_address) {
- SSL* ssl = to_SSL(env, ssl_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
- if (ssl == NULL) {
- return;
- }
-
- /*
- * Mark the connection as quasi-dead, then send something to the emergency
- * file descriptor, so any blocking select() calls are woken up.
- */
- AppData* appData = toAppData(ssl);
- if (appData != NULL) {
- appData->aliveAndKicking = 0;
-
- // At most two threads can be waiting.
- sslNotify(appData);
- sslNotify(appData);
- }
-}
-
-/**
- * OpenSSL close SSL socket function.
- */
-static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address,
- jobject fdObject, jobject shc) {
- SSL* ssl = to_SSL(env, ssl_address, false);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
- if (ssl == NULL) {
- return;
- }
- if (fdObject == NULL) {
- jniThrowNullPointerException(env, "fd == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
- return;
- }
- if (shc == NULL) {
- jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
- return;
- }
-
- AppData* appData = toAppData(ssl);
- if (appData != NULL) {
- if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
- // SocketException thrown by NetFd.isClosed
- SSL_clear(ssl);
- freeOpenSslErrorState();
- return;
- }
-
- /*
- * Try to make socket blocking again. OpenSSL literature recommends this.
- */
- int fd = SSL_get_fd(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
- if (fd != -1) {
- setBlocking(fd, true);
- }
-
- int ret = SSL_shutdown(ssl);
- appData->clearCallbackState();
- // callbacks can happen if server requests renegotiation
- if (env->ExceptionCheck()) {
- SSL_clear(ssl);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
- return;
- }
- switch (ret) {
- case 0:
- /*
- * Shutdown was not successful (yet), but there also
- * is no error. Since we can't know whether the remote
- * server is actually still there, and we don't want to
- * get stuck forever in a second SSL_shutdown() call, we
- * simply return. This is not security a problem as long
- * as we close the underlying socket, which we actually
- * do, because that's where we are just coming from.
- */
- break;
- case 1:
- /*
- * Shutdown was successful. We can safely return. Hooray!
- */
- break;
- default:
- /*
- * Everything else is a real error condition. We should
- * let the Java layer know about this by throwing an
- * exception.
- */
- int sslError = SSL_get_error(ssl, ret);
- throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
- break;
- }
- }
-
- SSL_clear(ssl);
- freeOpenSslErrorState();
-}
-
-/**
- * public static native void SSL_free(int ssl);
- */
-static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address)
-{
- SSL* ssl = to_SSL(env, ssl_address, true);
- JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
- if (ssl == NULL) {
- return;
- }
-
- AppData* appData = toAppData(ssl);
- SSL_set_app_data(ssl, NULL);
- delete appData;
- SSL_free(ssl);
-}
-
-/**
- * Gets and returns in a byte array the ID of the actual SSL session.
- */
-static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
- jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
- if (result != NULL) {
- jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
- env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
- }
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
- ssl_session, result, ssl_session->session_id_length);
- return result;
-}
-
-/**
- * Gets and returns in a long integer the creation's time of the
- * actual SSL session.
- */
-static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
- if (ssl_session == NULL) {
- return 0;
- }
- // result must be jlong, not long or *1000 will overflow
- jlong result = SSL_SESSION_get_time(ssl_session);
- result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
- return result;
-}
-
-/**
- * Gets and returns in a string the version of the SSL protocol. If it
- * returns the string "unknown" it means that no connection is established.
- */
-static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- const char* protocol = SSL_SESSION_get_version(ssl_session);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
- return env->NewStringUTF(protocol);
-}
-
-/**
- * Gets and returns in a string the cipher negotiated for the SSL session.
- */
-static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- const SSL_CIPHER* cipher = ssl_session->cipher;
- const char* name = SSL_CIPHER_get_name(cipher);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
- return env->NewStringUTF(name);
-}
-
-/**
- * Frees the SSL session.
- */
-static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
- if (ssl_session == NULL) {
- return;
- }
- SSL_SESSION_free(ssl_session);
-}
-
-
-/**
- * Serializes the native state of the session (ID, cipher, and keys but
- * not certificates). Returns a byte[] containing the DER-encoded state.
- * See apache mod_ssl.
- */
-static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) {
- SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
- JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
- if (ssl_session == NULL) {
- return NULL;
- }
- return ASN1ToByteArray<SSL_SESSION, i2d_SSL_SESSION>(env, ssl_session);
-}
-
-/**
- * Deserialize the session.
- */
-static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
-
- ScopedByteArrayRO bytes(env, javaBytes);
- if (bytes.get() == NULL) {
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
- return 0;
- }
- const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
- SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
-
- // Initialize SSL_SESSION cipher field based on cipher_id http://b/7091840
- if (ssl_session != NULL) {
- // based on ssl_get_prev_session
- uint32_t cipher_id_network_order = htonl(ssl_session->cipher_id);
- uint8_t* cipher_id_byte_pointer = reinterpret_cast<uint8_t*>(&cipher_id_network_order);
- if (ssl_session->ssl_version >= SSL3_VERSION_MAJOR) {
- cipher_id_byte_pointer += 2; // skip first two bytes for SSL3+
- } else {
- cipher_id_byte_pointer += 1; // skip first byte for SSL2
- }
- ssl_session->cipher = SSLv23_method()->get_cipher_by_char(cipher_id_byte_pointer);
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION cipher_id=%lx hton=%x 0=%x 1=%x cipher=%s",
- ssl_session->cipher_id, cipher_id_network_order,
- cipher_id_byte_pointer[0], cipher_id_byte_pointer[1],
- SSL_CIPHER_get_name(ssl_session->cipher));
- } else {
- freeOpenSslErrorState();
- }
-
- JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
- return reinterpret_cast<uintptr_t>(ssl_session);
-}
-
-static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) {
- return ERR_peek_last_error();
-}
-
-#define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
-#define SSL_CALLBACKS "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto$SSLHandshakeCallbacks;"
-static JNINativeMethod sNativeCryptoMethods[] = {
- NATIVE_METHOD(NativeCrypto, clinit, "()V"),
- NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
- NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(JJ[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)J"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"),
- NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"),
- NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"),
- NATIVE_METHOD(NativeCrypto, RSA_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BJI)I"),
- NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, get_DSA_params, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(JJ[B[B)V"),
- NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(JJJ)Z"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(JJ[B[B)V"),
- NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(JJ)[[B"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(J)J"),
- NATIVE_METHOD(NativeCrypto, ECDH_compute_key, "([BIJJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(J[BI)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(J)J"),
- NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(J[BIJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(J[BIIJ)I"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(JJJ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(J[B)V"),
- NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(JJ[B[BZ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(J[BI[BII)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(J[BI)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(J)I"),
- NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(J)I"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(JZ)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(J)V"),
- NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
- NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
- NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, ("(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream;)J")),
- NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
- NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"),
- NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"),
- NATIVE_METHOD(NativeCrypto, BIO_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_NAME_print_ex, "(JJ)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, d2i_X509_bio, "(J)J"),
- NATIVE_METHOD(NativeCrypto, d2i_X509, "([B)J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_PUBKEY, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509, "(J)J"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_PKCS7, "(JI)[J"),
- NATIVE_METHOD(NativeCrypto, d2i_PKCS7_bio, "(JI)[J"),
- NATIVE_METHOD(NativeCrypto, i2d_PKCS7, "([J)[B"),
- NATIVE_METHOD(NativeCrypto, ASN1_seq_unpack_X509_bio, "(J)[J"),
- NATIVE_METHOD(NativeCrypto, ASN1_seq_pack_X509, "([J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_cmp, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, get_X509_hashCode, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_print_ex, "(JJJJ)V"),
- NATIVE_METHOD(NativeCrypto, X509_get_pubkey, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_issuer_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_get_subject_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_pubkey_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_parameter, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_issuerUID, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_subjectUID, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_kusage, "(J)[Z"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_xkusage, "(J)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_pathlen, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_crl_enc, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_verify, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_lastUpdate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_nextUpdate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext_oid, "(JLjava/lang/String;)[B"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_serialNumber, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_print, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_revocationDate, "(J)J"),
- NATIVE_METHOD(NativeCrypto, get_X509_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_ext_oids, "(JI)[Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_GENERAL_NAME_stack, "(JI)[[Ljava/lang/Object;"),
- NATIVE_METHOD(NativeCrypto, X509_get_notBefore, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_notAfter, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_version, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_get_serialNumber, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_verify, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_cert_info_enc, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"),
- NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"),
- NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"),
- NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_serial, "(J[B)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_REVOKED, "(J)[J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_CRL, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_print, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_oid, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_parameter, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_issuer_name, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_version, "(J)J"),
- NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext, "(JLjava/lang/String;)J"),
- NATIVE_METHOD(NativeCrypto, X509_REVOKED_dup, "(J)J"),
- NATIVE_METHOD(NativeCrypto, i2d_X509_REVOKED, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, X509_supported_extension, "(J)I"),
- NATIVE_METHOD(NativeCrypto, ASN1_TIME_to_Calendar, "(JLjava/util/Calendar;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_set1_tls_channel_id, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"),
- NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"),
- NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B[B)I"),
- NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[[B"),
- NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
- NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
- NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
- NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"),
- NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"),
- NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"),
- NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, SSL_CTX_set_alpn_protos, "(J[B)I"),
- NATIVE_METHOD(NativeCrypto, SSL_get0_alpn_selected, "(J)[B"),
- NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"),
-};
-
-static void initialize_conscrypt(JNIEnv* env) {
- jniRegisterNativeMethods(env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto",
- sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
-
- ScopedLocalRef<jclass> localClass(env,
- env->FindClass(TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream"));
- openSslOutputStreamClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
- if (openSslOutputStreamClass == NULL) {
- ALOGE("failed to find class OpenSSLBIOInputStream");
- abort();
- }
-
- calendar_setMethod = env->GetMethodID(calendarClass, "set", "(IIIIII)V");
- inputStream_readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
- integer_valueOfMethod = env->GetStaticMethodID(integerClass, "valueOf",
- "(I)Ljava/lang/Integer;");
- openSslInputStream_readLineMethod = env->GetMethodID(openSslOutputStreamClass, "gets",
- "([B)I");
- outputStream_writeMethod = env->GetMethodID(outputStreamClass, "write", "([B)V");
- outputStream_flushMethod = env->GetMethodID(outputStreamClass, "flush", "()V");
-}
-
-static jclass findClass(JNIEnv* env, const char* name) {
- ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
- jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
- if (result == NULL) {
- ALOGE("failed to find class '%s'", name);
- abort();
- }
- return result;
-}
-
-// Use JNI_OnLoad for when we're standalone
-int JNI_OnLoad(JavaVM *vm, void*) {
- JNI_TRACE("JNI_OnLoad NativeCrypto");
- gJavaVM = vm;
-
- JNIEnv *env;
- if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
- ALOGE("Could not get JNIEnv");
- return JNI_ERR;
- }
-
- byteArrayClass = findClass(env, "[B");
- calendarClass = findClass(env, "java/util/Calendar");
- inputStreamClass = findClass(env, "java/io/InputStream");
- integerClass = findClass(env, "java/lang/Integer");
- objectClass = findClass(env, "java/lang/Object");
- objectArrayClass = findClass(env, "[Ljava/lang/Object;");
- outputStreamClass = findClass(env, "java/io/OutputStream");
- stringClass = findClass(env, "java/lang/String");
-
- initialize_conscrypt(env);
- return JNI_VERSION_1_6;
-}
diff --git a/crypto/src/main/native/sub.mk b/crypto/src/main/native/sub.mk
deleted file mode 100644
index 62f8672..0000000
--- a/crypto/src/main/native/sub.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- mode: makefile -*-
-# This file is included by the top-level libcore Android.mk.
-# It's not a normal makefile, so we don't include CLEAR_VARS
-# or BUILD_*_LIBRARY.
-
-LOCAL_SRC_FILES := \
- org_conscrypt_NativeCrypto.cpp
-
-LOCAL_C_INCLUDES += \
- libcore/luni/src/main/native
-
-# Any shared/static libs that are listed here must also
-# be listed in libs/nativehelper/Android.mk.
-# TODO: fix this requirement
-
-#LOCAL_SHARED_LIBRARIES +=
-
-#LOCAL_STATIC_LIBRARIES +=
diff --git a/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java b/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java
deleted file mode 100644
index 04890f6..0000000
--- a/crypto/src/test/java/org/conscrypt/CertPinManagerTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class CertPinManagerTest extends TestCase {
-
- private X509Certificate[] chain;
- private List<X509Certificate> shortChain;
- private List<X509Certificate> longChain;
- private String shortPin;
- private String longPin;
- private List<File> tmpFiles = new ArrayList<File>();
-
- private String writeTmpPinFile(String text) throws Exception {
- File tmp = File.createTempFile("pins", null);
- FileWriter fstream = new FileWriter(tmp);
- fstream.write(text);
- fstream.close();
- tmpFiles.add(tmp);
- return tmp.getPath();
- }
-
- private static String getFingerprint(X509Certificate cert) throws NoSuchAlgorithmException {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // build some valid chains
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- chain = (X509Certificate[]) pke.getCertificateChain();
- X509Certificate root = chain[2];
- X509Certificate server = chain[0];
-
- // build the short and long chains
- shortChain = new ArrayList<X509Certificate>();
- shortChain.add(root);
- longChain = new ArrayList<X509Certificate>();
- longChain.add(server);
-
- // we'll use the root as the pin for the short entry and the server as the pin for the long
- shortPin = getFingerprint(root);
- longPin = getFingerprint(server);
- }
-
- @Override
- public void tearDown() throws Exception {
- try {
- for (File f : tmpFiles) {
- f.delete();
- }
- tmpFiles.clear();
- } finally {
- super.tearDown();
- }
- }
-
- public void testPinFileMaximumLookup() throws Exception {
-
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
- String longEntry = "*.clients.google.com=true|" + longPin;
-
- // create the pinFile
- String path = writeTmpPinFile(shortEntry + "\n" + longEntry);
- CertPinManager pf = new CertPinManager(path, new TrustedCertificateStore());
-
- // verify that the shorter chain doesn't work for a name matching the longer
- assertTrue("short chain long uri failed",
- pf.chainIsNotPinned("android.clients.google.com", shortChain));
- // verify that the longer chain doesn't work for a name matching the shorter
- assertTrue("long chain short uri failed",
- pf.chainIsNotPinned("android.google.com", longChain));
- // verify that the shorter chain works for the shorter domain
- assertTrue("short chain short uri failed",
- !pf.chainIsNotPinned("android.google.com", shortChain));
- // and the same for the longer
- assertTrue("long chain long uri failed",
- !pf.chainIsNotPinned("android.clients.google.com", longChain));
- }
-
- public void testPinEntryMalformedEntry() throws Exception {
- // set up the pinEntry with a bogus entry
- String entry = "*.google.com=";
- try {
- new PinListEntry(entry, new TrustedCertificateStore());
- fail("Accepted an empty pin list entry.");
- } catch (PinEntryException expected) {
- }
- }
-
- public void testPinEntryNull() throws Exception {
- // set up the pinEntry with a bogus entry
- String entry = null;
- try {
- new PinListEntry(entry, new TrustedCertificateStore());
- fail("Accepted a basically wholly bogus entry.");
- } catch (NullPointerException expected) {
- }
- }
-
- public void testPinEntryEmpty() throws Exception {
- // set up the pinEntry with a bogus entry
- try {
- new PinListEntry("", new TrustedCertificateStore());
- fail("Accepted an empty entry.");
- } catch (PinEntryException expected) {
- }
- }
-
- public void testPinEntryPinFailure() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
-
- // set up the pinEntry with a pinlist that doesn't match what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertTrue("Not enforcing!", e.getEnforcing());
- // verify that it doesn't accept
- boolean retval = e.chainIsNotPinned(longChain);
- assertTrue("Accepted an incorrect pinning, this is very bad", retval);
- }
-
- public void testPinEntryPinSuccess() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=true|" + shortPin;
-
- // set up the pinEntry with a pinlist that matches what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertTrue("Not enforcing!", e.getEnforcing());
- // verify that it accepts
- boolean retval = e.chainIsNotPinned(shortChain);
- assertTrue("Failed on a correct pinning, this is very bad", !retval);
- }
-
- public void testPinEntryNonEnforcing() throws Exception {
- // write a pinfile with two entries, one longer than the other
- String shortEntry = "*.google.com=false|" + shortPin;
-
- // set up the pinEntry with a pinlist that matches what we'll give it
- PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
- assertFalse("Enforcing!", e.getEnforcing());
- // verify that it accepts
- boolean retval = e.chainIsNotPinned(shortChain);
- assertTrue("Failed on an unenforced pinning, this is bad-ish", !retval);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java b/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java
deleted file mode 100644
index 7663789..0000000
--- a/crypto/src/test/java/org/conscrypt/ChainStrengthAnalyzerTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import junit.framework.TestCase;
-
-public class ChainStrengthAnalyzerTest extends TestCase {
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:2048 -sha256 -keyout k.pem -out good.pem
- private static final String GOOD_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIDYTCCAkmgAwIBAgIJAPFX8KGuEZcgMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQ0MTBaFw0xMzEwMTUyMTQ0MTBa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
- "ADCCAQoCggEBAM44hz3eTINuAIS9OYmg6DkUIj3MItn5dgbcMEdbXrhNpeWY93ho\n" +
- "WQFfsqcSSx28NzqKJmnX+cyinzIUfVde/qciP9P7fxRDokRsf34DJ6gXQplz6P2t\n" +
- "s4CWjYM+WXJrvEUgLUQ3CBV0CCrtYvG1B9wYsBdAdWkVaMxTvEt7aVxcvJYzp+KU\n" +
- "ME7HDg0PVxptvUExIskcqKVmW7i748AgBLhd0r1nFWLuH20d42Aowja0Wi19fWl2\n" +
- "SEMErDRjG8jIPUdSoOLPVLGTktEpex51xnAaZ+I7hy6zs55dq8ua/hE/v2cXIkiQ\n" +
- "ZXpWyvI/MaKEfeydLnNpa7J3GpH3KW93HQcCAwEAAaNQME4wHQYDVR0OBBYEFA0M\n" +
- "RI+3hIPCSpVVArisr3Y3/sheMB8GA1UdIwQYMBaAFA0MRI+3hIPCSpVVArisr3Y3\n" +
- "/sheMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFgUNyuy2qaJvgDO\n" +
- "plYudTrJR38O3id1B5oKOzgTEgRrfmHHfyloY4fL5gjAGNp7vdlDKSHC2Ebo23/X\n" +
- "Wg535MJ2296R855jaTMdkSE0+4ASpdmon1D007H0FhLyojlKVta3pqMAF1zsp0YF\n" +
- "Mf3V/rVMDxCOnbSnqAX0+1nW8Qm4Jgrr3AAMafZk6ypq0xuNQn+sUWuIWw3Xv5Jl\n" +
- "KehjnuKtMgVYkn2ItRNnUdhm2dQK+Phdb5Yg8WHXN/r9sZQdORg8FQS9TfQJmimB\n" +
- "CVYuqA9Dt0JJZPuO/Pd1yAxWP4NpxX1xr3lNQ5jrTO702QA3gOrscluULLzrYR50\n" +
- "FoAjeos=\n" +
- "-----END CERTIFICATE-----";
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:2048 -md5 -keyout k.pem -out md5.pem
- private static final String MD5_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIDYTCCAkmgAwIBAgIJAJsffMf2cyx0MA0GCSqGSIb3DQEBBAUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMzZaFw0xMzEwMTUyMTQzMzZa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" +
- "ADCCAQoCggEBAOJyiUwgf/VsdbTTdx6dsb742adeBFBY1FpSWCeQW/JVtdMephbK\n" +
- "AA00nu8Xq3dNx9bp8AqvzeyHi/RBsZOtb2eAsOXE3RbFy28ehDTHdG34fRQNT6kp\n" +
- "RUHw8wrUGovMVqS8j+iW8HfAy3sjArje0ygz2NIETlNQbEOifAJtY+AEfZwZE0/0\n" +
- "IMVP4hwTmIgyReJBDmAx31clwsWZSPar9x+WQfeJ3rfy5LBCtf3RUbdgnvynBHFk\n" +
- "FjucwoqgOOXviCWxIa0F+ZAmZJBj5+pLN/V92RXOu0c2fR3Mf68J67OJ+K4ueo1N\n" +
- "nBhRsulWMmGqIVjYOZQxiNzWYcOVXj3DTRMCAwEAAaNQME4wHQYDVR0OBBYEFJbY\n" +
- "TU06RuJaiMBs2vzx5y0MbaQOMB8GA1UdIwQYMBaAFJbYTU06RuJaiMBs2vzx5y0M\n" +
- "baQOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBAFEky0jLTmKefDVX\n" +
- "8O84KoupmQ2qQQBaQF3F5GEuhi0qJRwnmsWkCmsxPP55S67WDFp3JH+LX14UxL4T\n" +
- "fbG2CXHt/BF1yU3Z8JBwx3bDmfUnUOAFkO3nmByb11FyZTHMzq4jp03DexWREv4q\n" +
- "Ai5+5Xb56VECgCH/hnGqhQeFGhlZUcSXobVhAU+39L6azWELXxk1K4bpVxYFGn1N\n" +
- "uZ+dWmb6snPKDzG6J5IIX8QIs6G8H6ptj+QNoU/qTcZEnuzMJxpqMsyq10AA+bY/\n" +
- "VAYyXeZm3XZrtqYosDeiUdmcL0jjmyQtyOcAoVUQWj1EJuRjXg4BvI6xxRAIPWYT\n" +
- "EDeWHJE=\n" +
- "-----END CERTIFICATE-----";
-
- //openssl req -x509 -nodes -days 365 -subj '/C=US/ST=Testsota/L=Testville/CN=test.com' \
- //-newkey rsa:512 -sha256 -keyout k.pem -out short.pem
- private static final String SHORT_PEM = "" +
- "-----BEGIN CERTIFICATE-----\n" +
- "MIIB1zCCAYGgAwIBAgIJAOxaz9TreDNIMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV\n" +
- "BAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVzdHZpbGxlMREw\n" +
- "DwYDVQQDDAh0ZXN0LmNvbTAeFw0xMjEwMTUyMTQzMjNaFw0xMzEwMTUyMTQzMjNa\n" +
- "MEcxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhUZXN0c290YTESMBAGA1UEBwwJVGVz\n" +
- "dHZpbGxlMREwDwYDVQQDDAh0ZXN0LmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC\n" +
- "QQCoMgxK9HG0L+hXEht1mKq6ApN3+3lmIEVUcWQKL7EMmn9+L6rVSJyOAGwpTVG7\n" +
- "eZ5uulC0Lkm5/bzKFSrCf1jlAgMBAAGjUDBOMB0GA1UdDgQWBBTda66RZsgUvR4e\n" +
- "2RSsq65K1xcz0jAfBgNVHSMEGDAWgBTda66RZsgUvR4e2RSsq65K1xcz0jAMBgNV\n" +
- "HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA0EAZWYgoNDn6yEzcmWgsYnG3w2BT6fL\n" +
- "Npi0+APKWkwxnEJk1kgpdeSTMgaHAphQ8qksHnSgeBAJSs2ZCQMinVPgOg==\n" +
- "-----END CERTIFICATE-----";
-
- public void testMD5() throws Exception {
- assertBad(MD5_PEM, "Weak hash check did not fail as expected");
- }
-
- public void test512() throws Exception {
- assertBad(SHORT_PEM, "Short modulus check did not fail as expected");
- }
-
- public void testGoodChain() throws Exception {
- assertGood(GOOD_PEM);
- }
-
- private static void assertBad(String pem, String msg) throws Exception {
- try {
- check(createCert(pem));
- fail(msg);
- } catch (CertificateException expected) {
- }
- }
-
- private static void assertGood(String pem) throws Exception {
- check(createCert(pem));
- }
-
- private static void check(X509Certificate cert) throws Exception {
- X509Certificate[] chain = {cert};
- ChainStrengthAnalyzer.check(chain);
- }
-
- private static X509Certificate createCert(String pem) throws Exception {
- CertificateFactory cf = CertificateFactory.getInstance("X509");
- InputStream pemInput = new ByteArrayInputStream(pem.getBytes());
- return (X509Certificate) cf.generateCertificate(pemInput);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java b/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java
deleted file mode 100644
index 3255de8..0000000
--- a/crypto/src/test/java/org/conscrypt/CipherSuiteTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import junit.framework.TestCase;
-import libcore.java.security.StandardNames;
-
-public class CipherSuiteTest extends TestCase {
- public void test_getByName() throws Exception {
- for (String name : StandardNames.CIPHER_SUITES) {
- if (name.equals(StandardNames.CIPHER_SUITE_SECURE_RENEGOTIATION)
- || name.equals(StandardNames.CIPHER_SUITE_FALLBACK)) {
- assertNull(CipherSuite.getByName(name));
- } else {
- test_CipherSuite(name);
- }
- }
-
- assertNull(CipherSuite.getByName("bogus"));
- try {
- CipherSuite.getByName(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- private void test_CipherSuite(String name) throws Exception {
- CipherSuite cs = CipherSuite.getByName(name);
- assertNotNull(name, cs);
- assertEquals(name, cs.getName());
- test_CipherSuite(cs);
- }
-
- private void test_CipherSuite(CipherSuite cs) throws Exception {
- assertNotNull(cs);
-
- String name = cs.getName();
- assertNotNull(name);
- assertSame(name, cs, CipherSuite.getByName(name));
- assertTrue(name, StandardNames.CIPHER_SUITES.contains(name));
- assertTrue(name, name.startsWith("SSL_") || name.startsWith("TLS_"));
-
- assertEquals(cs.isAnonymous(), name.contains("_anon_"));
-
- byte[] bytes = cs.toBytes();
- assertNotNull(name, bytes);
- assertEquals(name, 2, bytes.length);
- assertTrue(name + bytes[0], bytes[0] == (byte) 0x00 || bytes[0] == (byte) 0xc0);
- assertSame(name, cs, CipherSuite.getByCode(bytes[0], bytes[1]));
- assertSame(name, cs, CipherSuite.getByCode((byte) 0, bytes[0], bytes[1]));
-
- assertTrue(name, cs.toString().contains(name));
-
- String bulkEncryptionAlgorithm = cs.getBulkEncryptionAlgorithm();
- int blockSize = cs.getBlockSize();
- if (bulkEncryptionAlgorithm == null) {
- assertTrue(name, name.contains("_NULL_"));
- assertEquals(name, 0, blockSize);
- } else {
- assertNotNull(name, Cipher.getInstance(cs.getBulkEncryptionAlgorithm()));
- assertTrue(name, blockSize == 0 || blockSize == 8 || blockSize == 16);
- }
-
- String hmacName = cs.getHmacName();
- assertNotNull(name, hmacName);
- assertNotNull(name, Mac.getInstance(hmacName));
-
- String hashName = cs.getHashName();
- assertNotNull(name, hashName);
- assertNotNull(name, MessageDigest.getInstance(hashName));
-
- int macLength = cs.getMACLength();
- assertTrue(name, macLength == 0 || macLength == 16 || macLength == 20);
-
- assertTrue(name,
- cs.isExportable() == name.contains("_EXPORT_")
- || cs.isExportable() == name.contains("_NULL_"));
-
- String keyType = cs.getServerKeyType();
- assertEquals(name, cs.isAnonymous(), keyType == null);
- assertTrue(name, keyType == null || StandardNames.KEY_TYPES.contains(keyType));
- }
-
- public void test_getByCode() {
- // CipherSuite.getByCode is also covered by test_CipherSuite
- assertUnknown(CipherSuite.getByCode((byte) 0x12, (byte) 0x34));
- assertUnknown(CipherSuite.getByCode((byte) 0x12, (byte) 0x34, (byte) 0x56));
- assertUnknown(CipherSuite.getByCode((byte) -1, (byte) -1));
- assertUnknown(CipherSuite.getByCode((byte) -1, (byte) -1, (byte) -1));
- }
- private void assertUnknown(CipherSuite cs) {
- assertNotNull(cs);
- assertNotNull(cs.getName().contains("UNKNOWN"));
- }
-
- public void test_getSupported() throws Exception {
- CipherSuite[] suites = CipherSuite.getSupported();
- List<String> names = new ArrayList<String>(suites.length);
- for (CipherSuite cs : suites) {
- test_CipherSuite(cs);
- names.add(cs.getName());
- }
- assertEquals(Arrays.asList(CipherSuite.getSupportedCipherSuiteNames()), names);
- }
-
- public void test_getSupportedCipherSuiteNames() throws Exception {
- String[] names = CipherSuite.getSupportedCipherSuiteNames();
- StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE, names);
- for (String name : names) {
- test_CipherSuite(name);
- }
- }
-
- public void test_getClientKeyType() throws Exception {
- byte b = Byte.MIN_VALUE;
- do {
- String byteString = Byte.toString(b);
- String keyType = CipherSuite.getClientKeyType(b);
- switch (b) {
- case 1:
- assertEquals(byteString, "RSA", keyType);
- break;
- case 2:
- assertEquals(byteString, "DSA", keyType);
- break;
- case 3:
- assertEquals(byteString, "DH_RSA", keyType);
- break;
- case 4:
- assertEquals(byteString, "DH_DSA", keyType);
- break;
- case 64:
- assertEquals(byteString, "EC", keyType);
- break;
- case 65:
- assertEquals(byteString, "EC_RSA", keyType);
- break;
- case 66:
- assertEquals(byteString, "EC_EC", keyType);
- break;
- default:
- assertNull(byteString, keyType);
- }
- b++;
- } while (b != Byte.MIN_VALUE);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java b/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java
deleted file mode 100644
index 93037db..0000000
--- a/crypto/src/test/java/org/conscrypt/ClientSessionContextTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import javax.net.ssl.SSLSession;
-import junit.framework.TestCase;
-import libcore.javax.net.ssl.FakeSSLSession;
-
-public final class ClientSessionContextTest extends TestCase {
-
- public void testSimpleAddition() {
- ClientSessionContext context = new ClientSessionContext();
- SSLSession a = new ValidSSLSession("a");
- SSLSession b = new ValidSSLSession("b");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[0]);
- }
-
- public void testTrimToSize() {
- ClientSessionContext context = new ClientSessionContext();
- ValidSSLSession a = new ValidSSLSession("a");
- ValidSSLSession b = new ValidSSLSession("b");
- ValidSSLSession c = new ValidSSLSession("c");
- ValidSSLSession d = new ValidSSLSession("d");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d });
-
- context.putSession(c);
- assertSessionContextContents(context, new SSLSession[] { a, b, c }, new SSLSession[] { d });
-
- context.putSession(d);
- assertSessionContextContents(context, new SSLSession[] { a, b, c, d }, new SSLSession[0]);
-
- context.setSessionCacheSize(2);
- assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b });
- }
-
- public void testImplicitRemovalOfOldest() {
- ClientSessionContext context = new ClientSessionContext();
- context.setSessionCacheSize(2);
- ValidSSLSession a = new ValidSSLSession("a");
- ValidSSLSession b = new ValidSSLSession("b");
- ValidSSLSession c = new ValidSSLSession("c");
- ValidSSLSession d = new ValidSSLSession("d");
-
- context.putSession(a);
- assertSessionContextContents(context, new SSLSession[] { a }, new SSLSession[] { b, c, d });
-
- context.putSession(b);
- assertSessionContextContents(context, new SSLSession[] { a, b }, new SSLSession[] { c, d });
-
- context.putSession(c);
- assertSessionContextContents(context, new SSLSession[] { b, c }, new SSLSession[] { a, d });
-
- context.putSession(d);
- assertSessionContextContents(context, new SSLSession[] { c, d }, new SSLSession[] { a, b });
- }
-
- private static void assertSessionContextContents(ClientSessionContext context,
- SSLSession[] contains,
- SSLSession[] exludes) {
- assertEquals(contains.length, context.size());
-
- for (SSLSession s : contains) {
- assertSame(s.getPeerHost(), s, context.getSession(s.getId()));
- assertSame(s.getPeerHost(), s, context.getSession(s.getPeerHost(), 443));
- }
- for (SSLSession s : exludes) {
- assertNull(s.getPeerHost(), context.getSession(s.getId()));
- assertNull(s.getPeerHost(), context.getSession(s.getPeerHost(), 443));
- }
-
- Set<SSLSession> sessions = new HashSet<SSLSession>();
- Enumeration<byte[]> ids = context.getIds();
- while (ids.hasMoreElements()) {
- byte[] id = ids.nextElement();
- sessions.add(context.getSession(id));
- }
-
- Set<SSLSession> expected = new HashSet<SSLSession>();
- for (SSLSession s : sessions) {
- expected.add(s);
- }
- assertEquals(expected, sessions);
- }
-
- static class ValidSSLSession extends FakeSSLSession {
- ValidSSLSession(String host) {
- super(host);
- }
- @Override public boolean isValid() {
- return true;
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java b/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java
deleted file mode 100644
index 9d7e2ec..0000000
--- a/crypto/src/test/java/org/conscrypt/FileClientSessionCacheTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.IOException;
-import junit.framework.TestCase;
-import libcore.javax.net.ssl.FakeSSLSession;
-
-public class FileClientSessionCacheTest extends TestCase {
-
- public void testMaxSize() throws IOException, InterruptedException {
- String tmpDir = System.getProperty("java.io.tmpdir");
- if (tmpDir == null) {
- fail("Please set 'java.io.tmpdir' system property.");
- }
- File cacheDir = new File(tmpDir
- + "/" + FileClientSessionCacheTest.class.getName() + "/cache");
- final SSLClientSessionCache cache
- = FileClientSessionCache.usingDirectory(cacheDir);
- Thread[] threads = new Thread[10];
- final int iterations = FileClientSessionCache.MAX_SIZE * 10;
- for (int i = 0; i < threads.length; i++) {
- final int id = i;
- threads[i] = new Thread() {
- @Override
- public void run() {
- for (int i = 0; i < iterations; i++) {
- cache.putSessionData(new FakeSSLSession(id + "" + i), new byte[10]);
- }
- }
- };
- }
- for (Thread thread : threads) {
- thread.start();
- }
- for (Thread thread : threads) {
- thread.join();
- }
- assertEquals(FileClientSessionCache.MAX_SIZE, cacheDir.list().length);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/MacTest.java b/crypto/src/test/java/org/conscrypt/MacTest.java
deleted file mode 100644
index 304ecdb..0000000
--- a/crypto/src/test/java/org/conscrypt/MacTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import junit.framework.TestCase;
-
-public class MacTest extends TestCase {
- public void test_getInstance_OpenSSL_ENGINE() throws Exception {
- final String secret = "-HMAC-test1";
- final byte[] testString = "testing123".getBytes();
-
- Provider p = Security.getProvider(OpenSSLProvider.PROVIDER_NAME);
- NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
-
- /*
- * The "-HMAC-" prefix is a special prefix recognized by
- * test_openssl_engine.cpp
- */
- SecretKey key1 = engine.getSecretKeyById(secret, "HmacSHA256");
- SecretKey key1dupe = engine.getSecretKeyById(secret, "HmacSHA256");
-
- /* Non-ENGINE-based SecretKey */
- SecretKey key2 = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
-
- /* The one that is ENGINE-based can't be equal to a non-ENGINE one. */
- assertFalse(key1.equals(key2));
- assertEquals(key1, key1dupe);
- assertNull(key1.getFormat());
- assertNull(key1.getEncoded());
- assertEquals("RAW", key2.getFormat());
- assertEquals(Arrays.toString(secret.getBytes()), Arrays.toString(key2.getEncoded()));
-
- Mac mac1 = Mac.getInstance("HmacSHA256", p);
- mac1.init(key1);
- mac1.update(testString);
- byte[] output1 = mac1.doFinal();
- assertEquals(mac1.getMacLength(), output1.length);
-
- Mac mac2 = Mac.getInstance("HmacSHA256", p);
- mac2.init(key2);
- mac2.update(testString);
- byte[] output2 = mac2.doFinal();
-
- assertEquals(Arrays.toString(output2), Arrays.toString(output1));
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java b/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java
deleted file mode 100644
index ca5f498..0000000
--- a/crypto/src/test/java/org/conscrypt/NativeCryptoTest.java
+++ /dev/null
@@ -1,2629 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import dalvik.system.BaseDexClassLoader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketTimeoutException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.KeyStore.PrivateKeyEntry;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateCrtKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.ECPrivateKeySpec;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLProtocolException;
-import javax.security.auth.x500.X500Principal;
-import junit.framework.TestCase;
-import libcore.io.IoUtils;
-import libcore.java.security.StandardNames;
-import libcore.java.security.TestKeyStore;
-import org.conscrypt.NativeCrypto.SSLHandshakeCallbacks;
-import static org.conscrypt.NativeCrypto.SSL_MODE_HANDSHAKE_CUTTHROUGH;
-
-public class NativeCryptoTest extends TestCase {
- /** Corresponds to the native test library "libjavacoretests.so" */
- public static final String TEST_ENGINE_ID = "javacoretests";
-
- private static final long NULL = 0;
- private static final FileDescriptor INVALID_FD = new FileDescriptor();
- private static final SSLHandshakeCallbacks DUMMY_CB
- = new TestSSLHandshakeCallbacks(null, 0, null);
-
- private static final long TIMEOUT_SECONDS = 5;
-
- private static OpenSSLKey SERVER_PRIVATE_KEY;
- private static byte[][] SERVER_CERTIFICATES;
- private static OpenSSLKey CLIENT_PRIVATE_KEY;
- private static byte[][] CLIENT_CERTIFICATES;
- private static byte[][] CA_PRINCIPALS;
- private static OpenSSLKey CHANNEL_ID_PRIVATE_KEY;
- private static byte[] CHANNEL_ID;
-
- @Override
- protected void tearDown() throws Exception {
- assertEquals(0, NativeCrypto.ERR_peek_last_error());
- }
-
- private static OpenSSLKey getServerPrivateKey() {
- initCerts();
- return SERVER_PRIVATE_KEY;
- }
-
- private static byte[][] getServerCertificates() {
- initCerts();
- return SERVER_CERTIFICATES;
- }
-
- private static OpenSSLKey getClientPrivateKey() {
- initCerts();
- return CLIENT_PRIVATE_KEY;
- }
-
- private static byte[][] getClientCertificates() {
- initCerts();
- return CLIENT_CERTIFICATES;
- }
-
- private static byte[][] getCaPrincipals() {
- initCerts();
- return CA_PRINCIPALS;
- }
-
- /**
- * Lazily create shared test certificates.
- */
- private static synchronized void initCerts() {
- if (SERVER_PRIVATE_KEY != null) {
- return;
- }
-
- try {
- PrivateKeyEntry serverPrivateKeyEntry
- = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- SERVER_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(serverPrivateKeyEntry.getPrivateKey());
- SERVER_CERTIFICATES = NativeCrypto.encodeCertificates(
- serverPrivateKeyEntry.getCertificateChain());
-
- PrivateKeyEntry clientPrivateKeyEntry
- = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA");
- CLIENT_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(clientPrivateKeyEntry.getPrivateKey());
- CLIENT_CERTIFICATES = NativeCrypto.encodeCertificates(
- clientPrivateKeyEntry.getCertificateChain());
-
- KeyStore ks = TestKeyStore.getClient().keyStore;
- String caCertAlias = ks.aliases().nextElement();
- X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias);
- X500Principal principal = certificate.getIssuerX500Principal();
- CA_PRINCIPALS = new byte[][] { principal.getEncoded() };
- initChannelIdKey();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private static synchronized void initChannelIdKey() throws Exception {
- if (CHANNEL_ID_PRIVATE_KEY != null) {
- return;
- }
-
- // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1
- OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1");
- BigInteger s = new BigInteger(
- "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16);
- CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey(
- new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())).getOpenSSLKey();
-
- // Channel ID is the concatenation of the X and Y coordinates of the public key.
- CHANNEL_ID = new BigInteger(
- "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" +
- "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77",
- 16).toByteArray();
- }
-
- public static void assertEqualSessions(long expected, long actual) {
- assertEqualByteArrays(NativeCrypto.SSL_SESSION_session_id(expected),
- NativeCrypto.SSL_SESSION_session_id(actual));
- }
- public static void assertEqualByteArrays(byte[] expected, byte[] actual) {
- assertEquals(Arrays.toString(expected), Arrays.toString(actual));
- }
-
- public static void assertEqualPrincipals(byte[][] expected, byte[][] actual) {
- assertEqualByteArrays(expected, actual);
- }
- public static void assertEqualCertificateChains(byte[][] expected, byte[][] actual) {
- assertEqualByteArrays(expected, actual);
- }
- public static void assertEqualByteArrays(byte[][] expected, byte[][] actual) {
- assertEquals(Arrays.deepToString(expected), Arrays.deepToString(actual));
- }
-
- public void test_EVP_PKEY_cmp() throws Exception {
- try {
- NativeCrypto.EVP_PKEY_cmp(NULL, NULL);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
- kpg.initialize(512);
-
- KeyPair kp1 = kpg.generateKeyPair();
- RSAPrivateCrtKey privKey1 = (RSAPrivateCrtKey) kp1.getPrivate();
-
- KeyPair kp2 = kpg.generateKeyPair();
- RSAPrivateCrtKey privKey2 = (RSAPrivateCrtKey) kp2.getPrivate();
-
- long pkey1 = 0, pkey1_copy = 0, pkey2 = 0;
- try {
- pkey1 = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
- privKey1.getPublicExponent().toByteArray(),
- privKey1.getPrivateExponent().toByteArray(),
- privKey1.getPrimeP().toByteArray(),
- privKey1.getPrimeQ().toByteArray(),
- privKey1.getPrimeExponentP().toByteArray(),
- privKey1.getPrimeExponentQ().toByteArray(),
- privKey1.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey1);
-
- pkey1_copy = NativeCrypto.EVP_PKEY_new_RSA(privKey1.getModulus().toByteArray(),
- privKey1.getPublicExponent().toByteArray(),
- privKey1.getPrivateExponent().toByteArray(),
- privKey1.getPrimeP().toByteArray(),
- privKey1.getPrimeQ().toByteArray(),
- privKey1.getPrimeExponentP().toByteArray(),
- privKey1.getPrimeExponentQ().toByteArray(),
- privKey1.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey1_copy);
-
- pkey2 = NativeCrypto.EVP_PKEY_new_RSA(privKey2.getModulus().toByteArray(),
- privKey2.getPublicExponent().toByteArray(),
- privKey2.getPrivateExponent().toByteArray(),
- privKey2.getPrimeP().toByteArray(),
- privKey2.getPrimeQ().toByteArray(),
- privKey2.getPrimeExponentP().toByteArray(),
- privKey2.getPrimeExponentQ().toByteArray(),
- privKey2.getCrtCoefficient().toByteArray());
- assertNotSame(NULL, pkey2);
-
- try {
- NativeCrypto.EVP_PKEY_cmp(pkey1, NULL);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.EVP_PKEY_cmp(NULL, pkey1);
- fail("Should throw NullPointerException when arguments are NULL");
- } catch (NullPointerException expected) {
- }
-
- assertEquals("Same keys should be the equal", 1,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1));
-
- assertEquals("Same keys should be the equal", 1,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey1_copy));
-
- assertEquals("Different keys should not be equal", 0,
- NativeCrypto.EVP_PKEY_cmp(pkey1, pkey2));
- } finally {
- if (pkey1 != 0) {
- NativeCrypto.EVP_PKEY_free(pkey1);
- }
- if (pkey1_copy != 0) {
- NativeCrypto.EVP_PKEY_free(pkey1_copy);
- }
- if (pkey2 != 0) {
- NativeCrypto.EVP_PKEY_free(pkey2);
- }
- }
- }
-
- public void test_SSL_CTX_new() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- assertTrue(c != NULL);
- long c2 = NativeCrypto.SSL_CTX_new();
- assertTrue(c != c2);
- NativeCrypto.SSL_CTX_free(c);
- NativeCrypto.SSL_CTX_free(c2);
- }
-
- public void test_SSL_CTX_free() throws Exception {
- try {
- NativeCrypto.SSL_CTX_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_CTX_free(NativeCrypto.SSL_CTX_new());
- }
-
- public void test_SSL_CTX_set_session_id_context() throws Exception {
- byte[] empty = new byte[0];
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(NULL, empty);
- fail();
- } catch (NullPointerException expected) {
- }
- long c = NativeCrypto.SSL_CTX_new();
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(c, null);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_CTX_set_session_id_context(c, empty);
- NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[32]);
- try {
- NativeCrypto.SSL_CTX_set_session_id_context(c, new byte[33]);
- } catch (IllegalArgumentException expected) {
- }
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_new() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- assertTrue(s != NULL);
- assertTrue((NativeCrypto.SSL_get_options(s) & 0x01000000L) != 0); // SSL_OP_NO_SSLv2
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_1) == 0);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_TLSv1_2) == 0);
-
- long s2 = NativeCrypto.SSL_new(c);
- assertTrue(s != s2);
- NativeCrypto.SSL_free(s2);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_certificate() throws Exception {
- try {
- NativeCrypto.SSL_use_certificate(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_use_certificate(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_PrivateKey_for_tls_channel_id() throws Exception {
- initChannelIdKey();
-
- try {
- NativeCrypto.SSL_set1_tls_channel_id(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_set1_tls_channel_id(s, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // Use the key natively. This works because the initChannelIdKey method ensures that the
- // key is backed by OpenSSL.
- NativeCrypto.SSL_set1_tls_channel_id(s, CHANNEL_ID_PRIVATE_KEY.getPkeyContext());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_use_PrivateKey() throws Exception {
- try {
- NativeCrypto.SSL_use_PrivateKey(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_use_PrivateKey(s, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_check_private_key_null() throws Exception {
- try {
- NativeCrypto.SSL_check_private_key(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_SSL_check_private_key_no_key_no_cert() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // neither private or certificate set
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_check_private_key_cert_then_key() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // first certificate, then private
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
-
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
- NativeCrypto.SSL_check_private_key(s);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
- public void test_SSL_check_private_key_key_then_cert() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // first private, then certificate
- NativeCrypto.SSL_use_PrivateKey(s, getServerPrivateKey().getPkeyContext());
-
- try {
- NativeCrypto.SSL_check_private_key(s);
- fail();
- } catch (SSLException expected) {
- }
-
- NativeCrypto.SSL_use_certificate(s, getServerCertificates());
- NativeCrypto.SSL_check_private_key(s);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_get_mode() throws Exception {
- try {
- NativeCrypto.SSL_get_mode(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue(NativeCrypto.SSL_get_mode(s) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_mode_and_clear_mode() throws Exception {
- try {
- NativeCrypto.SSL_set_mode(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- // check SSL_MODE_HANDSHAKE_CUTTHROUGH off by default
- assertEquals(0, NativeCrypto.SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- // set SSL_MODE_HANDSHAKE_CUTTHROUGH on
- NativeCrypto.SSL_set_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- assertTrue((NativeCrypto.SSL_get_mode(s)
- & SSL_MODE_HANDSHAKE_CUTTHROUGH) != 0);
- // clear SSL_MODE_HANDSHAKE_CUTTHROUGH off
- NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- assertTrue((NativeCrypto.SSL_get_mode(s)
- & SSL_MODE_HANDSHAKE_CUTTHROUGH) == 0);
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_get_options() throws Exception {
- try {
- NativeCrypto.SSL_get_options(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue(NativeCrypto.SSL_get_options(s) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_options() throws Exception {
- try {
- NativeCrypto.SSL_set_options(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_clear_options() throws Exception {
- try {
- NativeCrypto.SSL_clear_options(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_set_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) != 0);
- NativeCrypto.SSL_clear_options(s, NativeCrypto.SSL_OP_NO_SSLv3);
- assertTrue((NativeCrypto.SSL_get_options(s) & NativeCrypto.SSL_OP_NO_SSLv3) == 0);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_cipher_lists() throws Exception {
- try {
- NativeCrypto.SSL_set_cipher_lists(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_set_cipher_lists(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_set_cipher_lists(s, new String[] {});
-
- try {
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { null });
- fail();
- } catch (NullPointerException expected) {
- }
-
- // see OpenSSL ciphers man page
- String[] illegals = new String[] {
- // empty
- "",
- // never standardized
- "EXP1024-DES-CBC-SHA", "EXP1024-RC4-SHA", "DHE-DSS-RC4-SHA",
- // IDEA
- "IDEA-CBC-SHA", "IDEA-CBC-MD5"
- };
-
- for (String illegal : illegals) {
- try {
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { illegal });
- fail(illegal);
- } catch (IllegalArgumentException expected) {
- }
- }
-
- List<String> ciphers
- = new ArrayList<String>(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.keySet());
- NativeCrypto.SSL_set_cipher_lists(s, ciphers.toArray(new String[ciphers.size()]));
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_set_verify() throws Exception {
- try {
- NativeCrypto.SSL_set_verify(NULL, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_NONE);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- NativeCrypto.SSL_set_verify(s, (NativeCrypto.SSL_VERIFY_PEER
- | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT));
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- private static final boolean DEBUG = false;
-
- public static class Hooks {
- private OpenSSLKey channelIdPrivateKey;
-
- public long getContext() throws SSLException {
- return NativeCrypto.SSL_CTX_new();
- }
- public long beforeHandshake(long context) throws SSLException {
- long s = NativeCrypto.SSL_new(context);
- // without this SSL_set_cipher_lists call the tests were
- // negotiating DHE-RSA-AES256-SHA by default which had
- // very slow ephemeral RSA key generation
- NativeCrypto.SSL_set_cipher_lists(s, new String[] { "RC4-MD5" });
-
- if (channelIdPrivateKey != null) {
- NativeCrypto.SSL_set1_tls_channel_id(s, channelIdPrivateKey.getPkeyContext());
- }
- return s;
- }
- public void clientCertificateRequested(long s) {}
- public void afterHandshake(long session, long ssl, long context,
- Socket socket, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- if (session != NULL) {
- NativeCrypto.SSL_SESSION_free(session);
- }
- if (ssl != NULL) {
- try {
- NativeCrypto.SSL_shutdown(ssl, fd, callback);
- } catch (IOException e) {
- }
- NativeCrypto.SSL_free(ssl);
- }
- if (context != NULL) {
- NativeCrypto.SSL_CTX_free(context);
- }
- if (socket != null) {
- socket.close();
- }
- }
- }
-
- public static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks {
- private final Socket socket;
- private final long sslNativePointer;
- private final Hooks hooks;
-
- public TestSSLHandshakeCallbacks(Socket socket,
- long sslNativePointer,
- Hooks hooks) {
- this.socket = socket;
- this.sslNativePointer = sslNativePointer;
- this.hooks = hooks;
- }
-
- public byte[][] asn1DerEncodedCertificateChain;
- public String authMethod;
- public boolean verifyCertificateChainCalled;
-
- public void verifyCertificateChain(byte[][] asn1DerEncodedCertificateChain,
- String authMethod)
- throws CertificateException {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " verifyCertificateChain"
- + " asn1DerEncodedCertificateChain="
- + asn1DerEncodedCertificateChain
- + " authMethod=" + authMethod);
- }
- this.asn1DerEncodedCertificateChain = asn1DerEncodedCertificateChain;
- this.authMethod = authMethod;
- this.verifyCertificateChainCalled = true;
- }
-
- public byte[] keyTypes;
- public byte[][] asn1DerEncodedX500Principals;
- public boolean clientCertificateRequestedCalled;
- public void clientCertificateRequested(byte[] keyTypes,
- byte[][] asn1DerEncodedX500Principals) {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " clientCertificateRequested"
- + " keyTypes=" + keyTypes
- + " asn1DerEncodedX500Principals="
- + asn1DerEncodedX500Principals);
- }
- this.keyTypes = keyTypes;
- this.asn1DerEncodedX500Principals = asn1DerEncodedX500Principals;
- this.clientCertificateRequestedCalled = true;
- if (hooks != null ) {
- hooks.clientCertificateRequested(sslNativePointer);
- }
- }
-
- public boolean handshakeCompletedCalled;
- public void handshakeCompleted() {
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16)
- + " handshakeCompleted");
- }
- this.handshakeCompletedCalled = true;
- }
-
- public Socket getSocket() {
- return socket;
- }
- }
-
- public static class ServerHooks extends Hooks {
- private final OpenSSLKey privateKey;
- private final byte[][] certificates;
- private boolean channelIdEnabled;
- private byte[] channelIdAfterHandshake;
- private Throwable channelIdAfterHandshakeException;
-
- public ServerHooks(OpenSSLKey privateKey, byte[][] certificates) {
- this.privateKey = privateKey;
- this.certificates = certificates;
- }
-
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- if (privateKey != null) {
- NativeCrypto.SSL_use_PrivateKey(s, privateKey.getPkeyContext());
- }
- if (certificates != null) {
- NativeCrypto.SSL_use_certificate(s, certificates);
- }
- if (channelIdEnabled) {
- NativeCrypto.SSL_enable_tls_channel_id(s);
- }
- return s;
- }
-
- @Override
- public void afterHandshake(long session, long ssl, long context,
- Socket socket, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- if (channelIdEnabled) {
- try {
- channelIdAfterHandshake = NativeCrypto.SSL_get_tls_channel_id(ssl);
- } catch (Exception e) {
- channelIdAfterHandshakeException = e;
- }
- }
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
-
- public void clientCertificateRequested(long s) {
- fail("Server asked for client certificates");
- }
- }
-
- public static Future<TestSSLHandshakeCallbacks> handshake(final ServerSocket listener,
- final int timeout, final boolean client, final Hooks hooks, final byte[] npnProtocols,
- final byte[] alpnProtocols) {
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Future<TestSSLHandshakeCallbacks> future = executor.submit(
- new Callable<TestSSLHandshakeCallbacks>() {
- @Override public TestSSLHandshakeCallbacks call() throws Exception {
- Socket socket = (client
- ? new Socket(listener.getInetAddress(),
- listener.getLocalPort())
- : listener.accept());
- if (timeout == -1) {
- return new TestSSLHandshakeCallbacks(socket, 0, null);
- }
- FileDescriptor fd = socket.getFileDescriptor$();
- long c = hooks.getContext();
- long s = hooks.beforeHandshake(c);
- TestSSLHandshakeCallbacks callback
- = new TestSSLHandshakeCallbacks(socket, s, hooks);
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(s, 16)
- + " handshake"
- + " context=0x" + Long.toString(c, 16)
- + " socket=" + socket
- + " fd=" + fd
- + " timeout=" + timeout
- + " client=" + client);
- }
- long session = NULL;
- try {
- session = NativeCrypto.SSL_do_handshake(s, fd, callback, timeout, client,
- npnProtocols, alpnProtocols);
- if (DEBUG) {
- System.out.println("ssl=0x" + Long.toString(s, 16)
- + " handshake"
- + " session=0x" + Long.toString(session, 16));
- }
- } finally {
- // Ensure afterHandshake is called to free resources
- hooks.afterHandshake(session, s, c, socket, fd, callback);
- }
- return callback;
- }
- });
- executor.shutdown();
- return future;
- }
-
- public void test_SSL_do_handshake_NULL_SSL() throws Exception {
- try {
- NativeCrypto.SSL_do_handshake(NULL, null, null, 0, false, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- public void test_SSL_do_handshake_null_args() throws Exception {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- try {
- NativeCrypto.SSL_do_handshake(s, null, null, 0, true, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.SSL_do_handshake(s, INVALID_FD, null, 0, true, null, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- public void test_SSL_do_handshake_normal() throws Exception {
- // normal client and server case
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- }
-
- public void test_SSL_do_handshake_optional_client_certificate() throws Exception {
- // optional client certificate case
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void clientCertificateRequested(long s) {
- super.clientCertificateRequested(s);
- NativeCrypto.SSL_use_PrivateKey(s, getClientPrivateKey().getPkeyContext());
- NativeCrypto.SSL_use_certificate(s, getClientCertificates());
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertTrue(serverCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getClientCertificates(),
- serverCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", serverCallback.authMethod);
-
- assertTrue(clientCallback.clientCertificateRequestedCalled);
- assertNotNull(clientCallback.keyTypes);
- // this depends on the SSL_set_cipher_lists call in beforeHandshake
- // the three returned are the non-ephemeral cases.
- assertEquals(3, clientCallback.keyTypes.length);
- assertEquals("RSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[0]));
- assertEquals("DSA", CipherSuite.getClientKeyType(clientCallback.keyTypes[1]));
- assertEquals("EC", CipherSuite.getClientKeyType(clientCallback.keyTypes[2]));
- assertEqualPrincipals(getCaPrincipals(),
- clientCallback.asn1DerEncodedX500Principals);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
-
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- }
-
- public void test_SSL_do_handshake_missing_required_certificate() throws Exception {
- // required client certificate negative case
- final ServerSocket listener = new ServerSocket(0);
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_client_CA_list(s, getCaPrincipals());
- NativeCrypto.SSL_set_verify(s,
- NativeCrypto.SSL_VERIFY_PEER
- | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
- }
-
- /**
- * Usually if a RuntimeException is thrown by the
- * clientCertificateRequestedCalled callback, the caller sees it
- * during the call to NativeCrypto_SSL_do_handshake. However, IIS
- * does not request client certs until after the initial
- * handshake. It does an SSL renegotiation, which means we need to
- * be able to deliver the callback's exception in cases like
- * SSL_read, SSL_write, and SSL_shutdown.
- */
- public void test_SSL_do_handshake_clientCertificateRequested_throws_after_renegotiate()
- throws Exception {
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long context) throws SSLException {
- long s = super.beforeHandshake(context);
- NativeCrypto.SSL_clear_mode(s, SSL_MODE_HANDSHAKE_CUTTHROUGH);
- return s;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- fail();
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- @Override
- public void clientCertificateRequested(long s) {
- super.clientCertificateRequested(s);
- throw new RuntimeException("expected");
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- try {
- NativeCrypto.SSL_set_verify(s, NativeCrypto.SSL_VERIFY_PEER);
- NativeCrypto.SSL_set_options(
- s, NativeCrypto.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
- NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1,
- (int) ((TIMEOUT_SECONDS * 1000) / 2));
- } catch (IOException expected) {
- } finally {
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- try {
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
- if (!"expected".equals(e.getCause().getMessage())) {
- throw e;
- }
- }
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_do_handshake_client_timeout() throws Exception {
- // client timeout
- final ServerSocket listener = new ServerSocket(0);
- Socket serverSocket = null;
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 1, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, -1, false, sHooks, null,
- null);
- serverSocket = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- if (SocketTimeoutException.class != expected.getCause().getClass()) {
- expected.printStackTrace();
- }
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- } finally {
- // Manually close peer socket when testing timeout
- IoUtils.closeQuietly(serverSocket);
- }
- }
-
- public void test_SSL_do_handshake_server_timeout() throws Exception {
- // server timeout
- final ServerSocket listener = new ServerSocket(0);
- Socket clientSocket = null;
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, -1, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 1, false, sHooks, null, null);
- clientSocket = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).getSocket();
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- } finally {
- // Manually close peer socket when testing timeout
- IoUtils.closeQuietly(clientSocket);
- }
- }
-
- public void test_SSL_do_handshake_with_channel_id_normal() throws Exception {
- initChannelIdKey();
-
- // Normal handshake with TLS Channel ID.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = true;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertEqualByteArrays(CHANNEL_ID, sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() throws Exception {
- initChannelIdKey();
-
- // Client tries to use TLS Channel ID but the server does not enable/offer the extension.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = CHANNEL_ID_PRIVATE_KEY;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = false;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertNull(sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws Exception {
- initChannelIdKey();
-
- // Client does not use TLS Channel ID when the server has the extension enabled/offered.
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks();
- cHooks.channelIdPrivateKey = null;
- ServerHooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- sHooks.channelIdEnabled = true;
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertTrue(clientCallback.verifyCertificateChainCalled);
- assertEqualCertificateChains(getServerCertificates(),
- clientCallback.asn1DerEncodedCertificateChain);
- assertEquals("RSA", clientCallback.authMethod);
- assertFalse(serverCallback.verifyCertificateChainCalled);
- assertFalse(clientCallback.clientCertificateRequestedCalled);
- assertFalse(serverCallback.clientCertificateRequestedCalled);
- assertTrue(clientCallback.handshakeCompletedCalled);
- assertTrue(serverCallback.handshakeCompletedCalled);
- assertNull(sHooks.channelIdAfterHandshakeException);
- assertNull(sHooks.channelIdAfterHandshake);
- }
-
- public void test_SSL_set_session() throws Exception {
- try {
- NativeCrypto.SSL_set_session(NULL, NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_session(s, NULL);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- {
- final long clientContext = NativeCrypto.SSL_CTX_new();
- final long serverContext = NativeCrypto.SSL_CTX_new();
- final ServerSocket listener = new ServerSocket(0);
- final long[] clientSession = new long[] { NULL };
- final long[] serverSession = new long[] { NULL };
- {
- Hooks cHooks = new Hooks() {
- @Override
- public long getContext() throws SSLException {
- return clientContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- clientSession[0] = session;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long getContext() throws SSLException {
- return serverContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- serverSession[0] = session;
- }
- };
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- assertEqualSessions(clientSession[0], serverSession[0]);
- {
- Hooks cHooks = new Hooks() {
- @Override
- public long getContext() throws SSLException {
- return clientContext;
- }
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = NativeCrypto.SSL_new(clientContext);
- NativeCrypto.SSL_set_session(s, clientSession[0]);
- return s;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualSessions(clientSession[0], session);
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long getContext() throws SSLException {
- return serverContext;
- }
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualSessions(serverSession[0], session);
- super.afterHandshake(NULL, s, NULL, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- NativeCrypto.SSL_SESSION_free(clientSession[0]);
- NativeCrypto.SSL_SESSION_free(serverSession[0]);
- NativeCrypto.SSL_CTX_free(serverContext);
- NativeCrypto.SSL_CTX_free(clientContext);
- }
- }
-
- public void test_SSL_set_session_creation_enabled() throws Exception {
- try {
- NativeCrypto.SSL_set_session_creation_enabled(NULL, false);
- fail();
- } catch (NullPointerException expected) {
- }
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- NativeCrypto.SSL_set_session_creation_enabled(s, true);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // negative test case for SSL_set_session_creation_enabled(false) on client
- try {
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- return s;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
-
- // negative test case for SSL_set_session_creation_enabled(false) on server
- try {
- Hooks cHooks = new Hooks();
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_session_creation_enabled(s, false);
- return s;
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SSLProtocolException.class, expected.getCause().getClass());
- }
- }
-
- public void test_SSL_set_tlsext_host_name() throws Exception {
- // NULL SSL
- try {
- NativeCrypto.SSL_set_tlsext_host_name(NULL, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final String hostname = "www.android.com";
-
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
-
- // null hostname
- try {
- NativeCrypto.SSL_set_tlsext_host_name(s, null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // too long hostname
- try {
- char[] longHostname = new char[256];
- Arrays.fill(longHostname, 'w');
- NativeCrypto.SSL_set_tlsext_host_name(s, new String(longHostname));
- fail();
- } catch (SSLException expected) {
- }
-
- assertNull(NativeCrypto.SSL_get_servername(s));
- NativeCrypto.SSL_set_tlsext_host_name(s, new String(hostname));
- assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
-
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // normal
- Hooks cHooks = new Hooks() {
- @Override
- public long beforeHandshake(long c) throws SSLException {
- long s = super.beforeHandshake(c);
- NativeCrypto.SSL_set_tlsext_host_name(s, hostname);
- return s;
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEquals(hostname, NativeCrypto.SSL_get_servername(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_NpnNegotiateSuccess() throws Exception {
- final byte[] clientNpnProtocols = new byte[] {
- 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
- 3, 'f', 'o', 'o',
- 6, 's', 'p', 'd', 'y', '/', '2',
- };
- final byte[] serverNpnProtocols = new byte[] {
- 6, 's', 'p', 'd', 'y', '/', '2',
- 3, 'f', 'o', 'o',
- 3, 'b', 'a', 'r',
- };
-
- Hooks cHooks = new Hooks() {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_enable_npn(context);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertTrue("NPN should enable cutthrough on the client",
- 0 != (NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH));
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_enable_npn(context);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get_npn_negotiated_protocol(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertEquals("NPN should not enable cutthrough on the server",
- 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, c, sock, fd, callback);
- }
- };
-
- ServerSocket listener = new ServerSocket(0);
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, clientNpnProtocols, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, serverNpnProtocols, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_AlpnNegotiateSuccess() throws Exception {
- final byte[] clientAlpnProtocols = new byte[] {
- 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
- 3, 'f', 'o', 'o',
- 6, 's', 'p', 'd', 'y', '/', '2',
- };
- final byte[] serverAlpnProtocols = new byte[] {
- 6, 's', 'p', 'd', 'y', '/', '2',
- 3, 'f', 'o', 'o',
- 3, 'b', 'a', 'r',
- };
-
- Hooks cHooks = new Hooks() {
- @Override public long beforeHandshake(long context) throws SSLException {
- NativeCrypto.SSL_CTX_set_alpn_protos(context, clientAlpnProtocols);
- return super.beforeHandshake(context);
- }
- @Override public void afterHandshake(long session, long ssl, long context, Socket socket,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl);
- assertEquals("spdy/2", new String(negotiated));
- /*
- * There is no callback on the client, so we can't enable
- * cut-through
- */
- assertEquals("ALPN should not enable cutthrough on the client", 0,
- NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, context, socket, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override public void afterHandshake(long session, long ssl, long c, Socket sock,
- FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception {
- byte[] negotiated = NativeCrypto.SSL_get0_alpn_selected(ssl);
- assertEquals("spdy/2", new String(negotiated));
- assertEquals("ALPN should not enable cutthrough on the server",
- 0, NativeCrypto.SSL_get_mode(ssl) & SSL_MODE_HANDSHAKE_CUTTHROUGH);
- super.afterHandshake(session, ssl, c, sock, fd, callback);
- }
- };
-
- ServerSocket listener = new ServerSocket(0);
- Future<TestSSLHandshakeCallbacks> client
- = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server
- = handshake(listener, 0, false, sHooks, null, serverAlpnProtocols);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_servername_null() throws Exception {
- // NULL SSL
- try {
- NativeCrypto.SSL_get_servername(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- assertNull(NativeCrypto.SSL_get_servername(s));
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
-
- // additional positive testing by test_SSL_set_tlsext_host_name
- }
-
- public void test_SSL_renegotiate() throws Exception {
- try {
- NativeCrypto.SSL_renegotiate(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] buffer = new byte[1];
- NativeCrypto.SSL_read(s, fd, callback, buffer, 0, 1, 0);
- assertEquals(42, buffer[0]);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_renegotiate(s);
- NativeCrypto.SSL_write(s, fd, callback, new byte[] { 42 }, 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_certificate() throws Exception {
- try {
- NativeCrypto.SSL_get_certificate(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertNull(NativeCrypto.SSL_get_certificate(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- assertEqualCertificateChains(
- getServerCertificates(),
- NativeCrypto.SSL_get_certificate(s));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_get_peer_cert_chain() throws Exception {
- try {
- NativeCrypto.SSL_get_peer_cert_chain(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[][] cc = NativeCrypto.SSL_get_peer_cert_chain(s);
- assertEqualCertificateChains(getServerCertificates(), cc);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- final byte[] BYTES = new byte[] { 2, -3, 5, 127, 0, -128 };
-
- public void test_SSL_read() throws Exception {
-
- // NULL ssl
- try {
- NativeCrypto.SSL_read(NULL, null, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // null FileDescriptor
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, null, DUMMY_CB, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null SSLHandshakeCallbacks
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null byte array
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // handshaking not yet performed
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_read(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
- fail();
- } catch (SSLException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- // normal case
- {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] in = new byte[256];
- assertEquals(BYTES.length,
- NativeCrypto.SSL_read(s,
- fd,
- callback,
- in,
- 0,
- BYTES.length,
- 0));
- for (int i = 0; i < BYTES.length; i++) {
- assertEquals(BYTES[i], in[i]);
- }
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_write(s, fd, callback, BYTES, 0, BYTES.length, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- // timeout case
- try {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 1);
- fail();
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- fail();
- } catch (ExecutionException expected) {
- assertEquals(SocketTimeoutException.class, expected.getCause().getClass());
- }
- }
-
- public void test_SSL_write() throws Exception {
- try {
- NativeCrypto.SSL_write(NULL, null, null, null, 0, 0, 0);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // null FileDescriptor
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, null, DUMMY_CB, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null SSLHandshakeCallbacks
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, null, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // null byte array
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, null, 0, 1, 0);
- fail();
- } catch (NullPointerException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // handshaking not yet performed
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_write(s, INVALID_FD, DUMMY_CB, new byte[1], 0, 1, 0);
- fail();
- } catch (SSLException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- // positively tested by test_SSL_read
- }
-
- public void test_SSL_interrupt() throws Exception {
- // SSL_interrupt is a rare case that tolerates a null SSL argument
- NativeCrypto.SSL_interrupt(NULL);
-
- // also works without handshaking
- {
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- NativeCrypto.SSL_interrupt(s);
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates()) {
- @Override
- public void afterHandshake(long session, final long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- new Thread() {
- public void run() {
- try {
- Thread.sleep(1*1000);
- NativeCrypto.SSL_interrupt(s);
- } catch (Exception e) {
- }
- }
- }.start();
- assertEquals(-1, NativeCrypto.SSL_read(s, fd, callback, new byte[1], 0, 1, 0));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_shutdown() throws Exception {
-
- // null FileDescriptor
- try {
- NativeCrypto.SSL_shutdown(NULL, null, DUMMY_CB);
- } catch (NullPointerException expected) {
- }
-
- // null SSLHandshakeCallbacks
- try {
- NativeCrypto.SSL_shutdown(NULL, INVALID_FD, null);
- } catch (NullPointerException expected) {
- }
-
- // SSL_shutdown is a rare case that tolerates a null SSL argument
- NativeCrypto.SSL_shutdown(NULL, INVALID_FD, DUMMY_CB);
-
- // handshaking not yet performed
- long c = NativeCrypto.SSL_CTX_new();
- long s = NativeCrypto.SSL_new(c);
- try {
- NativeCrypto.SSL_shutdown(s, INVALID_FD, DUMMY_CB);
- } catch (SSLProtocolException expected) {
- }
- NativeCrypto.SSL_free(s);
- NativeCrypto.SSL_CTX_free(c);
-
- // positively tested elsewhere because handshake uses use
- // SSL_shutdown to ensure SSL_SESSIONs are reused.
- }
-
- public void test_SSL_free() throws Exception {
- try {
- NativeCrypto.SSL_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- long c = NativeCrypto.SSL_CTX_new();
- NativeCrypto.SSL_free(NativeCrypto.SSL_new(c));
- NativeCrypto.SSL_CTX_free(c);
-
- // additional positive testing elsewhere because handshake
- // uses use SSL_free to cleanup in afterHandshake.
- }
-
- public void test_SSL_SESSION_session_id() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_session_id(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] id = NativeCrypto.SSL_SESSION_session_id(session);
- assertNotNull(id);
- assertEquals(32, id.length);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_get_time() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_get_time(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- {
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- long time = NativeCrypto.SSL_SESSION_get_time(session);
- assertTrue(time != 0);
- assertTrue(time < System.currentTimeMillis());
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null,
- null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null,
- null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
- }
-
- public void test_SSL_SESSION_get_version() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_get_version(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- String v = NativeCrypto.SSL_SESSION_get_version(session);
- assertTrue(StandardNames.SSL_SOCKET_PROTOCOLS.contains(v));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_cipher() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_cipher(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- String a = NativeCrypto.SSL_SESSION_cipher(session);
- assertTrue(NativeCrypto.OPENSSL_TO_STANDARD_CIPHER_SUITES.containsKey(a));
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_SSL_SESSION_free() throws Exception {
- try {
- NativeCrypto.SSL_SESSION_free(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- // additional positive testing elsewhere because handshake
- // uses use SSL_SESSION_free to cleanup in afterHandshake.
- }
-
- public void test_i2d_SSL_SESSION() throws Exception {
- try {
- NativeCrypto.i2d_SSL_SESSION(NULL);
- fail();
- } catch (NullPointerException expected) {
- }
-
- final ServerSocket listener = new ServerSocket(0);
-
- Hooks cHooks = new Hooks() {
- @Override
- public void afterHandshake(long session, long s, long c,
- Socket sock, FileDescriptor fd,
- SSLHandshakeCallbacks callback)
- throws Exception {
- byte[] b = NativeCrypto.i2d_SSL_SESSION(session);
- assertNotNull(b);
- long session2 = NativeCrypto.d2i_SSL_SESSION(b);
- assertTrue(session2 != NULL);
-
- // Make sure d2i_SSL_SESSION retores SSL_SESSION_cipher value http://b/7091840
- assertTrue(NativeCrypto.SSL_SESSION_cipher(session2) != null);
- assertEquals(NativeCrypto.SSL_SESSION_cipher(session),
- NativeCrypto.SSL_SESSION_cipher(session2));
-
- NativeCrypto.SSL_SESSION_free(session2);
- super.afterHandshake(session, s, c, sock, fd, callback);
- }
- };
- Hooks sHooks = new ServerHooks(getServerPrivateKey(), getServerCertificates());
- Future<TestSSLHandshakeCallbacks> client = handshake(listener, 0, true, cHooks, null, null);
- Future<TestSSLHandshakeCallbacks> server = handshake(listener, 0, false, sHooks, null, null);
- client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- }
-
- public void test_d2i_SSL_SESSION() throws Exception {
- try {
- NativeCrypto.d2i_SSL_SESSION(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[0]));
- assertEquals(NULL, NativeCrypto.d2i_SSL_SESSION(new byte[1]));
-
- // positive testing by test_i2d_SSL_SESSION
- }
-
- public void test_X509_NAME_hashes() {
- // ensure these hash functions are stable over time since the
- // /system/etc/security/cacerts CA filenames have to be
- // consistent with the output.
- X500Principal name = new X500Principal("CN=localhost");
- assertEquals(-1372642656, NativeCrypto.X509_NAME_hash(name)); // SHA1
- assertEquals(-1626170662, NativeCrypto.X509_NAME_hash_old(name)); // MD5
- }
-
- public void test_ENGINE_by_id_Failure() throws Exception {
- NativeCrypto.ENGINE_load_dynamic();
-
- long engine = NativeCrypto.ENGINE_by_id("non-existent");
- if (engine != 0) {
- NativeCrypto.ENGINE_free(engine);
- fail("should not acquire reference to non-existent engine");
- }
- }
-
- /**
- * Loads the test OpenSSL ENGINE. If it's already loaded, returns
- * immediately.
- */
- public static void loadTestEngine() throws Exception {
- long testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- if (testEngine != 0) {
- NativeCrypto.ENGINE_free(testEngine);
- return;
- }
-
- NativeCrypto.ENGINE_load_dynamic();
- long dynEngine = NativeCrypto.ENGINE_by_id("dynamic");
- try {
- ClassLoader loader = NativeCryptoTest.class.getClassLoader();
-
- final String libraryPaths;
- if (loader instanceof BaseDexClassLoader) {
- libraryPaths = ((BaseDexClassLoader) loader).getLdLibraryPath();
- } else {
- libraryPaths = System.getProperty("java.library.path");
- }
- assertNotNull(libraryPaths);
-
- String[] libraryPathArray = libraryPaths.split(":");
- for (String path : libraryPathArray) {
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "DIR_ADD", path, 0));
- }
-
- // We must add this to the list of ENGINEs
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LIST_ADD", "2", 0));
-
- // Do a direct load of the ENGINE.
- assertEquals(1,
- NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "ID", TEST_ENGINE_ID, 0));
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LOAD", null, 0));
- } finally {
- NativeCrypto.ENGINE_free(dynEngine);
- }
-
- testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- if (testEngine == 0) {
- fail("could not load test engine");
- }
- NativeCrypto.ENGINE_free(testEngine);
- }
-
- public void test_ENGINE_by_id_TestEngine() throws Exception {
- loadTestEngine();
-
- long engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
- assertTrue(engine != 0);
- NativeCrypto.ENGINE_add(engine);
- NativeCrypto.ENGINE_init(engine);
-
- long pkey = NULL;
- try {
- final String rsaPem =
- "-----BEGIN RSA PRIVATE KEY-----\n"
- + "MIICXAIBAAKBgQCvvsYz1VKhU9PT0NHlotX22tcCjeaiVFNg0JrkjoK2XuMb+7a6\n"
- + "R5bzgIr24+OnBB0LqgaKnHwxZTA73lo/Wy/Ms5Kvg4yX9UMkNE+PvH5vzcQBbFdI\n"
- + "lwETFPvFokHO5OyOcEY+iVWG2fDloteH2JsrKYLh9Sx3Br5pHFCCm5qT5wIDAQAB\n"
- + "AoGAWDxoNs371pPH3qkROUIwOuhU2ytziDzeP9V8bxQ9/GJXlE0kyRH4b/kxzBNO\n"
- + "0SP3kUukTSOUFxi+xtA0b2rQ7Be2txtjzW1TGOHSCWbFrJAdTqeBcmQJSaZay8n1\n"
- + "LOpk4/zvBl7VScBth1IgXP44v6lOzthsrDhMlUYs07ymwYECQQDonaLOhkmVThPa\n"
- + "CIThdE5CN/wF5UDzGOz+ZBz3dt8D8QQMu0aZaPzibq9BC462j/fWeWS5OFzbq2+T\n"
- + "+cor3nwPAkEAwWmTQdra6GMPEc40zNsM5ehF2FjOpX8aU8267eG56y0Y+GbHx2BN\n"
- + "zAHfPxGBBH8cZ0cLhk4RSo/po7Vv+cRyqQJAAQz1N0mT+4Cmxk1TjFEiKVpnYP9w\n"
- + "E6kBKQT6vINk7negNQ6Dex3mRn+Jexm6Q0jTLbzOn6eJg9R6ZIi0SQ5wMQJAKX2n\n"
- + "fGohqdaORgiRZRzcsHlaemXatsAEetPYdO2Gf7/l6mvKEahEKC6CoLn1jmxiQHmK\n"
- + "LF6U8QTcXyUuB0uwOQJBAIwWWjQGGc2sAQ1HW0C2wwCQbWneeBkiRBedonDBHtiB\n"
- + "Wz0zS2CMCtBPNeHQmmsXH2Ca+ADdh53sKTuperLiuiw=\n"
- + "-----END RSA PRIVATE KEY-----";
- pkey = NativeCrypto.ENGINE_load_private_key(engine, rsaPem);
- assertTrue(pkey != 0);
- } finally {
- if (pkey != NULL) {
- NativeCrypto.EVP_PKEY_free(pkey);
- }
-
- NativeCrypto.ENGINE_free(engine);
- NativeCrypto.ENGINE_finish(engine);
- }
- }
-
- public void test_RAND_bytes_Success() throws Exception {
- byte[] output = new byte[128];
- NativeCrypto.RAND_bytes(output);
-
- boolean isZero = true;
- for (int i = 0; i < output.length; i++) {
- isZero &= (output[i] == 0);
- }
-
- assertFalse("Random output was zero. This is a very low probability event (1 in 2^128) "
- + "and probably indicates an error.", isZero);
- }
-
- public void test_RAND_bytes_Null_Failure() throws Exception {
- byte[] output = null;
- try {
- NativeCrypto.RAND_bytes(output);
- fail("Should be an error on null buffer input");
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_EVP_get_digestbyname() throws Exception {
- assertTrue(NativeCrypto.EVP_get_digestbyname("sha256") != NULL);
-
- try {
- NativeCrypto.EVP_get_digestbyname(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.EVP_get_digestbyname("");
- NativeCrypto.EVP_get_digestbyname("foobar");
- fail();
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_EVP_SignInit() throws Exception {
- final long ctx = NativeCrypto.EVP_SignInit("RSA-SHA256");
- assertTrue(ctx != NULL);
- NativeCrypto.EVP_MD_CTX_destroy(ctx);
-
- try {
- NativeCrypto.EVP_SignInit("foobar");
- fail();
- } catch (RuntimeException expected) {
- }
- }
-
- public void test_get_RSA_private_params() throws Exception {
- try {
- NativeCrypto.get_RSA_private_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.get_RSA_private_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- // Test getting params for the wrong kind of key.
- final byte[] seed = new byte[20];
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- try {
- NativeCrypto.get_RSA_private_params(ctx);
- fail();
- } catch (RuntimeException expected) {
- }
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- public void test_get_RSA_public_params() throws Exception {
- try {
- NativeCrypto.get_RSA_public_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- try {
- NativeCrypto.get_RSA_public_params(NULL);
- } catch (NullPointerException expected) {
- }
-
- // Test getting params for the wrong kind of key.
- final byte[] seed = new byte[20];
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- try {
- NativeCrypto.get_RSA_public_params(ctx);
- fail();
- } catch (RuntimeException expected) {
- }
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- final byte[] dsa2048_p = {
- (byte) 0xC3, (byte) 0x16, (byte) 0xD4, (byte) 0xBA, (byte) 0xDC, (byte) 0x0E,
- (byte) 0xB8, (byte) 0xFC, (byte) 0x40, (byte) 0xDB, (byte) 0xB0, (byte) 0x76,
- (byte) 0x47, (byte) 0xB8, (byte) 0x8D, (byte) 0xC1, (byte) 0xF1, (byte) 0xAB,
- (byte) 0x9B, (byte) 0x80, (byte) 0x9D, (byte) 0xDC, (byte) 0x55, (byte) 0x33,
- (byte) 0xEC, (byte) 0xB6, (byte) 0x09, (byte) 0x8F, (byte) 0xB7, (byte) 0xD9,
- (byte) 0xA5, (byte) 0x7F, (byte) 0xC1, (byte) 0xE3, (byte) 0xAD, (byte) 0xE1,
- (byte) 0x7A, (byte) 0x58, (byte) 0xF4, (byte) 0x2D, (byte) 0xB9, (byte) 0x61,
- (byte) 0xCF, (byte) 0x5B, (byte) 0xCA, (byte) 0x41, (byte) 0x9F, (byte) 0x73,
- (byte) 0x8D, (byte) 0x81, (byte) 0x62, (byte) 0xD2, (byte) 0x19, (byte) 0x7D,
- (byte) 0x18, (byte) 0xDB, (byte) 0xB3, (byte) 0x04, (byte) 0xE7, (byte) 0xB2,
- (byte) 0x28, (byte) 0x59, (byte) 0x14, (byte) 0x73, (byte) 0x43, (byte) 0xF1,
- (byte) 0x45, (byte) 0xC7, (byte) 0x47, (byte) 0xCC, (byte) 0xD1, (byte) 0x12,
- (byte) 0x8E, (byte) 0x19, (byte) 0x00, (byte) 0x2C, (byte) 0xD0, (byte) 0x86,
- (byte) 0x54, (byte) 0x64, (byte) 0x2D, (byte) 0x42, (byte) 0x6C, (byte) 0x6B,
- (byte) 0x5C, (byte) 0x2D, (byte) 0x4D, (byte) 0x97, (byte) 0x6A, (byte) 0x1D,
- (byte) 0x89, (byte) 0xB1, (byte) 0x2C, (byte) 0xA0, (byte) 0x05, (byte) 0x2B,
- (byte) 0x3C, (byte) 0xDB, (byte) 0x1F, (byte) 0x89, (byte) 0x03, (byte) 0x03,
- (byte) 0x92, (byte) 0x63, (byte) 0xB6, (byte) 0x08, (byte) 0x32, (byte) 0x50,
- (byte) 0xB2, (byte) 0x54, (byte) 0xA3, (byte) 0xFE, (byte) 0x6C, (byte) 0x35,
- (byte) 0x17, (byte) 0x2F, (byte) 0x7F, (byte) 0x54, (byte) 0xA4, (byte) 0xAE,
- (byte) 0x96, (byte) 0x1E, (byte) 0x31, (byte) 0x83, (byte) 0xF1, (byte) 0x3F,
- (byte) 0x9E, (byte) 0xB9, (byte) 0x5D, (byte) 0xD3, (byte) 0xA9, (byte) 0xCB,
- (byte) 0xE5, (byte) 0x2F, (byte) 0xBC, (byte) 0xA4, (byte) 0x1A, (byte) 0x31,
- (byte) 0x41, (byte) 0x91, (byte) 0x2C, (byte) 0xA0, (byte) 0xF4, (byte) 0x83,
- (byte) 0xAC, (byte) 0xD5, (byte) 0xBA, (byte) 0x3D, (byte) 0x19, (byte) 0xED,
- (byte) 0xF1, (byte) 0x6C, (byte) 0xD9, (byte) 0x3F, (byte) 0x30, (byte) 0xDA,
- (byte) 0x80, (byte) 0x06, (byte) 0x56, (byte) 0x3A, (byte) 0x8C, (byte) 0x74,
- (byte) 0x63, (byte) 0xF2, (byte) 0xED, (byte) 0x1E, (byte) 0xE3, (byte) 0x86,
- (byte) 0x95, (byte) 0x64, (byte) 0x2A, (byte) 0xC4, (byte) 0x5F, (byte) 0xB2,
- (byte) 0x64, (byte) 0x40, (byte) 0x9D, (byte) 0xA6, (byte) 0xB8, (byte) 0xF5,
- (byte) 0x84, (byte) 0x03, (byte) 0x2E, (byte) 0x4A, (byte) 0x7A, (byte) 0x1A,
- (byte) 0xB0, (byte) 0x0E, (byte) 0xBA, (byte) 0xB1, (byte) 0xF5, (byte) 0xD2,
- (byte) 0xE7, (byte) 0x65, (byte) 0xCE, (byte) 0xEE, (byte) 0x2C, (byte) 0x7C,
- (byte) 0x68, (byte) 0x20, (byte) 0x50, (byte) 0x53, (byte) 0x0F, (byte) 0x60,
- (byte) 0x92, (byte) 0x81, (byte) 0xC0, (byte) 0x2C, (byte) 0x2A, (byte) 0xEA,
- (byte) 0xE9, (byte) 0xB3, (byte) 0x2A, (byte) 0x81, (byte) 0xDA, (byte) 0x0F,
- (byte) 0xBB, (byte) 0xFA, (byte) 0x5B, (byte) 0x47, (byte) 0xDA, (byte) 0x57,
- (byte) 0x4E, (byte) 0xFC, (byte) 0x05, (byte) 0x2C, (byte) 0x6A, (byte) 0x90,
- (byte) 0xA0, (byte) 0x99, (byte) 0x88, (byte) 0x71, (byte) 0x8A, (byte) 0xCC,
- (byte) 0xD2, (byte) 0x97, (byte) 0x11, (byte) 0xB1, (byte) 0xCE, (byte) 0xF7,
- (byte) 0x47, (byte) 0x53, (byte) 0x53, (byte) 0x68, (byte) 0xE1, (byte) 0x2A,
- (byte) 0x56, (byte) 0xD5, (byte) 0x3D, (byte) 0xDF, (byte) 0x08, (byte) 0x16,
- (byte) 0x1F, (byte) 0xAA, (byte) 0x54, (byte) 0x15,
- };
-
- final byte[] dsa2048_q = {
- (byte) 0xAA, (byte) 0xDD, (byte) 0xE2, (byte) 0xCE, (byte) 0x08, (byte) 0xC0,
- (byte) 0x0E, (byte) 0x91, (byte) 0x8C, (byte) 0xD9, (byte) 0xBC, (byte) 0x1E,
- (byte) 0x05, (byte) 0x70, (byte) 0x07, (byte) 0x3B, (byte) 0xB5, (byte) 0xA9,
- (byte) 0xB5, (byte) 0x8B, (byte) 0x21, (byte) 0x68, (byte) 0xA2, (byte) 0x76,
- (byte) 0x53, (byte) 0x1E, (byte) 0x68, (byte) 0x1B, (byte) 0x4F, (byte) 0x88,
- (byte) 0x6D, (byte) 0xCF,
- };
-
- final byte[] dsa2048_g = {
- (byte) 0x6B, (byte) 0x4D, (byte) 0x21, (byte) 0x92, (byte) 0x24, (byte) 0x76,
- (byte) 0xE5, (byte) 0xA2, (byte) 0xCE, (byte) 0x02, (byte) 0x85, (byte) 0x32,
- (byte) 0x73, (byte) 0x70, (byte) 0xFF, (byte) 0xB9, (byte) 0xD4, (byte) 0x51,
- (byte) 0xBA, (byte) 0x22, (byte) 0x8B, (byte) 0x75, (byte) 0x29, (byte) 0xE3,
- (byte) 0xF2, (byte) 0x2E, (byte) 0x20, (byte) 0xF5, (byte) 0x6A, (byte) 0xD9,
- (byte) 0x75, (byte) 0xA0, (byte) 0xC0, (byte) 0x3B, (byte) 0x12, (byte) 0x2F,
- (byte) 0x4F, (byte) 0x9A, (byte) 0xF8, (byte) 0x5D, (byte) 0x45, (byte) 0xC5,
- (byte) 0x80, (byte) 0x6C, (byte) 0x9B, (byte) 0x56, (byte) 0xBE, (byte) 0x8E,
- (byte) 0x40, (byte) 0xF9, (byte) 0x0A, (byte) 0xF0, (byte) 0x3D, (byte) 0xD7,
- (byte) 0x7C, (byte) 0xDE, (byte) 0x22, (byte) 0x10, (byte) 0x24, (byte) 0xCC,
- (byte) 0xAE, (byte) 0x8A, (byte) 0xC0, (byte) 0x05, (byte) 0xCD, (byte) 0xDC,
- (byte) 0x10, (byte) 0x29, (byte) 0x4D, (byte) 0xFC, (byte) 0xEC, (byte) 0xEF,
- (byte) 0x51, (byte) 0x4B, (byte) 0xF9, (byte) 0xCC, (byte) 0x99, (byte) 0x84,
- (byte) 0x1B, (byte) 0x14, (byte) 0x68, (byte) 0xEC, (byte) 0xF0, (byte) 0x5E,
- (byte) 0x07, (byte) 0x10, (byte) 0x09, (byte) 0xA9, (byte) 0x2C, (byte) 0x04,
- (byte) 0xD0, (byte) 0x14, (byte) 0xBF, (byte) 0x88, (byte) 0x9E, (byte) 0xBB,
- (byte) 0xE3, (byte) 0x3F, (byte) 0xDE, (byte) 0x92, (byte) 0xE1, (byte) 0x64,
- (byte) 0x07, (byte) 0x28, (byte) 0xC1, (byte) 0xCA, (byte) 0x48, (byte) 0xC1,
- (byte) 0x1D, (byte) 0x33, (byte) 0xE4, (byte) 0x35, (byte) 0xBE, (byte) 0xDF,
- (byte) 0x5E, (byte) 0x50, (byte) 0xF9, (byte) 0xC2, (byte) 0x0E, (byte) 0x25,
- (byte) 0x0D, (byte) 0x20, (byte) 0x8C, (byte) 0x01, (byte) 0x0A, (byte) 0x23,
- (byte) 0xD4, (byte) 0x6E, (byte) 0x42, (byte) 0x47, (byte) 0xE1, (byte) 0x9E,
- (byte) 0x36, (byte) 0x91, (byte) 0xC8, (byte) 0x65, (byte) 0x44, (byte) 0xE0,
- (byte) 0x04, (byte) 0x86, (byte) 0x2F, (byte) 0xD4, (byte) 0x90, (byte) 0x16,
- (byte) 0x09, (byte) 0x14, (byte) 0xB1, (byte) 0xC5, (byte) 0x7D, (byte) 0xB2,
- (byte) 0x7C, (byte) 0x36, (byte) 0x0D, (byte) 0x9C, (byte) 0x1F, (byte) 0x83,
- (byte) 0x57, (byte) 0x94, (byte) 0x26, (byte) 0x32, (byte) 0x9C, (byte) 0x86,
- (byte) 0x8E, (byte) 0xE5, (byte) 0x80, (byte) 0x3A, (byte) 0xA9, (byte) 0xAF,
- (byte) 0x4A, (byte) 0x95, (byte) 0x78, (byte) 0x8D, (byte) 0xE6, (byte) 0xC3,
- (byte) 0x0C, (byte) 0x78, (byte) 0x83, (byte) 0x4B, (byte) 0xF5, (byte) 0x40,
- (byte) 0x04, (byte) 0x20, (byte) 0x90, (byte) 0x5C, (byte) 0xA1, (byte) 0x19,
- (byte) 0xEB, (byte) 0x95, (byte) 0x70, (byte) 0x2B, (byte) 0x94, (byte) 0xA3,
- (byte) 0x43, (byte) 0xDD, (byte) 0xEB, (byte) 0xD4, (byte) 0x0C, (byte) 0xBC,
- (byte) 0xBD, (byte) 0x58, (byte) 0x2D, (byte) 0x75, (byte) 0xB0, (byte) 0x8D,
- (byte) 0x8B, (byte) 0x70, (byte) 0xB9, (byte) 0xE7, (byte) 0xA3, (byte) 0xCC,
- (byte) 0x8C, (byte) 0xB4, (byte) 0xCD, (byte) 0xBB, (byte) 0x4B, (byte) 0xB1,
- (byte) 0x15, (byte) 0x18, (byte) 0x79, (byte) 0xDF, (byte) 0x22, (byte) 0xA6,
- (byte) 0x5C, (byte) 0x90, (byte) 0x7C, (byte) 0x1F, (byte) 0xEA, (byte) 0x1B,
- (byte) 0xF2, (byte) 0x89, (byte) 0x87, (byte) 0xB2, (byte) 0xEC, (byte) 0x57,
- (byte) 0xFF, (byte) 0xB2, (byte) 0xDA, (byte) 0xF5, (byte) 0xAD, (byte) 0x73,
- (byte) 0xC0, (byte) 0xA0, (byte) 0x20, (byte) 0x8B, (byte) 0x78, (byte) 0xA1,
- (byte) 0x5D, (byte) 0x04, (byte) 0x0A, (byte) 0x29, (byte) 0xE3, (byte) 0xD7,
- (byte) 0x37, (byte) 0xF6, (byte) 0xA2, (byte) 0xCA,
- };
-
- public void test_DSA_generate_key() throws Exception {
- final byte[] seed = new byte[20];
-
- // Real key
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(2048, seed, dsa2048_g, dsa2048_p, dsa2048_q);
- assertTrue(ctx != NULL);
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- // Real key with minimum bit size (should be 512 bits)
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(0, null, null, null, null);
- assertTrue(ctx != NULL);
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
-
- // Bad DSA params.
- {
- long ctx = 0;
- try {
- ctx = NativeCrypto.DSA_generate_key(0, null, new byte[] {}, new byte[] {},
- new byte[] {});
- fail();
- } catch (RuntimeException expected) {
- } finally {
- if (ctx != 0) {
- NativeCrypto.EVP_PKEY_free(ctx);
- }
- }
- }
- }
-
- /*
- * Test vector generation:
- * openssl rand -hex 16
- */
- private static final byte[] AES_128_KEY = new byte[] {
- (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2,
- (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29,
- (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f,
- };
-
- private static final byte[] AES_IV_ZEROES = new byte[] {
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- };
-
- public void testEC_GROUP() throws Exception {
- /* Test using NIST's P-256 curve */
- check_EC_GROUP(NativeCrypto.EC_CURVE_GFP, "prime256v1",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
- "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
- "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
- "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
- "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
- 1L);
-
- check_EC_GROUP(NativeCrypto.EC_CURVE_GF2M, "sect283r1",
- "0800000000000000000000000000000000000000000000000000000000000000000010A1",
- "000000000000000000000000000000000000000000000000000000000000000000000001",
- "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
- "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
- "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
- "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
- 2L);
- }
-
- private void check_EC_GROUP(int type, String name, String pStr, String aStr, String bStr,
- String xStr, String yStr, String nStr, long hLong) throws Exception {
- long group1 = NULL, group2 = NULL, point1 = NULL, point2 = NULL, key1 = NULL;
- try {
- group1 = NativeCrypto.EC_GROUP_new_by_curve_name(name);
- assertTrue(group1 != NULL);
- assertEquals(NativeCrypto.OBJ_txt2nid_longName(name),
- NativeCrypto.EC_GROUP_get_curve_name(group1));
- assertEquals(type, NativeCrypto.get_EC_GROUP_type(group1));
-
- // prime
- BigInteger p = new BigInteger(pStr, 16);
- // first coefficient
- BigInteger a = new BigInteger(aStr, 16);
- // second coefficient
- BigInteger b = new BigInteger(bStr, 16);
- // x affine coordinate of generator
- BigInteger x = new BigInteger(xStr, 16);
- // y affine coordinate of generator
- BigInteger y = new BigInteger(yStr, 16);
- // order of the generator
- BigInteger n = new BigInteger(nStr, 16);
- // cofactor of generator
- BigInteger h = BigInteger.valueOf(hLong);
-
- group2 = NativeCrypto.EC_GROUP_new_curve(type, p.toByteArray(),
- a.toByteArray(), b.toByteArray());
- assertEquals(type, NativeCrypto.get_EC_GROUP_type(group2));
-
- point2 = NativeCrypto.EC_POINT_new(group2);
-
- NativeCrypto.EC_POINT_set_affine_coordinates(group2, point2, x.toByteArray(),
- y.toByteArray());
-
- NativeCrypto.EC_GROUP_set_generator(group2, point2, n.toByteArray(), h.toByteArray());
-
- point1 = NativeCrypto.EC_GROUP_get_generator(group2);
- assertTrue(NativeCrypto.EC_POINT_cmp(group1, point1, point2));
-
- byte[][] pab = NativeCrypto.EC_GROUP_get_curve(group2);
- assertEquals(3, pab.length);
-
- BigInteger p2 = new BigInteger(pab[0]);
- assertEquals(p, p2);
-
- BigInteger a2 = new BigInteger(pab[1]);
- assertEquals(a, a2);
-
- BigInteger b2 = new BigInteger(pab[2]);
- assertEquals(b, b2);
-
- byte[][] xy = NativeCrypto.EC_POINT_get_affine_coordinates(group2, point2);
- assertEquals(2, xy.length);
-
- BigInteger x2 = new BigInteger(xy[0]);
- assertEquals(x, x2);
-
- BigInteger y2 = new BigInteger(xy[1]);
- assertEquals(y, y2);
-
- BigInteger n2 = new BigInteger(NativeCrypto.EC_GROUP_get_order(group1));
- assertEquals(n, n2);
-
- BigInteger h2 = new BigInteger(NativeCrypto.EC_GROUP_get_cofactor(group2));
- assertEquals(h, h2);
-
- assertTrue(NativeCrypto.EC_GROUP_cmp(group1, group2));
-
- key1 = NativeCrypto.EC_KEY_generate_key(group1);
- long groupTmp = NativeCrypto.EC_KEY_get0_group(key1);
- assertEquals(NativeCrypto.EC_GROUP_get_curve_name(group1),
- NativeCrypto.EC_GROUP_get_curve_name(groupTmp));
-
- } finally {
- if (group1 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group1);
- }
-
- if (group2 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group2);
- }
-
- if (point1 != NULL) {
- NativeCrypto.EC_POINT_clear_free(point1);
- }
-
- if (point2 != NULL) {
- NativeCrypto.EC_POINT_clear_free(point2);
- }
-
- if (key1 != NULL) {
- NativeCrypto.EVP_PKEY_free(key1);
- }
- }
- }
-
- public void test_EVP_CipherInit_ex_Null_Failure() throws Exception {
- final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
- try {
- final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
-
- try {
- NativeCrypto.EVP_CipherInit_ex(NULL, evpCipher, null, null, true);
- fail("Null context should throw NullPointerException");
- } catch (NullPointerException expected) {
- }
-
- /* Initialize encrypting. */
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, true);
- NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, true);
-
- /* Initialize decrypting. */
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, null, null, false);
- NativeCrypto.EVP_CipherInit_ex(ctx, NULL, null, null, false);
- } finally {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
- }
- }
-
- public void test_EVP_CipherInit_ex_Success() throws Exception {
- final long ctx = NativeCrypto.EVP_CIPHER_CTX_new();
- try {
- final long evpCipher = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
- NativeCrypto.EVP_CipherInit_ex(ctx, evpCipher, AES_128_KEY, null, true);
- } finally {
- NativeCrypto.EVP_CIPHER_CTX_cleanup(ctx);
- }
- }
-
- public void test_EVP_CIPHER_iv_length() throws Exception {
- long aes128ecb = NativeCrypto.EVP_get_cipherbyname("aes-128-ecb");
- assertEquals(0, NativeCrypto.EVP_CIPHER_iv_length(aes128ecb));
-
- long aes128cbc = NativeCrypto.EVP_get_cipherbyname("aes-128-cbc");
- assertEquals(16, NativeCrypto.EVP_CIPHER_iv_length(aes128cbc));
- }
-
- public void test_OpenSSLKey_toJava() throws Exception {
- OpenSSLKey key1;
-
- BigInteger e = BigInteger.valueOf(65537);
- key1 = new OpenSSLKey(NativeCrypto.RSA_generate_key_ex(1024, e.toByteArray()));
- assertTrue(key1.getPublicKey() instanceof RSAPublicKey);
-
- key1 = new OpenSSLKey(NativeCrypto.DSA_generate_key(1024, null, null, null, null));
- assertTrue(key1.getPublicKey() instanceof DSAPublicKey);
-
- long group1 = NULL;
- try {
- group1 = NativeCrypto.EC_GROUP_new_by_curve_name("prime256v1");
- assertTrue(group1 != NULL);
- key1 = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group1));
- } finally {
- if (group1 != NULL) {
- NativeCrypto.EC_GROUP_clear_free(group1);
- }
- }
- assertTrue(key1.getPublicKey() instanceof ECPublicKey);
- }
-
- public void test_create_BIO_InputStream() throws Exception {
- byte[] actual = "Test".getBytes();
- ByteArrayInputStream is = new ByteArrayInputStream(actual);
-
- long ctx = NativeCrypto.create_BIO_InputStream(new OpenSSLBIOInputStream(is));
- try {
- byte[] buffer = new byte[1024];
- int numRead = NativeCrypto.BIO_read(ctx, buffer);
- assertEquals(actual.length, numRead);
- assertEquals(Arrays.toString(actual),
- Arrays.toString(Arrays.copyOfRange(buffer, 0, numRead)));
- } finally {
- NativeCrypto.BIO_free(ctx);
- }
-
- }
-
- public void test_create_BIO_OutputStream() throws Exception {
- byte[] actual = "Test".getBytes();
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
- long ctx = NativeCrypto.create_BIO_OutputStream(os);
- try {
- NativeCrypto.BIO_write(ctx, actual, 0, actual.length);
- assertEquals(actual.length, os.size());
- assertEquals(Arrays.toString(actual), Arrays.toString(os.toByteArray()));
- } finally {
- NativeCrypto.BIO_free(ctx);
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java b/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java
deleted file mode 100644
index 045c509..0000000
--- a/crypto/src/test/java/org/conscrypt/OpenSSLSignatureTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.NoSuchAlgorithmException;
-import junit.framework.TestCase;
-
-public class OpenSSLSignatureTest extends TestCase {
-
- public void test_getInstance() throws Exception {
- try {
- OpenSSLSignature.getInstance("SHA1WITHDSA");
- OpenSSLSignature.getInstance("MD5WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA1WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA256WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA384WITHRSAENCRYPTION");
- OpenSSLSignature.getInstance("SHA512WITHRSAENCRYPTION");
- } catch (NoSuchAlgorithmException e) {
- fail("getInstance is not case insensitive");
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/SignatureTest.java b/crypto/src/test/java/org/conscrypt/SignatureTest.java
deleted file mode 100644
index d6679c4..0000000
--- a/crypto/src/test/java/org/conscrypt/SignatureTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.Security;
-import java.security.Signature;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Set;
-import junit.framework.TestCase;
-
-public class SignatureTest extends TestCase {
- // 20 bytes for DSA
- private final byte[] DATA = new byte[20];
-
- public void test_getInstance_OpenSSL_ENGINE() throws Exception {
- final String pem_private = "-----BEGIN RSA PRIVATE KEY-----\n"
- + "MIICXAIBAAKBgQDpm4KamxulJnycEzNONGM7p0CvAaoZxJEd5Dvio5b6BROdCtRN\n"
- + "lEsB+9vtB5thkyDVC7N+IW0AjtyDE6h2QP+AWa+c4dh0RM2uNVXkUWPrA8C++GHv\n"
- + "EDlxZzRGiQEMuippYfIyBVkO+4+GRvnkG4dKjzxrQYPqKUK3C4PgFW2FewIDAQAB\n"
- + "AoGAGUTSBsk6X03fcr588TundD9uNr/2V1002Ufj1msdnKPJ8FXIiy+8QVWt/2Cw\n"
- + "RQi2J3VhkAYrlUDex2rr8Qas3E9uuwKgg/MZ4EsJbnKKgkd7uBZfmZ2ogcNJ82u7\n"
- + "teVijFpdsVLDa9aczEppt5sZzyTaBrovrRb+AIRDpMw3I0ECQQD3JkWeQUA9Is1V\n"
- + "z0X/ly/kaQKQLlrwYNdiKF0qOpyTLAguI7asAS72Zj7fThk5bHLM+mmgYwkicIIb\n"
- + "67J32GQbAkEA8fkXqEnwMFYSkRmT9M/qUkwWUsMW12/AoZFI5gwKNDHZYxytGGLw\n"
- + "mC//0qKnyeUG00vz06vLApe4/Sq4ODe6IQJBALEGastF9ZtUuDsEciD2y8kRJlLb\n"
- + "wSt4Ug3u13yN6uTHnzxdPFTLrDW1WsdcC1lEQp5rpwjIpxxR9f/FvVl2V40CQHOY\n"
- + "F6EhkUjGFaCTo4b0PHCMQK3Q3PyWOmP0z+p2HfnJRpx+eoKH4YASjhfF9HoSmywd\n"
- + "wKGCFD1s1ca7vb29gYECQH86GmYZsDoLNWurEVJbkmCr7X1+xwim6umdrNKR27P7\n"
- + "F1y0Sa3YY+LiiRb+IRSWE/onlP+28LIzWGF4lcTfDMc=\n"
- + "-----END RSA PRIVATE KEY-----";
-
- final byte[] der_public = new byte[] {
- (byte) 0x30, (byte) 0x81, (byte) 0x9F, (byte) 0x30, (byte) 0x0D, (byte) 0x06,
- (byte) 0x09, (byte) 0x2A, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xF7,
- (byte) 0x0D, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
- (byte) 0x03, (byte) 0x81, (byte) 0x8D, (byte) 0x00, (byte) 0x30, (byte) 0x81,
- (byte) 0x89, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xE9,
- (byte) 0x9B, (byte) 0x82, (byte) 0x9A, (byte) 0x9B, (byte) 0x1B, (byte) 0xA5,
- (byte) 0x26, (byte) 0x7C, (byte) 0x9C, (byte) 0x13, (byte) 0x33, (byte) 0x4E,
- (byte) 0x34, (byte) 0x63, (byte) 0x3B, (byte) 0xA7, (byte) 0x40, (byte) 0xAF,
- (byte) 0x01, (byte) 0xAA, (byte) 0x19, (byte) 0xC4, (byte) 0x91, (byte) 0x1D,
- (byte) 0xE4, (byte) 0x3B, (byte) 0xE2, (byte) 0xA3, (byte) 0x96, (byte) 0xFA,
- (byte) 0x05, (byte) 0x13, (byte) 0x9D, (byte) 0x0A, (byte) 0xD4, (byte) 0x4D,
- (byte) 0x94, (byte) 0x4B, (byte) 0x01, (byte) 0xFB, (byte) 0xDB, (byte) 0xED,
- (byte) 0x07, (byte) 0x9B, (byte) 0x61, (byte) 0x93, (byte) 0x20, (byte) 0xD5,
- (byte) 0x0B, (byte) 0xB3, (byte) 0x7E, (byte) 0x21, (byte) 0x6D, (byte) 0x00,
- (byte) 0x8E, (byte) 0xDC, (byte) 0x83, (byte) 0x13, (byte) 0xA8, (byte) 0x76,
- (byte) 0x40, (byte) 0xFF, (byte) 0x80, (byte) 0x59, (byte) 0xAF, (byte) 0x9C,
- (byte) 0xE1, (byte) 0xD8, (byte) 0x74, (byte) 0x44, (byte) 0xCD, (byte) 0xAE,
- (byte) 0x35, (byte) 0x55, (byte) 0xE4, (byte) 0x51, (byte) 0x63, (byte) 0xEB,
- (byte) 0x03, (byte) 0xC0, (byte) 0xBE, (byte) 0xF8, (byte) 0x61, (byte) 0xEF,
- (byte) 0x10, (byte) 0x39, (byte) 0x71, (byte) 0x67, (byte) 0x34, (byte) 0x46,
- (byte) 0x89, (byte) 0x01, (byte) 0x0C, (byte) 0xBA, (byte) 0x2A, (byte) 0x69,
- (byte) 0x61, (byte) 0xF2, (byte) 0x32, (byte) 0x05, (byte) 0x59, (byte) 0x0E,
- (byte) 0xFB, (byte) 0x8F, (byte) 0x86, (byte) 0x46, (byte) 0xF9, (byte) 0xE4,
- (byte) 0x1B, (byte) 0x87, (byte) 0x4A, (byte) 0x8F, (byte) 0x3C, (byte) 0x6B,
- (byte) 0x41, (byte) 0x83, (byte) 0xEA, (byte) 0x29, (byte) 0x42, (byte) 0xB7,
- (byte) 0x0B, (byte) 0x83, (byte) 0xE0, (byte) 0x15, (byte) 0x6D, (byte) 0x85,
- (byte) 0x7B, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01
- };
-
- // We only need to test this on the OpenSSL provider.
- Provider p = Security.getProvider(OpenSSLProvider.PROVIDER_NAME);
-
- /* ENGINE-based private key */
- NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
- PrivateKey privKey = engine.getPrivateKeyById(pem_private);
- assertTrue(privKey instanceof RSAPrivateKey);
-
- /* Non-ENGINE-based public key */
- KeyFactory kf = KeyFactory.getInstance("RSA", p);
- PublicKey pubKey = kf.generatePublic(new X509EncodedKeySpec(der_public));
-
- KeyPair kp = new KeyPair(pubKey, privKey);
-
- Set<Provider.Service> services = p.getServices();
- for (Provider.Service service : services) {
- if ("Signature".equals(service.getType()) && service.getAlgorithm().contains("RSA")) {
- Signature sig1 = Signature.getInstance(service.getAlgorithm(), p);
- test_Signature(sig1, kp);
- }
- }
- }
-
- private void test_Signature(Signature sig, KeyPair keyPair) throws Exception {
- sig.initSign(keyPair.getPrivate());
- sig.update(DATA);
- byte[] signature = sig.sign();
- assertNotNull(sig.getAlgorithm(), signature);
- assertTrue(sig.getAlgorithm(), signature.length > 0);
-
- sig.initVerify(keyPair.getPublic());
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- // After verify, should be reusable as if we are after initVerify
- sig.update(DATA);
- assertTrue(sig.getAlgorithm(), sig.verify(signature));
-
- // Calling Signature.verify a second time should not throw
- // http://code.google.com/p/android/issues/detail?id=34933
- sig.verify(signature);
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java b/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java
deleted file mode 100644
index 639ed95..0000000
--- a/crypto/src/test/java/org/conscrypt/TrustManagerImplTest.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.security.KeyStore;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class TrustManagerImplTest extends TestCase {
-
- private List<File> tmpFiles = new ArrayList<File>();
-
- private String getFingerprint(X509Certificate cert) throws Exception {
- MessageDigest dgst = MessageDigest.getInstance("SHA512");
- byte[] encoded = cert.getPublicKey().getEncoded();
- byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
- }
-
- private String writeTmpPinFile(String text) throws Exception {
- File tmp = File.createTempFile("pins", null);
- FileWriter fstream = new FileWriter(tmp);
- fstream.write(text);
- fstream.close();
- tmpFiles.add(tmp);
- return tmp.getPath();
- }
-
- @Override
- public void tearDown() throws Exception {
- try {
- for (File f : tmpFiles) {
- f.delete();
- }
- tmpFiles.clear();
- } finally {
- super.tearDown();
- }
- }
-
- /**
- * Ensure that our non-standard behavior of learning to trust new
- * intermediate CAs does not regress. http://b/3404902
- */
- public void testLearnIntermediate() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- // Normal behavior
- assertValid(chain3, trustManager(root));
- assertValid(chain2, trustManager(root));
- assertInvalid(chain1, trustManager(root));
- assertValid(chain3, trustManager(intermediate));
- assertValid(chain2, trustManager(intermediate));
- assertValid(chain1, trustManager(intermediate));
- assertValid(chain3, trustManager(server));
- assertValid(chain2, trustManager(server));
- assertValid(chain1, trustManager(server));
-
- // non-standard behavior
- X509TrustManager tm = trustManager(root);
- // fail on short chain with only root trusted
- assertInvalid(chain1, tm);
- // succeed on longer chain, learn intermediate
- assertValid(chain2, tm);
- // now we can validate the short chain
- assertValid(chain1, tm);
- }
-
- // We should ignore duplicate cruft in the certificate chain
- // See https://code.google.com/p/android/issues/detail?id=52295 http://b/8313312
- public void testDuplicateInChain() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
-
- X509Certificate[] chain4 = new X509Certificate[] { server, intermediate,
- server, intermediate
- };
- assertValid(chain4, trustManager(root));
- }
-
- public void testGetFullChain() throws Exception {
- // build the trust manager
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[])pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509TrustManager tm = trustManager(root);
-
- // build the chains we'll use for testing
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- assertTrue(tm instanceof TrustManagerImpl);
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- List<X509Certificate> certs = tmi.checkServerTrusted(chain2, "RSA", "purple.com");
- assertEquals(Arrays.asList(chain3), certs);
- certs = tmi.checkServerTrusted(chain1, "RSA", "purple.com");
- assertEquals(Arrays.asList(chain3), certs);
- }
-
- public void testCertPinning() throws Exception {
- // chain3 should be server/intermediate/root
- KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- X509Certificate[] chain3 = (X509Certificate[]) pke.getCertificateChain();
- X509Certificate root = chain3[2];
- X509Certificate intermediate = chain3[1];
- X509Certificate server = chain3[0];
- X509Certificate[] chain2 = new X509Certificate[] { server, intermediate };
- X509Certificate[] chain1 = new X509Certificate[] { server };
-
- // test without a hostname, expecting failure
- assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), null);
- // test without a hostname, expecting success
- assertValidPinned(chain3, trustManager(root, "gugle.com", root), null, chain3);
- // test an unpinned hostname that should fail
- assertInvalidPinned(chain1, trustManager(root, "gugle.com", root), "purple.com");
- // test an unpinned hostname that should succeed
- assertValidPinned(chain3, trustManager(root, "gugle.com", root), "purple.com", chain3);
- // test a pinned hostname that should fail
- assertInvalidPinned(chain1, trustManager(intermediate, "gugle.com", root), "gugle.com");
- // test a pinned hostname that should succeed
- assertValidPinned(chain2, trustManager(intermediate, "gugle.com", server), "gugle.com",
- chain2);
- }
-
- private X509TrustManager trustManager(X509Certificate ca) throws Exception {
- KeyStore keyStore = TestKeyStore.createKeyStore();
- keyStore.setCertificateEntry("alias", ca);
-
- String algorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
- tmf.init(keyStore);
- return (X509TrustManager) tmf.getTrustManagers()[0];
- }
-
- private TrustManagerImpl trustManager(X509Certificate ca, String hostname, X509Certificate pin)
- throws Exception {
- // build the cert pin manager
- CertPinManager cm = certManager(hostname, pin);
- // insert it into the trust manager
- KeyStore keyStore = TestKeyStore.createKeyStore();
- keyStore.setCertificateEntry("alias", ca);
- return new TrustManagerImpl(keyStore, cm);
- }
-
- private CertPinManager certManager(String hostname, X509Certificate pin) throws Exception {
- String pinString = "";
- if (pin != null) {
- pinString = hostname + "=true|" + getFingerprint(pin);
- }
- // write it to a pinfile
- String path = writeTmpPinFile(pinString);
- // build the certpinmanager
- return new CertPinManager(path, new TrustedCertificateStore());
- }
-
- private void assertValid(X509Certificate[] chain, X509TrustManager tm) throws Exception {
- if (tm instanceof TrustManagerImpl) {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- tmi.checkServerTrusted(chain, "RSA");
- }
- tm.checkServerTrusted(chain, "RSA");
- }
-
- private void assertValidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname,
- X509Certificate[] fullChain) throws Exception {
- if (tm instanceof TrustManagerImpl) {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- List<X509Certificate> checkedChain = tmi.checkServerTrusted(chain, "RSA", hostname);
- assertEquals(checkedChain, Arrays.asList(fullChain));
- }
- tm.checkServerTrusted(chain, "RSA");
- }
-
- private void assertInvalid(X509Certificate[] chain, X509TrustManager tm) {
- try {
- tm.checkClientTrusted(chain, "RSA");
- fail();
- } catch (CertificateException expected) {
- }
- try {
- tm.checkServerTrusted(chain, "RSA");
- fail();
- } catch (CertificateException expected) {
- }
- }
-
- private void assertInvalidPinned(X509Certificate[] chain, X509TrustManager tm, String hostname)
- throws Exception {
- assertTrue(tm.getClass().getName(), tm instanceof TrustManagerImpl);
- try {
- TrustManagerImpl tmi = (TrustManagerImpl) tm;
- tmi.checkServerTrusted(chain, "RSA", hostname);
- fail();
- } catch (CertificateException expected) {
- }
- }
-}
diff --git a/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java b/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
deleted file mode 100644
index a8e9475..0000000
--- a/crypto/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.conscrypt;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import javax.security.auth.x500.X500Principal;
-import junit.framework.TestCase;
-import libcore.java.security.TestKeyStore;
-
-public class TrustedCertificateStoreTest extends TestCase {
-
- private static final File DIR_TEMP = new File(System.getProperty("java.io.tmpdir"));
- private static final File DIR_TEST = new File(DIR_TEMP, "test");
- private static final File DIR_SYSTEM = new File(DIR_TEST, "system");
- private static final File DIR_ADDED = new File(DIR_TEST, "added");
- private static final File DIR_DELETED = new File(DIR_TEST, "removed");
-
- private static X509Certificate CA1;
- private static X509Certificate CA2;
-
- private static KeyStore.PrivateKeyEntry PRIVATE;
- private static X509Certificate[] CHAIN;
-
- private static X509Certificate CA3_WITH_CA1_SUBJECT;
- private static String ALIAS_SYSTEM_CA1;
- private static String ALIAS_SYSTEM_CA2;
- private static String ALIAS_USER_CA1;
- private static String ALIAS_USER_CA2;
-
- private static String ALIAS_SYSTEM_CHAIN0;
- private static String ALIAS_SYSTEM_CHAIN1;
- private static String ALIAS_SYSTEM_CHAIN2;
- private static String ALIAS_USER_CHAIN0;
- private static String ALIAS_USER_CHAIN1;
- private static String ALIAS_USER_CHAIN2;
-
- private static String ALIAS_SYSTEM_CA3;
- private static String ALIAS_SYSTEM_CA3_COLLISION;
- private static String ALIAS_USER_CA3;
- private static String ALIAS_USER_CA3_COLLISION;
-
- private static X509Certificate getCa1() {
- initCerts();
- return CA1;
- }
- private static X509Certificate getCa2() {
- initCerts();
- return CA2;
- }
-
- private static KeyStore.PrivateKeyEntry getPrivate() {
- initCerts();
- return PRIVATE;
- }
- private static X509Certificate[] getChain() {
- initCerts();
- return CHAIN;
- }
-
- private static X509Certificate getCa3WithCa1Subject() {
- initCerts();
- return CA3_WITH_CA1_SUBJECT;
- }
-
- private static String getAliasSystemCa1() {
- initCerts();
- return ALIAS_SYSTEM_CA1;
- }
- private static String getAliasSystemCa2() {
- initCerts();
- return ALIAS_SYSTEM_CA2;
- }
- private static String getAliasUserCa1() {
- initCerts();
- return ALIAS_USER_CA1;
- }
- private static String getAliasUserCa2() {
- initCerts();
- return ALIAS_USER_CA2;
- }
-
- private static String getAliasSystemChain0() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN0;
- }
- private static String getAliasSystemChain1() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN1;
- }
- private static String getAliasSystemChain2() {
- initCerts();
- return ALIAS_SYSTEM_CHAIN2;
- }
- private static String getAliasUserChain0() {
- initCerts();
- return ALIAS_USER_CHAIN0;
- }
- private static String getAliasUserChain1() {
- initCerts();
- return ALIAS_USER_CHAIN1;
- }
- private static String getAliasUserChain2() {
- initCerts();
- return ALIAS_USER_CHAIN2;
- }
-
- private static String getAliasSystemCa3() {
- initCerts();
- return ALIAS_SYSTEM_CA3;
- }
- private static String getAliasSystemCa3Collision() {
- initCerts();
- return ALIAS_SYSTEM_CA3_COLLISION;
- }
- private static String getAliasUserCa3() {
- initCerts();
- return ALIAS_USER_CA3;
- }
- private static String getAliasUserCa3Collision() {
- initCerts();
- return ALIAS_USER_CA3_COLLISION;
- }
-
- /**
- * Lazily create shared test certificates.
- */
- private static synchronized void initCerts() {
- if (CA1 != null) {
- return;
- }
- try {
- CA1 = TestKeyStore.getClient().getRootCertificate("RSA");
- CA2 = TestKeyStore.getClientCA2().getRootCertificate("RSA");
- PRIVATE = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
- CHAIN = (X509Certificate[]) PRIVATE.getCertificateChain();
- CA3_WITH_CA1_SUBJECT = new TestKeyStore.Builder()
- .aliasPrefix("unused")
- .subject(CA1.getSubjectX500Principal())
- .ca(true)
- .build().getRootCertificate("RSA");
-
-
- ALIAS_SYSTEM_CA1 = alias(false, CA1, 0);
- ALIAS_SYSTEM_CA2 = alias(false, CA2, 0);
- ALIAS_USER_CA1 = alias(true, CA1, 0);
- ALIAS_USER_CA2 = alias(true, CA2, 0);
-
- ALIAS_SYSTEM_CHAIN0 = alias(false, getChain()[0], 0);
- ALIAS_SYSTEM_CHAIN1 = alias(false, getChain()[1], 0);
- ALIAS_SYSTEM_CHAIN2 = alias(false, getChain()[2], 0);
- ALIAS_USER_CHAIN0 = alias(true, getChain()[0], 0);
- ALIAS_USER_CHAIN1 = alias(true, getChain()[1], 0);
- ALIAS_USER_CHAIN2 = alias(true, getChain()[2], 0);
-
- ALIAS_SYSTEM_CA3 = alias(false, CA3_WITH_CA1_SUBJECT, 0);
- ALIAS_SYSTEM_CA3_COLLISION = alias(false, CA3_WITH_CA1_SUBJECT, 1);
- ALIAS_USER_CA3 = alias(true, CA3_WITH_CA1_SUBJECT, 0);
- ALIAS_USER_CA3_COLLISION = alias(true, CA3_WITH_CA1_SUBJECT, 1);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private TrustedCertificateStore store;
-
- @Override protected void setUp() {
- setupStore();
- }
-
- private void setupStore() {
- DIR_SYSTEM.mkdirs();
- createStore();
- }
-
- private void createStore() {
- store = new TrustedCertificateStore(DIR_SYSTEM, DIR_ADDED, DIR_DELETED);
- }
-
- @Override protected void tearDown() {
- cleanStore();
- }
-
- private void cleanStore() {
- for (File dir : new File[] { DIR_SYSTEM, DIR_ADDED, DIR_DELETED, DIR_TEST }) {
- File[] files = dir.listFiles();
- if (files == null) {
- continue;
- }
- for (File file : files) {
- assertTrue(file.delete());
- }
- }
- store = null;
- }
-
- private void resetStore() {
- cleanStore();
- setupStore();
- }
-
- public void testEmptyDirectories() throws Exception {
- assertEmpty();
- }
-
- public void testOneSystemOneDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testTwoSystemTwoDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- install(getCa2(), getAliasSystemCa2());
- store.deleteCertificateEntry(getAliasSystemCa2());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertDeleted(getCa2(), getAliasSystemCa2());
- }
-
- public void testPartialFileIsIgnored() throws Exception {
- File file = file(getAliasSystemCa1());
- OutputStream os = new FileOutputStream(file);
- os.write(0);
- os.close();
- assertTrue(file.exists());
- assertEmpty();
- assertTrue(file.exists());
- }
-
- private void assertEmpty() throws Exception {
- try {
- store.getCertificate(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.getCertificate(""));
-
- try {
- store.getCreationDate(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.getCreationDate(""));
-
- Set<String> s = store.aliases();
- assertNotNull(s);
- assertTrue(s.isEmpty());
- assertAliases();
-
- Set<String> u = store.userAliases();
- assertNotNull(u);
- assertTrue(u.isEmpty());
-
- try {
- store.containsAlias(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertFalse(store.containsAlias(""));
-
- assertNull(store.getCertificateAlias(null));
- assertNull(store.getCertificateAlias(getCa1()));
-
- try {
- store.isTrustAnchor(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertFalse(store.isTrustAnchor(getCa1()));
-
- try {
- store.findIssuer(null);
- fail();
- } catch (NullPointerException expected) {
- }
- assertNull(store.findIssuer(getCa1()));
-
- try {
- store.installCertificate(null);
- fail();
- } catch (NullPointerException expected) {
- }
-
- store.deleteCertificateEntry(null);
- store.deleteCertificateEntry("");
-
- String[] userFiles = DIR_ADDED.list();
- assertTrue(userFiles == null || userFiles.length == 0);
- }
-
- public void testTwoSystem() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa2(), getAliasSystemCa2());
- }
-
- public void testTwoUser() throws Exception {
- testTwo(getCa1(), getAliasUserCa1(),
- getCa2(), getAliasUserCa2());
- }
-
- public void testOneSystemOneUser() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa2(), getAliasUserCa2());
- }
-
- public void testTwoSystemSameSubject() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa3WithCa1Subject(), getAliasSystemCa3Collision());
- }
-
- public void testTwoUserSameSubject() throws Exception {
- testTwo(getCa1(), getAliasUserCa1(),
- getCa3WithCa1Subject(), getAliasUserCa3Collision());
-
- store.deleteCertificateEntry(getAliasUserCa1());
- assertDeleted(getCa1(), getAliasUserCa1());
- assertTombstone(getAliasUserCa1());
- assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3Collision());
- assertAliases(getAliasUserCa3Collision());
-
- store.deleteCertificateEntry(getAliasUserCa3Collision());
- assertDeleted(getCa3WithCa1Subject(), getAliasUserCa3Collision());
- assertNoTombstone(getAliasUserCa3Collision());
- assertNoTombstone(getAliasUserCa1());
- assertEmpty();
- }
-
- public void testOneSystemOneUserSameSubject() throws Exception {
- testTwo(getCa1(), getAliasSystemCa1(),
- getCa3WithCa1Subject(), getAliasUserCa3());
- testTwo(getCa1(), getAliasUserCa1(),
- getCa3WithCa1Subject(), getAliasSystemCa3());
- }
-
- private void testTwo(X509Certificate x1, String alias1,
- X509Certificate x2, String alias2) {
- install(x1, alias1);
- install(x2, alias2);
- assertRootCa(x1, alias1);
- assertRootCa(x2, alias2);
- assertAliases(alias1, alias2);
- }
-
-
- public void testOneSystemOneUserOneDeleted() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.installCertificate(getCa2());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa2(), getAliasUserCa2());
- assertAliases(getAliasUserCa2());
- }
-
- public void testOneSystemOneUserOneDeletedSameSubject() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.installCertificate(getCa3WithCa1Subject());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertDeleted(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa3WithCa1Subject(), getAliasUserCa3());
- assertAliases(getAliasUserCa3());
- }
-
- public void testUserMaskingSystem() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- install(getCa1(), getAliasUserCa1());
- assertMasked(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasSystemCa1(), getAliasUserCa1());
- }
-
- public void testChain() throws Exception {
- testChain(getAliasSystemChain1(), getAliasSystemChain2());
- testChain(getAliasSystemChain1(), getAliasUserChain2());
- testChain(getAliasUserChain1(), getAliasSystemCa1());
- testChain(getAliasUserChain1(), getAliasUserChain2());
- }
-
- private void testChain(String alias1, String alias2) throws Exception {
- install(getChain()[1], alias1);
- install(getChain()[2], alias2);
- assertIntermediateCa(getChain()[1], alias1);
- assertRootCa(getChain()[2], alias2);
- assertAliases(alias1, alias2);
- assertEquals(getChain()[2], store.findIssuer(getChain()[1]));
- assertEquals(getChain()[1], store.findIssuer(getChain()[0]));
-
- X509Certificate[] expected = getChain();
- List<X509Certificate> actualList = store.getCertificateChain(expected[0]);
-
- assertEquals("Generated CA list should be same length", expected.length, actualList.size());
- for (int i = 0; i < expected.length; i++) {
- assertEquals("Chain value should be the same for position " + i, expected[i],
- actualList.get(i));
- }
- resetStore();
- }
-
- public void testMissingSystemDirectory() throws Exception {
- cleanStore();
- createStore();
- assertEmpty();
- }
-
- public void testWithExistingUserDirectories() throws Exception {
- DIR_ADDED.mkdirs();
- DIR_DELETED.mkdirs();
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
- }
-
- public void testIsTrustAnchorWithReissuedgetCa() throws Exception {
- PublicKey publicKey = getPrivate().getCertificate().getPublicKey();
- PrivateKey privateKey = getPrivate().getPrivateKey();
- String name = "CN=CA4";
- X509Certificate ca1 = TestKeyStore.createCa(publicKey, privateKey, name);
- Thread.sleep(1 * 1000); // wait to ensure CAs vary by expiration
- X509Certificate ca2 = TestKeyStore.createCa(publicKey, privateKey, name);
- assertFalse(ca1.equals(ca2));
-
- String systemAlias = alias(false, ca1, 0);
- install(ca1, systemAlias);
- assertRootCa(ca1, systemAlias);
- assertTrue(store.isTrustAnchor(ca2));
- assertEquals(ca1, store.findIssuer(ca2));
- resetStore();
-
- String userAlias = alias(true, ca1, 0);
- store.installCertificate(ca1);
- assertRootCa(ca1, userAlias);
- assertTrue(store.isTrustAnchor(ca2));
- assertEquals(ca1, store.findIssuer(ca2));
- resetStore();
- }
-
- public void testInstallEmpty() throws Exception {
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
-
- // reinstalling should not change anything
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
- }
-
- public void testInstallEmptySystemExists() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- // reinstalling should not affect system CA
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- }
-
- public void testInstallEmptyDeletedSystemExists() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
-
- // installing should restore deleted system CA
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
- }
-
- public void testDeleteEmpty() throws Exception {
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testDeleteUser() throws Exception {
- store.installCertificate(getCa1());
- assertRootCa(getCa1(), getAliasUserCa1());
- assertAliases(getAliasUserCa1());
-
- store.deleteCertificateEntry(getAliasUserCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasUserCa1());
- assertNoTombstone(getAliasUserCa1());
- }
-
- public void testDeleteSystem() throws Exception {
- install(getCa1(), getAliasSystemCa1());
- assertRootCa(getCa1(), getAliasSystemCa1());
- assertAliases(getAliasSystemCa1());
-
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
-
- // deleting again should not change anything
- store.deleteCertificateEntry(getAliasSystemCa1());
- assertEmpty();
- assertDeleted(getCa1(), getAliasSystemCa1());
- }
-
- public void testIsUserAddedCertificate() throws Exception {
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa1(), getAliasSystemCa1());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa1(), getAliasUserCa1());
- assertTrue(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- install(getCa2(), getAliasUserCa2());
- assertTrue(store.isUserAddedCertificate(getCa1()));
- assertTrue(store.isUserAddedCertificate(getCa2()));
- store.deleteCertificateEntry(getAliasUserCa1());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertTrue(store.isUserAddedCertificate(getCa2()));
- store.deleteCertificateEntry(getAliasUserCa2());
- assertFalse(store.isUserAddedCertificate(getCa1()));
- assertFalse(store.isUserAddedCertificate(getCa2()));
- }
-
- private void assertRootCa(X509Certificate x, String alias) {
- assertIntermediateCa(x, alias);
- assertEquals(x, store.findIssuer(x));
- }
-
- private void assertTrusted(X509Certificate x, String alias) {
- assertEquals(x, store.getCertificate(alias));
- assertEquals(file(alias).lastModified(), store.getCreationDate(alias).getTime());
- assertTrue(store.containsAlias(alias));
- assertTrue(store.isTrustAnchor(x));
- }
-
- private void assertIntermediateCa(X509Certificate x, String alias) {
- assertTrusted(x, alias);
- assertEquals(alias, store.getCertificateAlias(x));
- }
-
- private void assertMasked(X509Certificate x, String alias) {
- assertTrusted(x, alias);
- assertFalse(alias.equals(store.getCertificateAlias(x)));
- }
-
- private void assertDeleted(X509Certificate x, String alias) {
- assertNull(store.getCertificate(alias));
- assertFalse(store.containsAlias(alias));
- assertNull(store.getCertificateAlias(x));
- assertFalse(store.isTrustAnchor(x));
- assertEquals(store.allSystemAliases().contains(alias),
- store.getCertificate(alias, true) != null);
- }
-
- private void assertTombstone(String alias) {
- assertTrue(TrustedCertificateStore.isUser(alias));
- File file = file(alias);
- assertTrue(file.exists());
- assertEquals(0, file.length());
- }
-
- private void assertNoTombstone(String alias) {
- assertTrue(TrustedCertificateStore.isUser(alias));
- assertFalse(file(alias).exists());
- }
-
- private void assertAliases(String... aliases) {
- Set<String> expected = new HashSet<String>(Arrays.asList(aliases));
- Set<String> actual = new HashSet<String>();
- for (String alias : store.aliases()) {
- boolean system = TrustedCertificateStore.isSystem(alias);
- boolean user = TrustedCertificateStore.isUser(alias);
- if (system || user) {
- assertEquals(system, store.allSystemAliases().contains(alias));
- assertEquals(user, store.userAliases().contains(alias));
- actual.add(alias);
- } else {
- throw new AssertionError(alias);
- }
- }
- assertEquals(expected, actual);
- }
-
- /**
- * format a certificate alias
- */
- private static String alias(boolean user, X509Certificate x, int index) {
- String prefix = user ? "user:" : "system:";
-
- X500Principal subject = x.getSubjectX500Principal();
- int intHash = NativeCrypto.X509_NAME_hash_old(subject);
- String strHash = IntegralToString.intToHexString(intHash, false, 8);
-
- return prefix + strHash + '.' + index;
- }
-
- /**
- * Install certificate under specified alias
- */
- private static void install(X509Certificate x, String alias) {
- try {
- File file = file(alias);
- file.getParentFile().mkdirs();
- OutputStream out = new FileOutputStream(file);
- out.write(x.getEncoded());
- out.close();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Compute file for an alias
- */
- private static File file(String alias) {
- File dir;
- if (TrustedCertificateStore.isSystem(alias)) {
- dir = DIR_SYSTEM;
- } else if (TrustedCertificateStore.isUser(alias)) {
- dir = DIR_ADDED;
- } else {
- throw new IllegalArgumentException(alias);
- }
-
- int index = alias.lastIndexOf(":");
- if (index == -1) {
- throw new IllegalArgumentException(alias);
- }
- String filename = alias.substring(index+1);
-
- return new File(dir, filename);
- }
-}