summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCasey Marshall <csm@gnu.org>2006-07-15 00:51:02 +0000
committerCasey Marshall <csm@gnu.org>2006-07-15 00:51:02 +0000
commitc5b0021ff787e0b4a2c83c0d908ac008ce45215b (patch)
tree5493f567fbbde344fd140fda0efae37c22acc5e2
parent34f553db4913a9b7810298cadf3cf8b126688aaa (diff)
downloadclasspath-c5b0021ff787e0b4a2c83c0d908ac008ce45215b.tar.gz
2006-07-14 Casey Marshall <csm@gnu.org>
* gnu/classpath/debug/Component.java (SSL_DELEGATED_TASK): new constant. * gnu/classpath/debug/SystemLogger.java (getSystemLogger): new class method. * gnu/javax/crypto/RSACipherImpl.java (logger): make instance of SystemLogger. (doFinal): use `EME_PKCS1_V1_5' to pad/unpad. * gnu/javax/net/ssl/AbstractSessionContext.java (getSession): new method. * gnu/javax/net/ssl/PreSharedKeyManager.java: new file. * gnu/javax/net/ssl/PreSharedKeyManagerParameters.java: new file. * gnu/javax/net/ssl/provider/AbstractHandshake.java: move delegated task classes to the end. (handleInput): don't stop processing current input if tasks are scheduled. (DHE_PSKGen): new class. * gnu/javax/net/ssl/provider/CertificateStatusRequest.java (buffer): make non-final. (<init>): new "builder" constructor. (buffer): new method. * gnu/javax/net/ssl/provider/CertificateURL.java (buffer): make non-final. (<init>): new "builder" constructor. (buffer): new method. (URLAndOptionalHash): implement Builder. (URLAndOptionalHash.<init>): set buffer order to BIG_ENDIAN. (URLAndOptionalHash.<init>, URLAndOptionalHash.<init>): new "builder" constructors. (URLAndOptionalHash.buffer): new method. * gnu/javax/net/ssl/provider/CipherSuite.java: replace DIFFIE_HELLMAN with qualified algorithm. (TLS_PSK_WITH_RC4_128_SHA, TLS_PSK_WITH_3DES_EDE_CBC_SHA, TLS_PSK_WITH_AES_128_CBC_SHA, TLS_PSK_WITH_AES_256_CBC_SHA, TLS_DHE_PSK_WITH_RC4_128_SHA, TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, TLS_DHE_PSK_WITH_AES_128_CBC_SHA, TLS_DHE_PSK_WITH_AES_256_CBC_SHA, TLS_RSA_PSK_WITH_RC4_128_SHA, TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, TLS_RSA_PSK_WITH_AES_128_CBC_SHA, TLS_RSA_PSK_WITH_AES_256_CBC_SHA): new constants. * gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java: new file. * gnu/javax/net/ssl/provider/ClientHandshake.java (maxFragmentLengthSent, truncatedHMacSent, sentVersion): new fields. (implHandleInput): handle hello extensions; handle PSK key exchange. (implHandleOutput): send extensions if configured; handle PSK key exchange. (enableExtensions, maxFragmentLength, truncatedHMac, getPSKIdentity): new methods. (RSAGen.implRun): use the protocol version we sent in the generated secret, not the agreed version. * gnu/javax/net/ssl/provider/ClientHello.java: remove unused imports. (disableExtensions): new field. (length): use `disableExtensions' field. (extensions): fix telling if there are extensions. * gnu/javax/net/ssl/provider/ClientHelloBuilder.java (setExtensions): fix. (setDisableExtensions): new method. * gnu/javax/net/ssl/provider/ClientKeyExchange.java (exchangeKeys): handle PSK exchange. * gnu/javax/net/ssl/provider/ClientPSKParameters.java: new file. * gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java: new file. * gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java (toString): include hexdump output. * gnu/javax/net/ssl/provider/Extension.java: implement Builder. (buffer): mark non-final. (<init>): make public. (<init>): new "builder" constructor. (length): include length of the extension type. (buffer): new method. (Value): implement Builder. * gnu/javax/net/ssl/provider/ExtensionList.java: implement Builder. (<init>): new "builder" constructor. (get): fix. (length): return total length, including length field. * gnu/javax/net/ssl/provider/InputSecurityParameters.java (decrypt): handle stream ciphers (with no padding) properly. * gnu/javax/net/ssl/provider/Jessie.java (<init>): add JessiePSK key manager factory. * gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java (DIFFIE_HELLMAN): removed. (DH_DSS, DH_RSA, DH_anon, DHE_DSS, DHE_RSA, PSK, DHE_PSK, RSA_PSK): new enum constants. * gnu/javax/net/ssl/provider/MaxFragmentLength.java (buffer): new method. * gnu/javax/net/ssl/provider/OutputSecurityParameters.java (encrypt): don't use `doFinal.' * gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java: new file. * gnu/javax/net/ssl/provider/SSLContextImpl.java (pskManager): new field. (engineInit): initialize PSK manager, if specified. * gnu/javax/net/ssl/provider/SSLEngineImpl.java (unwrap): debug logging; don't log warnings on closure alerts. * gnu/javax/net/ssl/provider/SSLSocketImpl.java (SocketOutputStream.write): throw an exception if the handshake threw one in another thread; clear the output buffer after writing the record. (doHandshake): fix this; capture exceptions thrown here, for other threads. * gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java: new file. * gnu/javax/net/ssl/provider/ServerDHParams.java (algorithm): mark deprecated (it's difficult to support this properly). * gnu/javax/net/ssl/provider/ServerHandshake.java (chooseSuites): select suites based on key exchange algorithm. (implHandleInput): handle key exchange better; handle PSK exchange. (implHandleOutput): likewise. (CertLoader.implRun): just use key exchange name directly. (RSA_PSKExchange): new class. * gnu/javax/net/ssl/provider/ServerKeyExchange.java (params): handle PSK exchange algorithms. (signature): likewise. * gnu/javax/net/ssl/provider/ServerNameList.java (buffer): make non-final. (<init>): new "builder" constructor. (buffer): new method. (ServerName.buffer): make non-final. (ServerName.<init>): new "builder" constructor. (ServerName.length): return total length, including type and length fields. (ServerName.buffer): new method. * gnu/javax/net/ssl/provider/ServerPSKParameters.java: new file. * gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java: new file. * gnu/javax/net/ssl/provider/TruncatedHMAC.java (buffer): new method. * gnu/javax/net/ssl/provider/TrustedAuthorities.java (<init>): set buffer order to BIG_ENDIAN. (buffer): new method. * gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java (buffer): new method. * gnu/javax/net/ssl/provider/Util.java (wrapBuffer, wrapBuffer): new methods. (WrappedBuffer): new class. * gnu/javax/net/ssl/provider/X509KeyManagerFactory.java (getAliases): add RSA_PSK.
-rw-r--r--ChangeLog-ssl-nio145
-rw-r--r--gnu/classpath/debug/Component.java7
-rw-r--r--gnu/classpath/debug/SystemLogger.java12
-rw-r--r--gnu/javax/crypto/RSACipherImpl.java42
-rw-r--r--gnu/javax/net/ssl/AbstractSessionContext.java29
-rw-r--r--gnu/javax/net/ssl/PreSharedKeyManager.java54
-rw-r--r--gnu/javax/net/ssl/PreSharedKeyManagerParameters.java83
-rw-r--r--gnu/javax/net/ssl/provider/AbstractHandshake.java263
-rw-r--r--gnu/javax/net/ssl/provider/CertificateStatusRequest.java70
-rw-r--r--gnu/javax/net/ssl/provider/CertificateURL.java96
-rw-r--r--gnu/javax/net/ssl/provider/CipherSuite.java138
-rw-r--r--gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java122
-rw-r--r--gnu/javax/net/ssl/provider/ClientHandshake.java187
-rw-r--r--gnu/javax/net/ssl/provider/ClientHello.java33
-rw-r--r--gnu/javax/net/ssl/provider/ClientHelloBuilder.java11
-rw-r--r--gnu/javax/net/ssl/provider/ClientKeyExchange.java12
-rw-r--r--gnu/javax/net/ssl/provider/ClientPSKParameters.java122
-rw-r--r--gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java128
-rw-r--r--gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java22
-rw-r--r--gnu/javax/net/ssl/provider/Extension.java26
-rw-r--r--gnu/javax/net/ssl/provider/ExtensionList.java53
-rw-r--r--gnu/javax/net/ssl/provider/InputSecurityParameters.java9
-rw-r--r--gnu/javax/net/ssl/provider/Jessie.java1
-rw-r--r--gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java11
-rw-r--r--gnu/javax/net/ssl/provider/MaxFragmentLength.java9
-rw-r--r--gnu/javax/net/ssl/provider/OutputSecurityParameters.java11
-rw-r--r--gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java118
-rw-r--r--gnu/javax/net/ssl/provider/SSLContextImpl.java25
-rw-r--r--gnu/javax/net/ssl/provider/SSLEngineImpl.java32
-rw-r--r--gnu/javax/net/ssl/provider/SSLSocketImpl.java207
-rw-r--r--gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java148
-rw-r--r--gnu/javax/net/ssl/provider/ServerDHParams.java4
-rw-r--r--gnu/javax/net/ssl/provider/ServerHandshake.java302
-rw-r--r--gnu/javax/net/ssl/provider/ServerKeyExchange.java29
-rw-r--r--gnu/javax/net/ssl/provider/ServerNameList.java91
-rw-r--r--gnu/javax/net/ssl/provider/ServerPSKParameters.java127
-rw-r--r--gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java62
-rw-r--r--gnu/javax/net/ssl/provider/TruncatedHMAC.java45
-rw-r--r--gnu/javax/net/ssl/provider/TrustedAuthorities.java48
-rw-r--r--gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java43
-rw-r--r--gnu/javax/net/ssl/provider/Util.java27
-rw-r--r--gnu/javax/net/ssl/provider/X509KeyManagerFactory.java3
42 files changed, 2524 insertions, 483 deletions
diff --git a/ChangeLog-ssl-nio b/ChangeLog-ssl-nio
index f65ef0a1f..a09cda046 100644
--- a/ChangeLog-ssl-nio
+++ b/ChangeLog-ssl-nio
@@ -1,3 +1,148 @@
+2006-07-14 Casey Marshall <csm@gnu.org>
+
+ * gnu/classpath/debug/Component.java (SSL_DELEGATED_TASK): new
+ constant.
+ * gnu/classpath/debug/SystemLogger.java (getSystemLogger): new
+ class method.
+ * gnu/javax/crypto/RSACipherImpl.java (logger): make instance of
+ SystemLogger.
+ (doFinal): use `EME_PKCS1_V1_5' to pad/unpad.
+ * gnu/javax/net/ssl/AbstractSessionContext.java (getSession): new
+ method.
+ * gnu/javax/net/ssl/PreSharedKeyManager.java: new file.
+ * gnu/javax/net/ssl/PreSharedKeyManagerParameters.java: new file.
+ * gnu/javax/net/ssl/provider/AbstractHandshake.java: move
+ delegated task classes to the end.
+ (handleInput): don't stop processing current input if tasks are
+ scheduled.
+ (DHE_PSKGen): new class.
+ * gnu/javax/net/ssl/provider/CertificateStatusRequest.java
+ (buffer): make non-final.
+ (<init>): new "builder" constructor.
+ (buffer): new method.
+ * gnu/javax/net/ssl/provider/CertificateURL.java (buffer): make
+ non-final.
+ (<init>): new "builder" constructor.
+ (buffer): new method.
+ (URLAndOptionalHash): implement Builder.
+ (URLAndOptionalHash.<init>): set buffer order to BIG_ENDIAN.
+ (URLAndOptionalHash.<init>, URLAndOptionalHash.<init>): new
+ "builder" constructors.
+ (URLAndOptionalHash.buffer): new method.
+ * gnu/javax/net/ssl/provider/CipherSuite.java: replace
+ DIFFIE_HELLMAN with qualified algorithm.
+ (TLS_PSK_WITH_RC4_128_SHA, TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+ TLS_PSK_WITH_AES_128_CBC_SHA, TLS_PSK_WITH_AES_256_CBC_SHA,
+ TLS_DHE_PSK_WITH_RC4_128_SHA, TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
+ TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
+ TLS_RSA_PSK_WITH_RC4_128_SHA, TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
+ TLS_RSA_PSK_WITH_AES_256_CBC_SHA): new constants.
+ * gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java: new
+ file.
+ * gnu/javax/net/ssl/provider/ClientHandshake.java
+ (maxFragmentLengthSent, truncatedHMacSent, sentVersion): new
+ fields.
+ (implHandleInput): handle hello extensions; handle PSK key
+ exchange.
+ (implHandleOutput): send extensions if configured; handle PSK key
+ exchange.
+ (enableExtensions, maxFragmentLength, truncatedHMac,
+ getPSKIdentity): new methods.
+ (RSAGen.implRun): use the protocol version we sent in the
+ generated secret, not the agreed version.
+ * gnu/javax/net/ssl/provider/ClientHello.java: remove unused
+ imports.
+ (disableExtensions): new field.
+ (length): use `disableExtensions' field.
+ (extensions): fix telling if there are extensions.
+ * gnu/javax/net/ssl/provider/ClientHelloBuilder.java
+ (setExtensions): fix.
+ (setDisableExtensions): new method.
+ * gnu/javax/net/ssl/provider/ClientKeyExchange.java
+ (exchangeKeys): handle PSK exchange.
+ * gnu/javax/net/ssl/provider/ClientPSKParameters.java: new file.
+ * gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java: new
+ file.
+ * gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java
+ (toString): include hexdump output.
+ * gnu/javax/net/ssl/provider/Extension.java: implement Builder.
+ (buffer): mark non-final.
+ (<init>): make public.
+ (<init>): new "builder" constructor.
+ (length): include length of the extension type.
+ (buffer): new method.
+ (Value): implement Builder.
+ * gnu/javax/net/ssl/provider/ExtensionList.java: implement
+ Builder.
+ (<init>): new "builder" constructor.
+ (get): fix.
+ (length): return total length, including length field.
+ * gnu/javax/net/ssl/provider/InputSecurityParameters.java
+ (decrypt): handle stream ciphers (with no padding) properly.
+ * gnu/javax/net/ssl/provider/Jessie.java (<init>): add JessiePSK
+ key manager factory.
+ * gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java
+ (DIFFIE_HELLMAN): removed.
+ (DH_DSS, DH_RSA, DH_anon, DHE_DSS, DHE_RSA, PSK, DHE_PSK,
+ RSA_PSK): new enum constants.
+ * gnu/javax/net/ssl/provider/MaxFragmentLength.java (buffer): new
+ method.
+ * gnu/javax/net/ssl/provider/OutputSecurityParameters.java
+ (encrypt): don't use `doFinal.'
+ * gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java:
+ new file.
+ * gnu/javax/net/ssl/provider/SSLContextImpl.java (pskManager): new
+ field.
+ (engineInit): initialize PSK manager, if specified.
+ * gnu/javax/net/ssl/provider/SSLEngineImpl.java (unwrap): debug
+ logging; don't log warnings on closure alerts.
+ * gnu/javax/net/ssl/provider/SSLSocketImpl.java
+ (SocketOutputStream.write): throw an exception if the handshake
+ threw one in another thread; clear the output buffer after writing
+ the record.
+ (doHandshake): fix this; capture exceptions thrown here, for other
+ threads.
+ * gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java: new
+ file.
+ * gnu/javax/net/ssl/provider/ServerDHParams.java (algorithm): mark
+ deprecated (it's difficult to support this properly).
+ * gnu/javax/net/ssl/provider/ServerHandshake.java
+ (chooseSuites): select suites based on key exchange algorithm.
+ (implHandleInput): handle key exchange better; handle PSK
+ exchange.
+ (implHandleOutput): likewise.
+ (CertLoader.implRun): just use key exchange name directly.
+ (RSA_PSKExchange): new class.
+ * gnu/javax/net/ssl/provider/ServerKeyExchange.java (params):
+ handle PSK exchange algorithms.
+ (signature): likewise.
+ * gnu/javax/net/ssl/provider/ServerNameList.java
+ (buffer): make non-final.
+ (<init>): new "builder" constructor.
+ (buffer): new method.
+ (ServerName.buffer): make non-final.
+ (ServerName.<init>): new "builder" constructor.
+ (ServerName.length): return total length, including type and
+ length fields.
+ (ServerName.buffer): new method.
+ * gnu/javax/net/ssl/provider/ServerPSKParameters.java: new file.
+ * gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java: new
+ file.
+ * gnu/javax/net/ssl/provider/TruncatedHMAC.java (buffer): new
+ method.
+ * gnu/javax/net/ssl/provider/TrustedAuthorities.java (<init>): set
+ buffer order to BIG_ENDIAN.
+ (buffer): new method.
+ * gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java
+ (buffer): new method.
+ * gnu/javax/net/ssl/provider/Util.java (wrapBuffer, wrapBuffer):
+ new methods.
+ (WrappedBuffer): new class.
+ * gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
+ (getAliases): add RSA_PSK.
+
2006-07-12 Casey Marshall <csm@gnu.org>
* gnu/javax/security/auth/callback/CertificateCallback.java: new
diff --git a/gnu/classpath/debug/Component.java b/gnu/classpath/debug/Component.java
index 0cc38d709..dce257502 100644
--- a/gnu/classpath/debug/Component.java
+++ b/gnu/classpath/debug/Component.java
@@ -97,8 +97,13 @@ public final class Component extends Level
* Trace details about the SSL key exchange.
*/
public static final Component SSL_KEY_EXCHANGE = new Component ("SSL KEY EXCHANGE", 2);
+
+ /**
+ * Trace running of delegated tasks.
+ */
+ public static final Component SSL_DELEGATED_TASK = new Component ("SSL DELEGATED TASK", 3);
- /* Indices 3 and 4 reserved for future use by SSL components. */
+ /* Index 4 reserved for future use by SSL components. */
/**
* Trace the operation of cryptographic primitives.
diff --git a/gnu/classpath/debug/SystemLogger.java b/gnu/classpath/debug/SystemLogger.java
index f341b5d9e..5813ef2f8 100644
--- a/gnu/classpath/debug/SystemLogger.java
+++ b/gnu/classpath/debug/SystemLogger.java
@@ -67,6 +67,18 @@ public final class SystemLogger extends Logger
}
/**
+ * Fetch the system logger instance. The logger returned is meant for debug
+ * and diagnostic logging for Classpath internals.
+ *
+ * @return The system logger.
+ */
+ public static SystemLogger getSystemLogger()
+ {
+ // XXX Check some permission here?
+ return SYSTEM;
+ }
+
+ /**
* Keep only one instance of the system logger.
*/
private SystemLogger()
diff --git a/gnu/javax/crypto/RSACipherImpl.java b/gnu/javax/crypto/RSACipherImpl.java
index 0a4c29db6..05f77213e 100644
--- a/gnu/javax/crypto/RSACipherImpl.java
+++ b/gnu/javax/crypto/RSACipherImpl.java
@@ -41,11 +41,11 @@ package gnu.javax.crypto;
import gnu.classpath.ByteArray;
import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
+import gnu.java.security.sig.rsa.EME_PKCS1_V1_5;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
-import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
@@ -58,8 +58,6 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.logging.Logger;
-
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
@@ -69,7 +67,7 @@ import javax.crypto.ShortBufferException;
public class RSACipherImpl extends CipherSpi
{
- private static final Logger logger = SystemLogger.SYSTEM;
+ private static final SystemLogger logger = SystemLogger.SYSTEM;
private static final byte[] EMPTY = new byte[0];
private int opmode = -1;
@@ -210,37 +208,25 @@ public class RSACipherImpl extends CipherSpi
throw new IllegalBlockSizeException ("expecting exactly " + dataBuffer.length + " bytes");
BigInteger enc = new BigInteger (1, dataBuffer);
byte[] dec = rsaDecrypt (enc);
- logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}",
- new ByteArray (dec));
- if (dec[0] != 0x02)
- throw new BadPaddingException ("expected padding type 2");
- int i;
- for (i = 1; i < dec.length && dec[i] != 0x00; i++);
- int len = dec.length - i;
- byte[] result = new byte[len];
- System.arraycopy (dec, i, result, 0, len);
- pos = 0;
+ logger.log (Component.CRYPTO, "RSA: decryption produced\n{0}",
+ new ByteArray (dec));
+ EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(decipherKey);
+ byte[] result = pkcs.decode(dec);
return result;
}
else
{
offset = dataBuffer.length - pos;
if (offset < 3)
- throw new IllegalBlockSizeException ("input is too large to encrypt");
- byte[] dec = new byte[dataBuffer.length];
- dec[0] = 0x02;
+ throw new IllegalBlockSizeException("input is too large to encrypt");
+ EME_PKCS1_V1_5 pkcs = EME_PKCS1_V1_5.getInstance(encipherKey);
if (random == null)
- random = new SecureRandom ();
- byte[] pad = new byte[offset - 2];
- random.nextBytes (pad);
- for (int i = 0; i < pad.length; i++)
- if (pad[i] == 0)
- pad[i] = 1;
- System.arraycopy (pad, 0, dec, 1, pad.length);
- dec[dec.length - pos] = 0x00;
- System.arraycopy (dataBuffer, 0, dec, offset, pos);
- logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}",
- new ByteArray (dec));
+ random = new SecureRandom();
+ byte[] em = new byte[pos];
+ System.arraycopy(dataBuffer, 0, em, 0, pos);
+ byte[] dec = pkcs.encode(em, random);
+ logger.log (Component.CRYPTO, "RSA: produced padded plaintext\n{0}",
+ new ByteArray (dec));
BigInteger x = new BigInteger (1, dec);
BigInteger y = x.modPow (encipherKey.getPublicExponent (),
encipherKey.getModulus ());
diff --git a/gnu/javax/net/ssl/AbstractSessionContext.java b/gnu/javax/net/ssl/AbstractSessionContext.java
index 916fec089..bdd7f274e 100644
--- a/gnu/javax/net/ssl/AbstractSessionContext.java
+++ b/gnu/javax/net/ssl/AbstractSessionContext.java
@@ -42,6 +42,8 @@ import gnu.java.security.Requires;
import gnu.javax.net.ssl.provider.SimpleSessionContext;
+import java.util.Enumeration;
+
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPermission;
import javax.net.ssl.SSLSession;
@@ -182,6 +184,33 @@ public abstract class AbstractSessionContext implements SSLSessionContext
return s;
}
+ public final SSLSession getSession(String host, int port)
+ {
+ for (Enumeration e = getIds(); e.hasMoreElements(); )
+ {
+ byte[] id = (byte[]) e.nextElement();
+ SSLSession s = getSession(id);
+ if (s == null) // session expired.
+ continue;
+ String host2 = s.getPeerHost();
+ if (host == null)
+ {
+ if (host2 != null)
+ continue;
+ }
+ else if (!host.equals(host2))
+ continue;
+ int port2 = s.getPeerPort();
+ if (port != port2)
+ continue;
+
+ // Else, a match.
+ return s;
+ }
+
+ return null;
+ }
+
/**
* To be implemented by subclasses. Subclasses do not need to check
* timeouts in this method.
diff --git a/gnu/javax/net/ssl/PreSharedKeyManager.java b/gnu/javax/net/ssl/PreSharedKeyManager.java
new file mode 100644
index 000000000..ba6500a27
--- /dev/null
+++ b/gnu/javax/net/ssl/PreSharedKeyManager.java
@@ -0,0 +1,54 @@
+/* PreSharedKeyManager.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl;
+
+import java.security.KeyManagementException;
+
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+
+/**
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public interface PreSharedKeyManager extends KeyManager
+{
+ SecretKey getKey(String name) throws KeyManagementException;
+
+ String chooseIdentityHint();
+} \ No newline at end of file
diff --git a/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java b/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java
new file mode 100644
index 000000000..1b1d492b1
--- /dev/null
+++ b/gnu/javax/net/ssl/PreSharedKeyManagerParameters.java
@@ -0,0 +1,83 @@
+/* PreSharedKeyManagerParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
+import javax.crypto.SecretKey;
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class PreSharedKeyManagerParameters
+ implements ManagerFactoryParameters
+{
+ private final LinkedHashMap<String, SecretKey> keys;
+
+ public PreSharedKeyManagerParameters()
+ {
+ keys = new LinkedHashMap<String, SecretKey>();
+ }
+
+ public SecretKey getKey(String name)
+ {
+ name.getClass();
+ return keys.get(name);
+ }
+
+ public void putKey(String name, SecretKey key)
+ {
+ name.getClass();
+ key.getClass();
+ keys.put(name, key);
+ }
+
+ public boolean removeKey(String name)
+ {
+ name.getClass();
+ return keys.remove(name) != null;
+ }
+
+ public Iterator<String> identities()
+ {
+ return keys.keySet().iterator();
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/AbstractHandshake.java b/gnu/javax/net/ssl/provider/AbstractHandshake.java
index f930f2301..4b4a7972b 100644
--- a/gnu/javax/net/ssl/provider/AbstractHandshake.java
+++ b/gnu/javax/net/ssl/provider/AbstractHandshake.java
@@ -68,6 +68,7 @@ import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.IvParameterSpec;
@@ -210,7 +211,7 @@ public abstract class AbstractHandshake
if (!pollHandshake(fragment))
return HandshakeStatus.NEED_UNWRAP;
- while (hasMessage() && status == HandshakeStatus.NEED_UNWRAP)
+ while (hasMessage() && status != HandshakeStatus.NEED_WRAP)
{
int pos = handshakeOffset;
status = implHandleInput();
@@ -728,118 +729,6 @@ Certificate.signature.sha_hash
}
}
- protected class DHPhase extends DelegatedTask
- {
- private final DHPublicKey key;
-
- protected DHPhase(DHPublicKey key)
- {
- this.key = key;
- }
-
- protected void implRun() throws InvalidKeyException, SSLException
- {
- keyAgreement.doPhase(key, true);
- preMasterSecret = keyAgreement.generateSecret();
- generateMasterSecret(clientRandom, serverRandom, engine.session());
- byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
- setupSecurityParameters(keys, engine.getUseClientMode(), engine, compression);
- }
- }
-
- protected class CertVerifier extends DelegatedTask
- {
- private final boolean clientSide;
- private final X509Certificate[] chain;
- private boolean verified;
-
- protected CertVerifier(boolean clientSide, X509Certificate[] chain)
- {
- this.clientSide = clientSide;
- this.chain = chain;
- }
-
- boolean verified()
- {
- return verified;
- }
-
- protected void implRun()
- {
- X509TrustManager tm = engine.contextImpl.trustManager;
- if (clientSide)
- {
- try
- {
- tm.checkServerTrusted(chain, null);
- verified = true;
- }
- catch (CertificateException ce)
- {
- if (Debug.DEBUG)
- logger.log(Component.SSL_DELEGATED_TASK, "cert verify", ce);
- // For client connections, ask the user if the certificate is OK.
- CallbackHandler verify = new DefaultCallbackHandler();
- GetSecurityPropertyAction gspa
- = new GetSecurityPropertyAction("jessie.certificate.handler");
- String clazz = AccessController.doPrivileged(gspa);
- try
- {
- ClassLoader cl =
- AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
- {
- public ClassLoader run() throws Exception
- {
- return ClassLoader.getSystemClassLoader();
- }
- });
- verify = (CallbackHandler) cl.loadClass(clazz).newInstance();
- }
- catch (Exception x)
- {
- // Ignore.
- if (Debug.DEBUG)
- logger.log(Component.SSL_DELEGATED_TASK,
- "callback handler loading", x);
- }
- // XXX Internationalize
- CertificateCallback confirm =
- new CertificateCallback(chain[0],
- "The server's certificate could not be verified. There is no proof " +
- "that this server is who it claims to be, or that their certificate " +
- "is valid. Do you wish to continue connecting? ");
-
- try
- {
- verify.handle(new Callback[] { confirm });
- verified = confirm.getSelectedIndex() == ConfirmationCallback.YES;
- }
- catch (Exception x)
- {
- if (Debug.DEBUG)
- logger.log(Component.SSL_DELEGATED_TASK,
- "callback handler exception", x);
- verified = false;
- }
- }
- }
- else
- {
- try
- {
- tm.checkClientTrusted(chain, null);
- }
- catch (CertificateException ce)
- {
- verified = false;
- }
- }
-
- if (verified)
- engine.session().setPeerVerified(true);
- }
- }
-
protected void generateMasterSecret(Random clientRandom,
Random serverRandom,
SessionImpl session)
@@ -984,4 +873,152 @@ Certificate.signature.sha_hash
throw new SSLException(nspe);
}
}
+
+ protected class DHPhase extends DelegatedTask
+ {
+ private final DHPublicKey key;
+
+ protected DHPhase(DHPublicKey key)
+ {
+ this.key = key;
+ }
+
+ protected void implRun() throws InvalidKeyException, SSLException
+ {
+ keyAgreement.doPhase(key, true);
+ preMasterSecret = keyAgreement.generateSecret();
+ generateMasterSecret(clientRandom, serverRandom, engine.session());
+ byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
+ setupSecurityParameters(keys, engine.getUseClientMode(), engine, compression);
+ }
+ }
+
+ protected class CertVerifier extends DelegatedTask
+ {
+ private final boolean clientSide;
+ private final X509Certificate[] chain;
+ private boolean verified;
+
+ protected CertVerifier(boolean clientSide, X509Certificate[] chain)
+ {
+ this.clientSide = clientSide;
+ this.chain = chain;
+ }
+
+ boolean verified()
+ {
+ return verified;
+ }
+
+ protected void implRun()
+ {
+ X509TrustManager tm = engine.contextImpl.trustManager;
+ if (clientSide)
+ {
+ try
+ {
+ tm.checkServerTrusted(chain, null);
+ verified = true;
+ }
+ catch (CertificateException ce)
+ {
+ if (Debug.DEBUG)
+ logger.log(Component.SSL_DELEGATED_TASK, "cert verify", ce);
+ // For client connections, ask the user if the certificate is OK.
+ CallbackHandler verify = new DefaultCallbackHandler();
+ GetSecurityPropertyAction gspa
+ = new GetSecurityPropertyAction("jessie.certificate.handler");
+ String clazz = AccessController.doPrivileged(gspa);
+ try
+ {
+ ClassLoader cl =
+ AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
+ {
+ public ClassLoader run() throws Exception
+ {
+ return ClassLoader.getSystemClassLoader();
+ }
+ });
+ verify = (CallbackHandler) cl.loadClass(clazz).newInstance();
+ }
+ catch (Exception x)
+ {
+ // Ignore.
+ if (Debug.DEBUG)
+ logger.log(Component.SSL_DELEGATED_TASK,
+ "callback handler loading", x);
+ }
+ // XXX Internationalize
+ CertificateCallback confirm =
+ new CertificateCallback(chain[0],
+ "The server's certificate could not be verified. There is no proof " +
+ "that this server is who it claims to be, or that their certificate " +
+ "is valid. Do you wish to continue connecting? ");
+
+ try
+ {
+ verify.handle(new Callback[] { confirm });
+ verified = confirm.getSelectedIndex() == ConfirmationCallback.YES;
+ }
+ catch (Exception x)
+ {
+ if (Debug.DEBUG)
+ logger.log(Component.SSL_DELEGATED_TASK,
+ "callback handler exception", x);
+ verified = false;
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ tm.checkClientTrusted(chain, null);
+ }
+ catch (CertificateException ce)
+ {
+ verified = false;
+ }
+ }
+
+ if (verified)
+ engine.session().setPeerVerified(true);
+ }
+ }
+
+ protected class DHE_PSKGen extends DelegatedTask
+ {
+ private final DHPublicKey dhKey;
+ private final SecretKey psKey;
+ private final boolean isClient;
+
+ protected DHE_PSKGen(DHPublicKey dhKey, SecretKey psKey, boolean isClient)
+ {
+ this.dhKey = dhKey;
+ this.psKey = psKey;
+ this.isClient = isClient;
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.DelegatedTask#implRun()
+ */
+ @Override protected void implRun() throws Throwable
+ {
+ keyAgreement.doPhase(dhKey, true);
+ byte[] dhSecret = keyAgreement.generateSecret();
+ byte[] psSecret = psKey.getEncoded();
+ preMasterSecret = new byte[dhSecret.length + psSecret.length + 4];
+ preMasterSecret[0] = (byte) (dhSecret.length >>> 8);
+ preMasterSecret[1] = (byte) dhSecret.length;
+ System.arraycopy(dhSecret, 0, preMasterSecret, 2, dhSecret.length);
+ preMasterSecret[dhSecret.length + 2] = (byte) (psSecret.length >>> 8);
+ preMasterSecret[dhSecret.length + 3] = (byte) psSecret.length;
+ System.arraycopy(psSecret, 0, preMasterSecret, dhSecret.length + 4,
+ psSecret.length);
+
+ generateMasterSecret(clientRandom, serverRandom, engine.session());
+ byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
+ setupSecurityParameters(keys, isClient, engine, compression);
+ }
+ }
} \ No newline at end of file
diff --git a/gnu/javax/net/ssl/provider/CertificateStatusRequest.java b/gnu/javax/net/ssl/provider/CertificateStatusRequest.java
index 8bce9d549..059c6ec47 100644
--- a/gnu/javax/net/ssl/provider/CertificateStatusRequest.java
+++ b/gnu/javax/net/ssl/provider/CertificateStatusRequest.java
@@ -1,3 +1,41 @@
+/* CertificateStatusRequest.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
@@ -6,6 +44,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
/**
@@ -31,12 +70,36 @@ opaque Extensions&lt;0..2^16-1&gt;;</pre>
*/
public class CertificateStatusRequest extends Value implements Iterable<byte[]>
{
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
public CertificateStatusRequest(final ByteBuffer buffer)
{
this.buffer = buffer;
}
+
+ public CertificateStatusRequest(CertificateStatusType type,
+ List<byte[]> responderIdList,
+ byte[] requestExtensions)
+ {
+ if (type != CertificateStatusType.OCSP)
+ throw new IllegalArgumentException();
+ int length = 3;
+ int idsLength = 0;
+ for (byte[] responderId : responderIdList)
+ {
+ length += 2 + responderId.length;
+ idsLength += 2 + responderId.length;
+ }
+ length += 2 + requestExtensions.length;
+ buffer = ByteBuffer.allocate(length);
+ buffer.put((byte) 1);
+ buffer.putShort((short) idsLength);
+ for (byte[] responderId : responderIdList)
+ buffer.putShort((short) responderId.length).put(responderId);
+ buffer.putShort((short) requestExtensions.length);
+ buffer.put(requestExtensions);
+ buffer.rewind();
+ }
public int length()
{
@@ -44,6 +107,11 @@ public class CertificateStatusRequest extends Value implements Iterable<byte[]>
return l + (buffer.getShort(l) & 0xFFFF) + 2;
}
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
public CertificateStatusType statusType()
{
int x = buffer.get(0) & 0xFF;
diff --git a/gnu/javax/net/ssl/provider/CertificateURL.java b/gnu/javax/net/ssl/provider/CertificateURL.java
index 107b164e2..0bc1c428b 100644
--- a/gnu/javax/net/ssl/provider/CertificateURL.java
+++ b/gnu/javax/net/ssl/provider/CertificateURL.java
@@ -1,3 +1,41 @@
+/* CertificateURL.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
@@ -5,7 +43,11 @@ import gnu.javax.net.ssl.provider.Extension.Value;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.util.List;
import java.util.NoSuchElementException;
/**
@@ -41,17 +83,35 @@ opaque SHA1Hash[20];</pre>
*/
public class CertificateURL extends Value implements Iterable<CertificateURL.URLAndOptionalHash>
{
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
public CertificateURL(final ByteBuffer buffer)
{
this.buffer = buffer;
}
+ public CertificateURL(CertChainType type, List<URLAndOptionalHash> urls)
+ {
+ int length = 3;
+ for (URLAndOptionalHash url : urls)
+ length += url.length();
+ buffer = ByteBuffer.allocate(length);
+ buffer.put((byte) type.getValue());
+ buffer.putShort((short) (length - 1));
+ for (URLAndOptionalHash url : urls)
+ buffer.put(url.buffer());
+ buffer.rewind();
+ }
+
public int length()
{
return 3 + (buffer.getShort(1) & 0xFFFF);
}
+
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
public CertChainType type()
{
@@ -211,13 +271,36 @@ public class CertificateURL extends Value implements Iterable<CertificateURL.URL
}
}
- public static class URLAndOptionalHash implements Constructed
+ public static class URLAndOptionalHash implements Builder, Constructed
{
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
public URLAndOptionalHash (final ByteBuffer buffer)
{
- this.buffer = buffer;
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public URLAndOptionalHash(String url)
+ {
+ this(url, null);
+ }
+
+ public URLAndOptionalHash(String url, byte[] hash)
+ {
+ if (hash != null && hash.length < 20)
+ throw new IllegalArgumentException();
+ int length = 3 + url.length();
+ if (hash != null)
+ length += 20;
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) url.length());
+ Charset cs = Charset.forName("US-ASCII");
+ CharsetEncoder ascii = cs.newEncoder();
+ ascii.encode(CharBuffer.wrap(url), buffer, true);
+ buffer.put((byte) (hash != null ? 1 : 0));
+ if (hash != null)
+ buffer.put(hash, 0, 20);
+ buffer.rewind();
}
public int length()
@@ -226,6 +309,11 @@ public class CertificateURL extends Value implements Iterable<CertificateURL.URL
+ (hashPresent() ? 23 : 3));
}
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
public String url()
{
Charset cs = Charset.forName("ASCII");
diff --git a/gnu/javax/net/ssl/provider/CipherSuite.java b/gnu/javax/net/ssl/provider/CipherSuite.java
index f3fbdcbc2..ee02e8281 100644
--- a/gnu/javax/net/ssl/provider/CipherSuite.java
+++ b/gnu/javax/net/ssl/provider/CipherSuite.java
@@ -124,73 +124,73 @@ public final class CipherSuite implements Constructed
"TLS_RSA_WITH_3DES_EDE_CBC_SHA");
public static final CipherSuite TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.DSA,
+ KeyExchangeAlgorithm.DH_DSS,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 5, 0x00, 0x0B,
"TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
public static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.DSA,
+ KeyExchangeAlgorithm.DH_DSS,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 8, 0x00, 0x0C,
"TLS_DH_DSS_WITH_DES_CBC_SHA");
public static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA =
new CipherSuite (CipherAlgorithm.DESede,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.DSA,
+ KeyExchangeAlgorithm.DH_DSS,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 24, 0x00, 0x0D,
"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA");
public static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.RSA,
+ KeyExchangeAlgorithm.DH_RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 5, 0x00, 0x0E,
"TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
public static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.RSA,
+ KeyExchangeAlgorithm.DH_RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 8, 0x00, 0x0F,
"TLS_DH_RSA_WITH_DES_CBC_SHA");
public static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA =
new CipherSuite (CipherAlgorithm.DESede,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.RSA,
+ KeyExchangeAlgorithm.DH_RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 24, 0x00, 0x10,
"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA");
public static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_DSS, true,
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 5, 0x00, 0x11,
"TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
public static final CipherSuite TLS_DHE_DSS_WITH_DES_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_DSS, true,
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 8, 0x00, 0x12,
"TLS_DHE_DSS_WITH_DES_CBC_SHA");
public static final CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA =
new CipherSuite (CipherAlgorithm.DESede,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_DSS, true,
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 24, 0x00, 0x13,
"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
public static final CipherSuite TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_RSA, true,
SignatureAlgorithm.RSA,
MacAlgorithm.SHA, 5, 0x00, 0x14,
"TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
public static final CipherSuite TLS_DHE_RSA_WITH_DES_CBC_SHA =
new CipherSuite (CipherAlgorithm.DES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_RSA, true,
SignatureAlgorithm.RSA,
MacAlgorithm.SHA, 8, 0x00, 0x15,
"TLS_DHE_RSA_WITH_DES_CBC_SHA");
public static final CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA =
new CipherSuite (CipherAlgorithm.DESede,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_RSA, true,
SignatureAlgorithm.RSA,
MacAlgorithm.SHA, 24, 0x00, 0x16,
"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
@@ -204,55 +204,55 @@ public final class CipherSuite implements Constructed
"TLS_RSA_WITH_AES_128_CBC_SHA");
public static final CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.DSA,
+ KeyExchangeAlgorithm.DH_DSS,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 16, 0x00, 0x30,
"TLS_DH_DSS_WITH_AES_128_CBC_SHA");
public static final CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.RSA,
+ KeyExchangeAlgorithm.DH_RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 16, 0x00, 0x31,
"TLS_DH_RSA_WITH_AES_128_CBC_SHA");
public static final CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_DSS, true,
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 16, 0x00, 0x32,
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
public static final CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_RSA, true,
SignatureAlgorithm.RSA,
MacAlgorithm.SHA, 16, 0x00, 0x33,
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
public static final CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
KeyExchangeAlgorithm.RSA,
- SignatureAlgorithm.RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 32, 0x00, 0x35,
"TLS_RSA_WITH_AES_256_CBC_SHA");
public static final CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.DSA,
+ KeyExchangeAlgorithm.DH_DSS,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 32, 0x00, 0x36,
"TLS_DH_DSS_WITH_AES_256_CBC_SHA");
public static final CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN,
- SignatureAlgorithm.RSA,
+ KeyExchangeAlgorithm.DH_RSA,
+ SignatureAlgorithm.ANONYMOUS,
MacAlgorithm.SHA, 32, 0x00, 0x37,
"TLS_DH_RSA_WITH_AES_256_CBC_SHA");
public static final CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_DSS, true,
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 32, 0x00, 0x38,
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
public static final CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA =
new CipherSuite (CipherAlgorithm.AES,
- KeyExchangeAlgorithm.DIFFIE_HELLMAN, true,
+ KeyExchangeAlgorithm.DHE_RSA, true,
SignatureAlgorithm.RSA,
MacAlgorithm.SHA, 32, 0x00, 0x39,
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
@@ -312,6 +312,82 @@ public final class CipherSuite implements Constructed
SignatureAlgorithm.DSA,
MacAlgorithm.SHA, 32, 0x00, 0x58,
"TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA");
+
+ // Pre-shared key suites.
+ public static final CipherSuite TLS_PSK_WITH_RC4_128_SHA =
+ new CipherSuite(CipherAlgorithm.RC4,
+ KeyExchangeAlgorithm.PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x8A,
+ "TLS_PSK_WITH_RC4_128_SHA");
+ public static final CipherSuite TLS_PSK_WITH_3DES_EDE_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.DESede,
+ KeyExchangeAlgorithm.PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 24, 0x00, 0x8B,
+ "TLS_PSK_WITH_3DES_EDE_CBC_SHA");
+ public static final CipherSuite TLS_PSK_WITH_AES_128_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x8C,
+ "TLS_PSK_WITH_AES_128_CBC_SHA");
+ public static final CipherSuite TLS_PSK_WITH_AES_256_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 32, 0x00, 0x8D,
+ "TLS_PSK_WITH_AES_256_CBC_SHA");
+
+ public static final CipherSuite TLS_DHE_PSK_WITH_RC4_128_SHA =
+ new CipherSuite(CipherAlgorithm.RC4,
+ KeyExchangeAlgorithm.DHE_PSK, true,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x8E,
+ "TLS_DHE_PSK_WITH_RC4_128_SHA");
+ public static final CipherSuite TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.DESede,
+ KeyExchangeAlgorithm.DHE_PSK, true,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 24, 0x00, 0x8F,
+ "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA");
+ public static final CipherSuite TLS_DHE_PSK_WITH_AES_128_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.DHE_PSK, true,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x90,
+ "TLS_DHE_PSK_WITH_AES_128_CBC_SHA");
+ public static final CipherSuite TLS_DHE_PSK_WITH_AES_256_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.DHE_PSK, true,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 32, 0x00, 0x91,
+ "TLS_DHE_PSK_WITH_AES_256_CBC_SHA");
+
+ public static final CipherSuite TLS_RSA_PSK_WITH_RC4_128_SHA =
+ new CipherSuite(CipherAlgorithm.RC4,
+ KeyExchangeAlgorithm.RSA_PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x92,
+ "TLS_RSA_PSK_WITH_RC4_128_SHA");
+ public static final CipherSuite TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.DESede,
+ KeyExchangeAlgorithm.RSA_PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 24, 0x00, 0x93,
+ "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA");
+ public static final CipherSuite TLS_RSA_PSK_WITH_AES_128_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.RSA_PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 16, 0x00, 0x94,
+ "TLS_RSA_PSK_WITH_AES_128_CBC_SHA");
+ public static final CipherSuite TLS_RSA_PSK_WITH_AES_256_CBC_SHA =
+ new CipherSuite(CipherAlgorithm.AES,
+ KeyExchangeAlgorithm.RSA_PSK,
+ SignatureAlgorithm.ANONYMOUS,
+ MacAlgorithm.SHA, 32, 0x00, 0x95,
+ "TLS_RSA_PSK_WITH_AES_256_CBC_SHA");
// Ciphersuites from the OpenPGP extension draft.
// These disappeared from a more recent draft.
diff --git a/gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java b/gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java
new file mode 100644
index 000000000..a40f77ba2
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ClientDHE_PSKParameters.java
@@ -0,0 +1,122 @@
+/* ClientDHE_PSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * <pre>
+ struct {
+ select (KeyExchangeAlgorithm) {
+ /* other cases for rsa, diffie_hellman, etc. &#42;/
+ case diffie_hellman_psk: /* NEW &#42;/
+ opaque psk_identity<0..2^16-1>;
+ ClientDiffieHellmanPublic public;
+ } exchange_keys;
+ } ClientKeyExchange;</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ClientDHE_PSKParameters extends ExchangeKeys implements Builder, Constructed
+{
+ public ClientDHE_PSKParameters(ByteBuffer buffer)
+ {
+ super(buffer);
+ }
+
+ public ClientDHE_PSKParameters(String identity, ClientDiffieHellmanPublic dh)
+ {
+ super(null);
+ Charset utf8 = Charset.forName("UTF-8");
+ ByteBuffer idBuf = utf8.encode(identity);
+ buffer = ByteBuffer.allocate(2 + idBuf.remaining() + dh.length());
+ buffer.putShort((short) idBuf.remaining());
+ buffer.put(idBuf);
+ buffer.put(dh.buffer());
+ buffer.rewind();
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Builder#buffer()
+ */
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().rewind().limit(length());
+ }
+
+ private int identityLength()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2;
+ }
+
+ public String identity()
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ return utf8.decode((ByteBuffer) buffer.duplicate().position(2).limit
+ (identityLength())).toString();
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#length()
+ */
+ public int length()
+ {
+ int length = (buffer.getShort(0) & 0xFFFF) + 2;
+ // XXX always explicit?
+ length += (buffer.getShort(length) & 0xFFFF) + 2;
+ return length;
+ }
+
+ public ClientDiffieHellmanPublic params()
+ {
+ return new ClientDiffieHellmanPublic((ByteBuffer) buffer.duplicate()
+ .position(identityLength()).limit(length()));
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#toString(java.lang.String)
+ */
+ public String toString(String prefix)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/gnu/javax/net/ssl/provider/ClientHandshake.java b/gnu/javax/net/ssl/provider/ClientHandshake.java
index 2b0ebf407..494e66dc7 100644
--- a/gnu/javax/net/ssl/provider/ClientHandshake.java
+++ b/gnu/javax/net/ssl/provider/ClientHandshake.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package gnu.javax.net.ssl.provider;
import static gnu.javax.net.ssl.provider.ClientHandshake.State.*;
+import static gnu.javax.net.ssl.provider.KeyExchangeAlgorithm.*;
import gnu.classpath.debug.Component;
import gnu.java.security.action.GetSecurityPropertyAction;
@@ -48,6 +49,8 @@ import gnu.javax.net.ssl.Session;
import gnu.javax.net.ssl.provider.Alert.Description;
import gnu.javax.net.ssl.provider.Alert.Level;
import gnu.javax.net.ssl.provider.CertificateRequest.ClientCertificateType;
+import gnu.javax.net.ssl.provider.ServerNameList.NameType;
+import gnu.javax.net.ssl.provider.ServerNameList.ServerName;
import java.nio.ByteBuffer;
import java.security.AccessController;
@@ -61,7 +64,9 @@ import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -125,6 +130,9 @@ public class ClientHandshake extends AbstractHandshake
private KeyPair dhPair;
private String keyAlias;
private PrivateKey privateKey;
+ private MaxFragmentLength maxFragmentLengthSent;
+ private boolean truncatedHMacSent;
+ private ProtocolVersion sentVersion;
// Delegated tasks.
private CertVerifier certVerifier;
@@ -190,7 +198,31 @@ public class ClientHandshake extends AbstractHandshake
((AbstractSessionContext) engine.contextImpl
.engineGetClientSessionContext()).put(engine.session());
}
-
+ ExtensionList extensions = hello.extensions();
+ if (extensions != null)
+ {
+ for (Extension extension : extensions)
+ {
+ Extension.Type type = extension.type();
+ if (type == null)
+ continue;
+ switch (type)
+ {
+ case MAX_FRAGMENT_LENGTH:
+ MaxFragmentLength mfl
+ = (MaxFragmentLength) extension.value();
+ if (maxFragmentLengthSent == mfl)
+ engine.session().setApplicationBufferSize(mfl.maxLength());
+ break;
+
+ case TRUNCATED_HMAC:
+ if (truncatedHMacSent)
+ engine.session().setTruncatedMac(true);
+ break;
+ }
+ }
+ }
+
if (continuedSession)
{
byte[][] keys = generateKeys(clientRandom, serverRandom,
@@ -253,16 +285,16 @@ public class ClientHandshake extends AbstractHandshake
case READ_SERVER_KEY_EXCHANGE:
{
CipherSuite s = engine.session().suite;
+ KeyExchangeAlgorithm kexalg = s.keyExchangeAlgorithm();
// XXX also SRP.
- if (!s.isEphemeralDH() &&
- !(s.keyExchangeAlgorithm() == KeyExchangeAlgorithm.DIFFIE_HELLMAN
- && s.signatureAlgorithm() == SignatureAlgorithm.ANONYMOUS))
+ if (kexalg != DHE_DSS && kexalg != DHE_RSA && kexalg != DH_anon
+ && kexalg != DHE_PSK && kexalg != PSK && kexalg != RSA_PSK)
throw new AlertException(new Alert(Level.FATAL,
Description.UNEXPECTED_MESSAGE));
ServerKeyExchange skex = (ServerKeyExchange) handshake.body();
ByteBuffer paramsBuffer = null;
- if (s.keyExchangeAlgorithm() == KeyExchangeAlgorithm.DIFFIE_HELLMAN)
+ if (kexalg == DHE_DSS || kexalg == DHE_RSA || kexalg == DH_anon)
{
ServerDHParams dhParams = (ServerDHParams) skex.params();
ByteBuffer b = dhParams.buffer();
@@ -277,7 +309,7 @@ public class ClientHandshake extends AbstractHandshake
tasks.add(paramsVerifier);
}
- if (s.keyExchangeAlgorithm() == KeyExchangeAlgorithm.DIFFIE_HELLMAN)
+ if (kexalg == DHE_DSS || kexalg == DHE_RSA || kexalg == DH_anon)
{
ServerDHParams dhParams = (ServerDHParams) skex.params();
DHPublicKey serverKey = new GnuDHPublicKey(null,
@@ -455,7 +487,8 @@ outer_loop:
sid = continued.id();
hello.setSessionId(sid.id());
- hello.setVersion(chooseVersion());
+ sentVersion = chooseVersion();
+ hello.setVersion(sentVersion);
hello.setCipherSuites(getSuites());
hello.setCompressionMethods(getCompressionMethods());
Random r = hello.random();
@@ -464,8 +497,44 @@ outer_loop:
engine.session().random().nextBytes(nonce);
r.setRandomBytes(nonce);
clientRandom = r.copy();
- // XXX extensions?
+ if (enableExtensions())
+ {
+ List<Extension> extensions = new LinkedList<Extension>();
+ MaxFragmentLength fraglen = maxFragmentLength();
+ if (fraglen != null)
+ {
+ extensions.add(new Extension(Extension.Type.MAX_FRAGMENT_LENGTH,
+ fraglen));
+ maxFragmentLengthSent = fraglen;
+ }
+
+ String host = engine.getPeerHost();
+ if (host != null)
+ {
+ ServerName name
+ = new ServerName(NameType.HOST_NAME, host);
+ ServerNameList names
+ = new ServerNameList(Collections.singletonList(name));
+ extensions.add(new Extension(Extension.Type.SERVER_NAME,
+ names));
+ }
+
+ if (truncatedHMac())
+ {
+ extensions.add(new Extension(Extension.Type.TRUNCATED_HMAC,
+ new TruncatedHMAC()));
+ truncatedHMacSent = true;
+ }
+
+ ExtensionList elist = new ExtensionList(extensions);
+ hello.setExtensions(elist.buffer());
+ }
+ else
+ hello.setDisableExtensions(true);
+ if (Debug.DEBUG)
+ logger.logv(Component.SSL_HANDSHAKE, "{0}", hello);
+
fragment.putInt((Handshake.Type.CLIENT_HELLO.getValue() << 24)
| (hello.length() & 0xFFFFFF));
outBuffer = hello.buffer();
@@ -517,7 +586,8 @@ outer_loop:
ClientKeyExchangeBuilder ckex
= new ClientKeyExchangeBuilder(engine.session().suite,
engine.session().version);
- if (kea == KeyExchangeAlgorithm.DIFFIE_HELLMAN)
+ if (kea == DHE_DSS || kea == DHE_RSA || kea == DH_anon
+ || kea == DH_DSS || kea == DH_RSA)
{
assert(dhPair != null);
DHPublicKey pubkey = (DHPublicKey) dhPair.getPublic();
@@ -525,7 +595,7 @@ outer_loop:
= new ClientDiffieHellmanPublic(pubkey.getY());
ckex.setExchangeKeys(pub.buffer());
}
- if (kea == KeyExchangeAlgorithm.RSA)
+ if (kea == RSA || kea == RSA_PSK)
{
assert(keyExchange instanceof RSAGen);
assert(keyExchange.hasRun());
@@ -536,7 +606,44 @@ outer_loop:
EncryptedPreMasterSecret epms
= new EncryptedPreMasterSecret(((RSAGen) keyExchange).encryptedSecret(),
engine.session().version);
- ckex.setExchangeKeys(epms.buffer());
+ if (kea == RSA)
+ ckex.setExchangeKeys(epms.buffer());
+ else
+ {
+ String identity = getPSKIdentity();
+ if (identity == null)
+ throw new SSLException("no pre-shared-key identity;"
+ + " set the security property"
+ + " \"jessie.client.psk.identity\"");
+ ClientRSA_PSKParameters params =
+ new ClientRSA_PSKParameters(identity, epms,
+ engine.session().version);
+ ckex.setExchangeKeys(params.buffer());
+ }
+ }
+ if (kea == DHE_PSK)
+ {
+ assert(dhPair != null);
+ String identity = getPSKIdentity();
+ if (identity == null)
+ throw new SSLException("no pre-shared key identity; set"
+ + " the security property"
+ + " \"jessie.client.psk.identity\"");
+ DHPublicKey pubkey = (DHPublicKey) dhPair.getPublic();
+ ClientDHE_PSKParameters params =
+ new ClientDHE_PSKParameters(identity,
+ new ClientDiffieHellmanPublic(pubkey.getY()));
+ ckex.setExchangeKeys(params.buffer());
+ }
+ if (kea == PSK)
+ {
+ String identity = getPSKIdentity();
+ if (identity == null)
+ throw new SSLException("no pre-shared key identity; set"
+ + " the security property"
+ + " \"jessie.client.psk.identity\"");
+ ClientPSKParameters params = new ClientPSKParameters(identity);
+ ckex.setExchangeKeys(params.buffer());
}
if (Debug.DEBUG)
@@ -697,6 +804,56 @@ outer_loop:
return methods;
}
+ private boolean enableExtensions()
+ {
+ GetSecurityPropertyAction action
+ = new GetSecurityPropertyAction("jessie.client.enable.extensions");
+ return Boolean.valueOf(AccessController.doPrivileged(action));
+ }
+
+ private MaxFragmentLength maxFragmentLength()
+ {
+ GetSecurityPropertyAction action
+ = new GetSecurityPropertyAction("jessie.client.maxFragmentLength");
+ String s = AccessController.doPrivileged(action);
+ if (s != null)
+ {
+ try
+ {
+ int len = Integer.parseInt(s);
+ switch (len)
+ {
+ case 9:
+ case (1 << 9): return MaxFragmentLength.LEN_2_9;
+ case 10:
+ case (1 << 10): return MaxFragmentLength.LEN_2_10;
+ case 11:
+ case (1 << 11): return MaxFragmentLength.LEN_2_11;
+ case 12:
+ case (1 << 12): return MaxFragmentLength.LEN_2_12;
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ }
+ }
+ return null;
+ }
+
+ private boolean truncatedHMac()
+ {
+ GetSecurityPropertyAction action
+ = new GetSecurityPropertyAction("jessie.client.truncatedHMac");
+ return Boolean.valueOf(AccessController.doPrivileged(action));
+ }
+
+ private String getPSKIdentity()
+ {
+ GetSecurityPropertyAction action
+ = new GetSecurityPropertyAction("jessie.client.psk.identity");
+ return AccessController.doPrivileged(action);
+ }
+
// Delegated tasks.
class ParamsVerifier extends DelegatedTask
@@ -832,10 +989,12 @@ outer_loop:
}
preMasterSecret = new byte[48];
engine.session().random().nextBytes(preMasterSecret);
- preMasterSecret[0] = (byte) engine.session().version.major();
- preMasterSecret[1] = (byte) engine.session().version.minor();
+ preMasterSecret[0] = (byte) sentVersion.major();
+ preMasterSecret[1] = (byte) sentVersion.minor();
Cipher rsa = Cipher.getInstance("RSA");
- rsa.init(Cipher.ENCRYPT_MODE, engine.session().getPeerCertificates()[0]);
+ java.security.cert.Certificate cert
+ = engine.session().getPeerCertificates()[0];
+ rsa.init(Cipher.ENCRYPT_MODE, cert);
encryptedPreMasterSecret = rsa.doFinal(preMasterSecret);
// Generate our session keys, because we can.
diff --git a/gnu/javax/net/ssl/provider/ClientHello.java b/gnu/javax/net/ssl/provider/ClientHello.java
index 9592bb8ff..cf1635db6 100644
--- a/gnu/javax/net/ssl/provider/ClientHello.java
+++ b/gnu/javax/net/ssl/provider/ClientHello.java
@@ -38,25 +38,12 @@ exception statement from your version. */
package gnu.javax.net.ssl.provider;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
import java.io.PrintWriter;
-import java.io.StringReader;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.net.ssl.SSLProtocolException;
-
/**
* A ClientHello handshake message.
*
@@ -87,6 +74,7 @@ public class ClientHello implements Handshake.Body
protected static final int SESSID_OFFSET2 = SESSID_OFFSET + 1;
protected ByteBuffer buffer;
+ protected boolean disableExtensions;
// Constructor.
// -------------------------------------------------------------------------
@@ -94,18 +82,19 @@ public class ClientHello implements Handshake.Body
public ClientHello (final ByteBuffer buffer)
{
this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ disableExtensions = false;
}
// Instance methods.
// -------------------------------------------------------------------------
- public int length ()
+ public int length()
{
int len = SESSID_OFFSET2 + buffer.get(SESSID_OFFSET);
len += (buffer.getShort(len) & 0xFFFF) + 2;
len += (buffer.get(len) & 0xFF) + 1;
- if (hasExtensions())
- len += (buffer.get(len) & 0xFFFF) + 2;
+ if (!disableExtensions && len + 1 < buffer.capacity())
+ len += (buffer.getShort(len) & 0xFFFF) + 2;
return len;
}
@@ -164,22 +153,20 @@ public class ClientHello implements Handshake.Body
public boolean hasExtensions()
{
int offset = getExtensionsOffset();
- if (offset + 1 > buffer.limit())
- return false;
- return (buffer.getShort(offset) & 0xFFFF) == 0;
+ return (offset + 1 > buffer.capacity());
}
public ExtensionList extensions()
{
int offset = getExtensionsOffset ();
- if (offset >= buffer.limit())
+ if (offset + 1 >= buffer.limit())
return null;
int len = buffer.getShort(offset) & 0xFFFF;
if (len == 0)
len = buffer.limit() - offset - 2;
- ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate ().position (offset)
- .limit (offset + len + 2)).slice ();
- return new ExtensionList (ebuf);
+ ByteBuffer ebuf = ((ByteBuffer) buffer.duplicate().position(offset)
+ .limit(offset + len + 2)).slice ();
+ return new ExtensionList(ebuf);
}
public int extensionsLength()
diff --git a/gnu/javax/net/ssl/provider/ClientHelloBuilder.java b/gnu/javax/net/ssl/provider/ClientHelloBuilder.java
index e82ef48b1..81e3dd72f 100644
--- a/gnu/javax/net/ssl/provider/ClientHelloBuilder.java
+++ b/gnu/javax/net/ssl/provider/ClientHelloBuilder.java
@@ -115,9 +115,14 @@ public class ClientHelloBuilder extends ClientHello implements Builder
public void setExtensions(ByteBuffer extensions)
{
- extensions = (ByteBuffer)
- extensions.duplicate().limit(extensions.position() + extensionsLength());
- ((ByteBuffer) buffer.duplicate().position(getExtensionsOffset() + 2)).put(extensions);
+ int elen = extensions.getShort(0) & 0xFFFF;
+ setExtensionsLength(elen);
+ ((ByteBuffer) buffer.duplicate().position(getExtensionsOffset())).put(extensions);
+ }
+
+ public void setDisableExtensions(boolean disableExtensions)
+ {
+ this.disableExtensions = disableExtensions;
}
public void ensureCapacity(final int length)
diff --git a/gnu/javax/net/ssl/provider/ClientKeyExchange.java b/gnu/javax/net/ssl/provider/ClientKeyExchange.java
index 439725856..cc05ff736 100644
--- a/gnu/javax/net/ssl/provider/ClientKeyExchange.java
+++ b/gnu/javax/net/ssl/provider/ClientKeyExchange.java
@@ -86,8 +86,16 @@ public class ClientKeyExchange implements Handshake.Body
KeyExchangeAlgorithm alg = suite.keyExchangeAlgorithm();
if (alg == KeyExchangeAlgorithm.RSA)
return new EncryptedPreMasterSecret(buffer, version);
- else if (alg == KeyExchangeAlgorithm.DIFFIE_HELLMAN)
- return new ClientDiffieHellmanPublic(buffer);
+ else if (alg == KeyExchangeAlgorithm.DH_anon
+ || alg == KeyExchangeAlgorithm.DHE_DSS
+ || alg == KeyExchangeAlgorithm.DHE_RSA)
+ return new ClientDiffieHellmanPublic(buffer.duplicate());
+ else if (alg == KeyExchangeAlgorithm.DHE_PSK)
+ return new ClientDHE_PSKParameters(buffer.duplicate());
+ else if (alg == KeyExchangeAlgorithm.PSK)
+ return new ClientPSKParameters(buffer.duplicate());
+ else if (alg == KeyExchangeAlgorithm.RSA_PSK)
+ return new ClientRSA_PSKParameters(buffer.duplicate(), version);
throw new IllegalArgumentException("unsupported key exchange");
}
diff --git a/gnu/javax/net/ssl/provider/ClientPSKParameters.java b/gnu/javax/net/ssl/provider/ClientPSKParameters.java
new file mode 100644
index 000000000..4f8a3fad9
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ClientPSKParameters.java
@@ -0,0 +1,122 @@
+/* ClientPSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * <pre>
+ struct {
+ select (KeyExchangeAlgorithm) {
+ /* other cases for rsa, diffie_hellman, etc. &#42;/
+ case psk: /* NEW &#42;/
+ opaque psk_identity&lt;0..2^16-1&gt;;
+ } exchange_keys;
+ } ClientKeyExchange;</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ClientPSKParameters extends ExchangeKeys implements Builder, Constructed
+{
+ public ClientPSKParameters(ByteBuffer buffer)
+ {
+ super(buffer);
+ }
+
+ public ClientPSKParameters(String identity)
+ {
+ super(null);
+ Charset utf8 = Charset.forName("UTF-8");
+ ByteBuffer idBuf = utf8.encode(CharBuffer.wrap(identity));
+ buffer = ByteBuffer.allocate(idBuf.remaining() + 2);
+ buffer.putShort((short) idBuf.remaining());
+ buffer.put(idBuf);
+ buffer.rewind();
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Builder#buffer()
+ */
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().rewind().limit(length());
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#length()
+ */
+ public int length()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2;
+ }
+
+ public String identity()
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ return utf8.decode((ByteBuffer) buffer.duplicate().position(2).limit(length())).toString();
+ }
+
+ public @Override String toString()
+ {
+ return toString(null);
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#toString(java.lang.String)
+ */
+ public String toString(String prefix)
+ {
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("struct {");
+ if (prefix != null) out.print(prefix);
+ out.print(" identity = ");
+ out.print(identity());
+ out.println(";");
+ if (prefix != null) out.print(prefix);
+ out.print("} ClientPSKParameters;");
+ return str.toString();
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java b/gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java
new file mode 100644
index 000000000..3023ff9a2
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ClientRSA_PSKParameters.java
@@ -0,0 +1,128 @@
+/* ClientRSA_PSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ClientRSA_PSKParameters extends ExchangeKeys implements Builder, Constructed
+{
+ private final ProtocolVersion version;
+
+ public ClientRSA_PSKParameters(ByteBuffer buffer, ProtocolVersion version)
+ {
+ super(buffer);
+ this.version = version;
+ }
+
+ public ClientRSA_PSKParameters(String identity, EncryptedPreMasterSecret epms,
+ ProtocolVersion version)
+ {
+ super(null);
+ Charset utf8 = Charset.forName("UTF-8");
+ ByteBuffer idBuf = utf8.encode(identity);
+ buffer = ByteBuffer.allocate(2 + idBuf.remaining() + epms.length());
+ buffer.putShort((short) idBuf.remaining());
+ buffer.put(idBuf);
+ buffer.put(epms.buffer());
+ buffer.rewind();
+ this.version = version;
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Builder#buffer()
+ */
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().rewind().limit(length());
+ }
+
+ public String identity()
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ return utf8.decode((ByteBuffer) buffer.duplicate().position(2).limit
+ (identityLength())).toString();
+ }
+
+ private int identityLength()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2;
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#length()
+ */
+ public int length()
+ {
+ return identityLength() + secret().length();
+ }
+
+ public EncryptedPreMasterSecret secret()
+ {
+ return new EncryptedPreMasterSecret
+ ((ByteBuffer) buffer.duplicate().position(identityLength())
+ .limit(buffer.capacity()), version);
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#toString(java.lang.String)
+ */
+ public String toString(String prefix)
+ {
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("struct {");
+ if (prefix != null) out.print(prefix);
+ out.print(" identity = ");
+ out.print(identity());
+ if (prefix != null) out.print(prefix);
+ out.println(" encrypted_pre_master_secret =");
+ out.println(secret().toString(prefix != null ? prefix + " " : " "));
+ if (prefix != null) out.print(prefix);
+ out.print("} ClientRSA_PSKParameters;");
+ return str.toString();
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java b/gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java
index edfc6f566..85769cffc 100644
--- a/gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java
+++ b/gnu/javax/net/ssl/provider/EncryptedPreMasterSecret.java
@@ -133,16 +133,16 @@ public final class EncryptedPreMasterSecret extends ExchangeKeys implements Buil
public String toString (final String prefix)
{
- StringWriter str = new StringWriter ();
- PrintWriter out = new PrintWriter (str);
- if (prefix != null) out.print (prefix);
- out.println ("struct {");
- if (prefix != null) out.print (prefix);
- out.print (" pre_master_secret = ");
- out.print (Util.toHexString (encryptedSecret (), ':'));
- out.println (';');
- if (prefix != null) out.print (prefix);
- out.print ("} EncryptedPreMasterSecret;");
- return str.toString ();
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("struct {");
+ if (prefix != null) out.print(prefix);
+ out.println(" pre_master_secret = ");
+ out.print(Util.hexDump(encryptedSecret(), prefix != null ? prefix + " "
+ : " "));
+ if (prefix != null) out.print(prefix);
+ out.print("} EncryptedPreMasterSecret;");
+ return str.toString();
}
} \ No newline at end of file
diff --git a/gnu/javax/net/ssl/provider/Extension.java b/gnu/javax/net/ssl/provider/Extension.java
index 5442daa02..c79e58832 100644
--- a/gnu/javax/net/ssl/provider/Extension.java
+++ b/gnu/javax/net/ssl/provider/Extension.java
@@ -55,28 +55,44 @@ import java.nio.ByteOrder;
*
* @author csm@gnu.org
*/
-public final class Extension implements Constructed
+public final class Extension implements Builder, Constructed
{
// Fields.
// -------------------------------------------------------------------------
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
// Constructor.
// -------------------------------------------------------------------------
- Extension(final ByteBuffer buffer)
+ public Extension(final ByteBuffer buffer)
{
this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
}
+
+ public Extension(final Type type, final Value value)
+ {
+ ByteBuffer valueBuffer = value.buffer();
+ int length = 2 + 2 + valueBuffer.remaining();
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) type.getValue());
+ buffer.putShort((short) valueBuffer.remaining());
+ buffer.put(valueBuffer);
+ buffer.rewind();
+ }
// Instance methods.
// -------------------------------------------------------------------------
public int length ()
{
- return (buffer.getShort (2) & 0xFFFF) + 2;
+ return (buffer.getShort (2) & 0xFFFF) + 4;
+ }
+
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
}
public Type type()
@@ -224,7 +240,7 @@ public final class Extension implements Constructed
}
}
- public static abstract class Value implements Constructed
+ public static abstract class Value implements Builder, Constructed
{
}
}
diff --git a/gnu/javax/net/ssl/provider/ExtensionList.java b/gnu/javax/net/ssl/provider/ExtensionList.java
index 07c689ae8..d5aaad621 100644
--- a/gnu/javax/net/ssl/provider/ExtensionList.java
+++ b/gnu/javax/net/ssl/provider/ExtensionList.java
@@ -6,6 +6,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
+import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
@@ -17,7 +18,7 @@ import java.util.NoSuchElementException;
*
* @author csm
*/
-public class ExtensionList implements Iterable<Extension>
+public class ExtensionList implements Builder, Iterable<Extension>
{
private final ByteBuffer buffer;
private int modCount;
@@ -27,6 +28,23 @@ public class ExtensionList implements Iterable<Extension>
this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
modCount = 0;
}
+
+ public ExtensionList(List<Extension> extensions)
+ {
+ int length = 2;
+ for (Extension extension : extensions)
+ length += extension.length();
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) (length - 2));
+ for (Extension extension : extensions)
+ buffer.put(extension.buffer());
+ buffer.rewind();
+ }
+
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
public Extension get (final int index)
{
@@ -42,7 +60,8 @@ public class ExtensionList implements Iterable<Extension>
if (n < index)
throw new IndexOutOfBoundsException ("no elemenet at " + index);
int el = buffer.getShort (i+2) & 0xFFFF;
- return new Extension (((ByteBuffer) buffer.duplicate().position(i).limit(i+el+4)).slice());
+ ByteBuffer b = (ByteBuffer) buffer.duplicate().position(i).limit(i+el+4);
+ return new Extension(b.slice());
}
/**
@@ -72,7 +91,7 @@ public class ExtensionList implements Iterable<Extension>
*/
public int length ()
{
- return buffer.getShort (0) & 0xFFFF;
+ return (buffer.getShort (0) & 0xFFFF) + 2;
}
/**
@@ -165,31 +184,31 @@ public class ExtensionList implements Iterable<Extension>
public Iterator<Extension> iterator()
{
- return new ExtensionsIterator ();
+ return new ExtensionsIterator();
}
- public String toString ()
+ public String toString()
{
return toString (null);
}
- public String toString (final String prefix)
+ public String toString(final String prefix)
{
- StringWriter str = new StringWriter ();
- PrintWriter out = new PrintWriter (str);
- if (prefix != null) out.print (prefix);
- out.println ("ExtensionList {");
- if (prefix != null) out.print (prefix);
- out.print (" length = ");
- out.print (length ());
- out.println (";");
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("ExtensionList {");
+ if (prefix != null) out.print(prefix);
+ out.print(" length = ");
+ out.print(length());
+ out.println(";");
String subprefix = " ";
if (prefix != null)
subprefix = prefix + subprefix;
for (Extension e : this)
- out.println (e.toString(subprefix));
- if (prefix != null) out.print (prefix);
- out.println ("};");
+ out.println(e.toString(subprefix));
+ if (prefix != null) out.print(prefix);
+ out.print("};");
return str.toString();
}
diff --git a/gnu/javax/net/ssl/provider/InputSecurityParameters.java b/gnu/javax/net/ssl/provider/InputSecurityParameters.java
index e1f56f052..72390b59c 100644
--- a/gnu/javax/net/ssl/provider/InputSecurityParameters.java
+++ b/gnu/javax/net/ssl/provider/InputSecurityParameters.java
@@ -152,9 +152,11 @@ public class InputSecurityParameters
fragmentLength -= maclen;
int padlen = 0;
+ int padRemoveLen = 0;
if (!suite.isStreamCipher ())
{
padlen = fragment.get(record.length() - 1) & 0xFF;
+ padRemoveLen = padlen + 1;
if (Debug.DEBUG)
logger.logv(Component.SSL_RECORD_LAYER, "padlen:{0}", padlen);
@@ -183,7 +185,7 @@ public class InputSecurityParameters
logger.logv(Component.SSL_RECORD_LAYER, "padding bad? {0}",
badPadding);
if (!badPadding)
- fragmentLength = fragmentLength - padlen - 1;
+ fragmentLength = fragmentLength - padRemoveLen;
}
int ivlen = 0;
@@ -234,7 +236,7 @@ public class InputSecurityParameters
int produced = 0;
if (inflater != null)
{
- ByteBufferOutputStream out = new ByteBufferOutputStream(record.length());
+ ByteBufferOutputStream out = new ByteBufferOutputStream(fragmentLength);
byte[] inbuffer = new byte[1024];
byte[] outbuffer = new byte[1024];
boolean done = false;
@@ -243,6 +245,7 @@ public class InputSecurityParameters
fragment.position (cipher.getBlockSize());
else
fragment.position(0);
+ fragment.limit(fragmentLength);
while (!done)
{
@@ -290,7 +293,7 @@ public class InputSecurityParameters
else
{
ByteBuffer outbuf = (ByteBuffer)
- fragment.duplicate().position(0).limit(record.length() - maclen - padlen - 1);
+ fragment.duplicate().position(0).limit(record.length() - maclen - padRemoveLen);
if (record.version().compareTo(ProtocolVersion.TLS_1_1) >= 0
&& !suite.isStreamCipher())
outbuf.position(cipher.getBlockSize());
diff --git a/gnu/javax/net/ssl/provider/Jessie.java b/gnu/javax/net/ssl/provider/Jessie.java
index 66f2576b3..6bd68b385 100644
--- a/gnu/javax/net/ssl/provider/Jessie.java
+++ b/gnu/javax/net/ssl/provider/Jessie.java
@@ -85,6 +85,7 @@ public class Jessie extends Provider
put("KeyManagerFactory.JessieX509", X509KeyManagerFactory.class.getName());
put("TrustManagerFactory.JessieX509", X509TrustManagerFactory.class.getName());
+ put("KeyManagerFactory.JessiePSK", PreSharedKeyManagerFactoryImpl.class.getName());
//put("TrustManagerFactory.SRP", SRPTrustManagerFactory.class.getName());
put("Mac.SSLv3HMac-MD5", SSLv3HMacMD5Impl.class.getName());
diff --git a/gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java b/gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java
index 555df6e95..a71d3de18 100644
--- a/gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java
+++ b/gnu/javax/net/ssl/provider/KeyExchangeAlgorithm.java
@@ -45,6 +45,13 @@ public enum KeyExchangeAlgorithm
{
NONE,
RSA,
- DIFFIE_HELLMAN,
- SRP;
+ DH_DSS,
+ DH_RSA,
+ DH_anon,
+ DHE_DSS,
+ DHE_RSA,
+ SRP,
+ PSK,
+ DHE_PSK,
+ RSA_PSK;
}
diff --git a/gnu/javax/net/ssl/provider/MaxFragmentLength.java b/gnu/javax/net/ssl/provider/MaxFragmentLength.java
index c680b0774..eb63958b8 100644
--- a/gnu/javax/net/ssl/provider/MaxFragmentLength.java
+++ b/gnu/javax/net/ssl/provider/MaxFragmentLength.java
@@ -2,6 +2,8 @@ package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
+import java.nio.ByteBuffer;
+
/**
* Extension value
* @author csm
@@ -22,12 +24,17 @@ public class MaxFragmentLength extends Value
this.length = length;
}
+ public ByteBuffer buffer()
+ {
+ return ByteBuffer.allocate(1).put(0, (byte) value);
+ }
+
public int length()
{
return 1;
}
- public int getValue ()
+ public int getValue()
{
return value;
}
diff --git a/gnu/javax/net/ssl/provider/OutputSecurityParameters.java b/gnu/javax/net/ssl/provider/OutputSecurityParameters.java
index f940ec727..728c9bad9 100644
--- a/gnu/javax/net/ssl/provider/OutputSecurityParameters.java
+++ b/gnu/javax/net/ssl/provider/OutputSecurityParameters.java
@@ -266,15 +266,6 @@ public class OutputSecurityParameters
cipher.update(ByteBuffer.wrap(macValue), outfragment);
if (pad != null)
cipher.update(ByteBuffer.wrap(pad), outfragment);
- try
- {
- cipher.doFinal(ByteBuffer.wrap(new byte[0]), outfragment);
- }
- catch (BadPaddingException bpe)
- {
- // Should never happen; we are encrypting.
- throw new Error("bad padding while encrypting", bpe);
- }
}
else
{
@@ -291,7 +282,7 @@ public class OutputSecurityParameters
if (macValue != null)
outfragment.put(macValue);
}
-
+
// Advance the output buffer's position.
output.position(output.position() + outrecord.length() + 5);
sequence++;
diff --git a/gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java b/gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java
new file mode 100644
index 000000000..aa1f97853
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/PreSharedKeyManagerFactoryImpl.java
@@ -0,0 +1,118 @@
+/* PreSharedKeyManagerFactory.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import gnu.javax.net.ssl.PreSharedKeyManager;
+import gnu.javax.net.ssl.PreSharedKeyManagerParameters;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.util.Iterator;
+
+import javax.crypto.SecretKey;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactorySpi;
+import javax.net.ssl.ManagerFactoryParameters;
+
+/**
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class PreSharedKeyManagerFactoryImpl
+ extends KeyManagerFactorySpi
+{
+ PreSharedKeyManagerParameters params;
+
+ /* (non-Javadoc)
+ * @see javax.net.ssl.KeyManagerFactorySpi#engineGetKeyManagers()
+ */
+ @Override protected KeyManager[] engineGetKeyManagers()
+ {
+ if (params == null)
+ throw new IllegalStateException("not initialized");
+ return new KeyManager[] { new Manager() };
+ }
+
+ /* (non-Javadoc)
+ * @see javax.net.ssl.KeyManagerFactorySpi#engineInit(javax.net.ssl.ManagerFactoryParameters)
+ */
+ @Override protected void engineInit(ManagerFactoryParameters params)
+ throws InvalidAlgorithmParameterException
+ {
+ if (!(params instanceof PreSharedKeyManagerParameters))
+ throw new InvalidAlgorithmParameterException("only supports gnu.javax.net.ssl.PreSharedKeyManagerParameters");
+ params = (PreSharedKeyManagerParameters) params;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.net.ssl.KeyManagerFactorySpi#engineInit(java.security.KeyStore, char[])
+ */
+ @Override protected void engineInit(KeyStore store, char[] passwd)
+ throws KeyStoreException, NoSuchAlgorithmException,
+ UnrecoverableKeyException
+ {
+ // XXX Could implement this.
+ }
+
+ class Manager implements PreSharedKeyManager
+ {
+ Manager()
+ {
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.PreSharedKeyManager#getKey(java.lang.String)
+ */
+ public SecretKey getKey(String name) throws KeyManagementException
+ {
+ return params.getKey(name);
+ }
+
+ public String chooseIdentityHint()
+ {
+ Iterator<String> it = params.identities();
+ if (it.hasNext())
+ return it.next();
+ return null;
+ }
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/SSLContextImpl.java b/gnu/javax/net/ssl/provider/SSLContextImpl.java
index e1a8ea252..0c00ccb2a 100644
--- a/gnu/javax/net/ssl/provider/SSLContextImpl.java
+++ b/gnu/javax/net/ssl/provider/SSLContextImpl.java
@@ -41,6 +41,7 @@ package gnu.javax.net.ssl.provider;
import gnu.java.security.action.GetSecurityPropertyAction;
import gnu.javax.net.ssl.AbstractSessionContext;
import gnu.javax.net.ssl.NullManagerParameters;
+import gnu.javax.net.ssl.PreSharedKeyManager;
import gnu.javax.net.ssl.SRPTrustManager;
import java.security.AccessController;
@@ -75,6 +76,7 @@ public final class SSLContextImpl extends SSLContextSpi
AbstractSessionContext serverContext;
AbstractSessionContext clientContext;
+ PreSharedKeyManager pskManager;
X509ExtendedKeyManager keyManager;
X509TrustManager trustManager;
SRPTrustManager srpTrustManager;
@@ -169,17 +171,16 @@ public final class SSLContextImpl extends SSLContextSpi
{
for (int i = 0; i < keyManagers.length; i++)
{
- if (keyManagers[i] instanceof X509ExtendedKeyManager)
- {
- keyManager = (X509ExtendedKeyManager) keyManagers[i];
- break;
- }
+ if ((keyManagers[i] instanceof X509ExtendedKeyManager)
+ && keyManager == null)
+ keyManager = (X509ExtendedKeyManager) keyManagers[i];
+ if (keyManagers[i] instanceof PreSharedKeyManagerFactoryImpl
+ && pskManager == null)
+ pskManager = (PreSharedKeyManager) keyManagers[i];
}
}
if (keyManager == null)
- {
- keyManager = defaultKeyManager();
- }
+ keyManager = defaultKeyManager();
if (trustManagers != null)
{
for (int i = 0; i < trustManagers.length; i++)
@@ -187,16 +188,12 @@ public final class SSLContextImpl extends SSLContextSpi
if (trustManagers[i] instanceof X509TrustManager)
{
if (trustManager == null)
- {
- trustManager = (X509TrustManager) trustManagers[i];
- }
+ trustManager = (X509TrustManager) trustManagers[i];
}
else if (trustManagers[i] instanceof SRPTrustManager)
{
if (srpTrustManager == null)
- {
- srpTrustManager = (SRPTrustManager) trustManagers[i];
- }
+ srpTrustManager = (SRPTrustManager) trustManagers[i];
}
}
}
diff --git a/gnu/javax/net/ssl/provider/SSLEngineImpl.java b/gnu/javax/net/ssl/provider/SSLEngineImpl.java
index c8c55979a..e198c3f0e 100644
--- a/gnu/javax/net/ssl/provider/SSLEngineImpl.java
+++ b/gnu/javax/net/ssl/provider/SSLEngineImpl.java
@@ -566,38 +566,44 @@ public final class SSLEngineImpl extends SSLEngine
insec = params;
result = new SSLEngineResult (SSLEngineResult.Status.OK,
handshakeStatus,
- record.length() + 5, 0); // XXXX
+ record.length() + 5, 0);
}
}
else if (type == ContentType.ALERT)
{
int len = 0;
- if (alertBuffer.position () > 0)
+ if (alertBuffer.position() > 0)
{
- alertBuffer.put (msg.get ());
+ alertBuffer.put(msg.get());
len = 1;
}
- len += msg.remaining () / 2;
+ if (Debug.DEBUG)
+ logger.logv(Component.SSL_RECORD_LAYER, "processing alerts {0}",
+ Util.wrapBuffer(msg));
+ len += msg.remaining() / 2;
Alert[] alerts = new Alert[len];
int i = 0;
- if (alertBuffer.position () > 0)
+ if (alertBuffer.position() > 0)
{
- alertBuffer.flip ();
- alerts[0] = new Alert (alertBuffer);
+ alertBuffer.flip();
+ alerts[0] = new Alert(alertBuffer);
i++;
}
while (i < alerts.length)
{
- alerts[i++] = new Alert (msg.duplicate ());
- msg.position (msg.position () + 2);
+ alerts[i++] = new Alert(msg.duplicate());
+ msg.position(msg.position() + 2);
}
+ if (Debug.DEBUG)
+ logger.logv(Component.SSL_RECORD_LAYER, "alerts: {0}", alerts.length);
for (i = 0; i < alerts.length; i++)
{
- if (alerts[i].level () == Alert.Level.FATAL)
- throw new AlertException (alerts[i]);
- logger.log (java.util.logging.Level.WARNING,
- "received alert: {0}", alerts[i]);
+ if (alerts[i].level() == Alert.Level.FATAL)
+ throw new AlertException(alerts[i], false);
+ if (alerts[i].description() != Alert.Description.CLOSE_NOTIFY)
+ logger.log(java.util.logging.Level.WARNING,
+ "received alert: {0}", alerts[i]);
if (alerts[i].description() == Alert.Description.CLOSE_NOTIFY)
inClosed = true;
}
diff --git a/gnu/javax/net/ssl/provider/SSLSocketImpl.java b/gnu/javax/net/ssl/provider/SSLSocketImpl.java
index 284094314..0181b66d8 100644
--- a/gnu/javax/net/ssl/provider/SSLSocketImpl.java
+++ b/gnu/javax/net/ssl/provider/SSLSocketImpl.java
@@ -87,7 +87,11 @@ public class SSLSocketImpl extends SSLSocket
{
if (!initialHandshakeDone
|| engine.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING)
- doHandshake();
+ {
+ doHandshake();
+ if (handshakeException != null)
+ throw handshakeException;
+ }
int k = 0;
while (k < len)
@@ -104,6 +108,7 @@ public class SSLSocketImpl extends SSLSocket
buffer.flip();
out.write(buffer.array(), 0, buffer.limit());
k += result.bytesConsumed();
+ buffer.clear();
}
}
}
@@ -141,7 +146,11 @@ public class SSLSocketImpl extends SSLSocket
{
if (!initialHandshakeDone ||
engine.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING)
- doHandshake();
+ {
+ doHandshake();
+ if (handshakeException != null)
+ throw handshakeException;
+ }
if (!appBuffer.hasRemaining())
{
@@ -415,115 +424,125 @@ public class SSLSocketImpl extends SSLSocket
else
sockOut = super.getOutputStream();
- while (status != HandshakeStatus.NOT_HANDSHAKING
- && status != HandshakeStatus.FINISHED)
+ try
{
- logger.logv(Component.SSL_HANDSHAKE, "socket processing state {0}",
- status);
-
- if (inBuffer.capacity() != getSession().getPacketBufferSize())
+ while (status != HandshakeStatus.NOT_HANDSHAKING
+ && status != HandshakeStatus.FINISHED)
{
- ByteBuffer b
+ logger.logv(Component.SSL_HANDSHAKE, "socket processing state {0}",
+ status);
+
+ if (inBuffer.capacity() != getSession().getPacketBufferSize())
+ {
+ ByteBuffer b
+ = ByteBuffer.wrap(new byte[getSession().getPacketBufferSize()]);
+ if (inBuffer.hasRemaining())
+ b.put(inBuffer).flip();
+ inBuffer = b;
+ }
+ if (outBuffer.capacity() != getSession().getPacketBufferSize())
+ outBuffer
= ByteBuffer.wrap(new byte[getSession().getPacketBufferSize()]);
- if (inBuffer.hasRemaining())
- b.put(inBuffer).flip();
- inBuffer = b;
- }
- if (outBuffer.capacity() != getSession().getPacketBufferSize())
- outBuffer
- = ByteBuffer.wrap(new byte[getSession().getPacketBufferSize()]);
- switch (status)
- {
- case NEED_UNWRAP:
- // Read in a single SSL record.
- inBuffer.clear();
- int i = sockIn.read();
- if (i == -1)
- throw new EOFException();
- if ((i & 0x80) == 0x80) // SSLv2 client hello.
+ switch (status)
+ {
+ case NEED_UNWRAP:
+ // Read in a single SSL record.
+ inBuffer.clear();
+ int i = sockIn.read();
+ if (i == -1)
+ throw new EOFException();
+ if ((i & 0x80) == 0x80) // SSLv2 client hello.
+ {
+ inBuffer.put((byte) i);
+ int v2len = (i & 0x7f) << 8;
+ i = sockIn.read();
+ v2len = v2len | (i & 0xff);
+ inBuffer.put((byte) i);
+ sockIn.readFully(inBuffer.array(), 2, v2len);
+ inBuffer.position(0).limit(v2len + 2);
+ }
+ else
+ {
+ inBuffer.put((byte) i);
+ inBuffer.putInt(sockIn.readInt());
+ int reclen = inBuffer.getShort(3) & 0xFFFF;
+ sockIn.readFully(inBuffer.array(), 5, reclen);
+ inBuffer.position(0).limit(reclen + 5);
+ }
+ result = engine.unwrap(inBuffer, emptyBuffer);
+ status = result.getHandshakeStatus();
+ if (result.getStatus() != Status.OK)
+ throw new SSLException("unexpected SSL status "
+ + result.getStatus());
+ break;
+
+ case NEED_WRAP:
{
- inBuffer.put((byte) i);
- int v2len = (i & 0x7f) << 8;
- i = sockIn.read();
- v2len = v2len | (i & 0xff);
- inBuffer.put((byte) i);
- sockIn.readFully(inBuffer.array(), 2, v2len);
- inBuffer.position(0).limit(v2len + 2);
+ outBuffer.clear();
+ result = engine.wrap(emptyBuffer, outBuffer);
+ status = result.getHandshakeStatus();
+ if (result.getStatus() != Status.OK)
+ throw new SSLException("unexpected SSL status "
+ + result.getStatus());
+ outBuffer.flip();
+ sockOut.write(outBuffer.array(), outBuffer.position(),
+ outBuffer.limit());
}
- else
+ break;
+
+ case NEED_TASK:
{
- inBuffer.put((byte) i);
- inBuffer.putInt(sockIn.readInt());
- int reclen = inBuffer.getShort(3) & 0xFFFF;
- sockIn.readFully(inBuffer.array(), 5, reclen);
- inBuffer.position(0).limit(reclen + 5);
+ Runnable task;
+ while ((task = engine.getDelegatedTask()) != null)
+ task.run();
+ status = engine.getHandshakeStatus();
}
- result = engine.unwrap(inBuffer, emptyBuffer);
- status = result.getHandshakeStatus();
- if (result.getStatus() != Status.OK)
- throw new SSLException("unexpected SSL status "
- + result.getStatus());
- break;
-
- case NEED_WRAP:
+ break;
+
+ case FINISHED:
+ break;
+ }
+ }
+
+ initialHandshakeDone = true;
+
+ HandshakeCompletedEvent hce = new HandshakeCompletedEvent(this, getSession());
+ for (HandshakeCompletedListener l : listeners)
+ {
+ try
+ {
+ l.handshakeCompleted(hce);
+ }
+ catch (ThreadDeath td)
{
- outBuffer.clear();
- result = engine.wrap(emptyBuffer, outBuffer);
- status = result.getHandshakeStatus();
- if (result.getStatus() != Status.OK)
- throw new SSLException("unexpected SSL status "
- + result.getStatus());
- outBuffer.flip();
- sockOut.write(outBuffer.array(), outBuffer.position(),
- outBuffer.limit());
+ throw td;
}
- break;
-
- case NEED_TASK:
+ catch (Throwable x)
{
- Runnable task;
- while ((task = engine.getDelegatedTask()) != null)
- task.run();
- status = engine.getHandshakeStatus();
+ logger.log(Component.WARNING,
+ "HandshakeCompletedListener threw exception", x);
}
- break;
-
- case FINISHED:
- break;
}
- }
-
- initialHandshakeDone = true;
- HandshakeCompletedEvent hce = new HandshakeCompletedEvent(this, getSession());
- for (HandshakeCompletedListener l : listeners)
+ now += System.currentTimeMillis();
+ if (Debug.DEBUG)
+ logger.logv(Component.SSL_HANDSHAKE,
+ "handshake completed in {0}ms in thread {1}", now,
+ Thread.currentThread().getName());
+ }
+ catch (SSLException ssle)
{
- try
- {
- l.handshakeCompleted(hce);
- }
- catch (ThreadDeath td)
- {
- throw td;
- }
- catch (Throwable x)
- {
- logger.log(Component.WARNING,
- "HandshakeCompletedListener threw exception", x);
- }
+ handshakeException = ssle;
+ throw ssle;
}
-
- now += System.currentTimeMillis();
- if (Debug.DEBUG)
- logger.logv(Component.SSL_HANDSHAKE,
- "handshake completed in {0}ms in thread {1}", now,
- Thread.currentThread().getName());
-
- synchronized (engine)
+ finally
{
- isHandshaking = false;
- engine.notifyAll();
+ synchronized (engine)
+ {
+ isHandshaking = false;
+ engine.notifyAll();
+ }
}
}
diff --git a/gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java b/gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java
new file mode 100644
index 000000000..2cc42929c
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ServerDHE_PSKParameters.java
@@ -0,0 +1,148 @@
+/* ServerDHE_PSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * <pre>
+ struct {
+ select (KeyExchangeAlgorithm) {
+ /* other cases for rsa, diffie_hellman, etc. &#42;/
+ case diffie_hellman_psk: /* NEW &#42;/
+ opaque psk_identity_hint&lt;0..2^16-1&gt;;
+ ServerDHParams params;
+ };
+ } ServerKeyExchange;</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ServerDHE_PSKParameters implements Constructed, Builder, ServerKeyExchangeParams
+{
+ private ByteBuffer buffer;
+
+ public ServerDHE_PSKParameters(ByteBuffer buffer)
+ {
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public ServerDHE_PSKParameters(String identityHint, ServerDHParams dhParams)
+ {
+ this(identityHint, dhParams.buffer());
+ }
+
+ public ServerDHE_PSKParameters(String identityHint, ByteBuffer dhParams)
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ ByteBuffer hintBuf = utf8.encode(identityHint);
+ buffer = ByteBuffer.allocate(2 + hintBuf.remaining() + dhParams.remaining());
+ buffer.putShort((short) hintBuf.remaining());
+ buffer.put(hintBuf);
+ buffer.put(buffer);
+ }
+
+ public KeyExchangeAlgorithm algorithm()
+ {
+ return KeyExchangeAlgorithm.DHE_PSK;
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#length()
+ */
+ public int length()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2 + params().length();
+ }
+
+ private int hintLength()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2;
+ }
+
+ public String identityHint()
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ return utf8.decode((ByteBuffer) buffer.duplicate().position(2).limit
+ (hintLength())).toString();
+ }
+
+ public ServerDHParams params()
+ {
+ return new ServerDHParams((ByteBuffer) buffer.duplicate().position
+ (hintLength()).limit(buffer.capacity()));
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Builder#buffer()
+ */
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().rewind().limit(length());
+ }
+
+ public @Override String toString()
+ {
+ return toString(null);
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#toString(java.lang.String)
+ */
+ public String toString(String prefix)
+ {
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("struct {");
+ if (prefix != null) out.print(prefix);
+ out.print(" identity_hint = ");
+ out.print(identityHint());
+ out.println(";");
+ if (prefix != null) out.print(prefix);
+ out.println(" params =");
+ out.println(params().toString(prefix != null ? prefix + " " : " "));
+ if (prefix != null) out.print(prefix);
+ out.print("} ServerDHE_PSKParameters;");
+ return str.toString();
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/ServerDHParams.java b/gnu/javax/net/ssl/provider/ServerDHParams.java
index c3e06a389..38abe93bb 100644
--- a/gnu/javax/net/ssl/provider/ServerDHParams.java
+++ b/gnu/javax/net/ssl/provider/ServerDHParams.java
@@ -103,9 +103,9 @@ public class ServerDHParams implements Builder, ServerKeyExchangeParams
buffer.put(y_bytes, y_off, y_len);
}
- public KeyExchangeAlgorithm algorithm ()
+ @Deprecated public KeyExchangeAlgorithm algorithm ()
{
- return KeyExchangeAlgorithm.DIFFIE_HELLMAN;
+ return null; // XXX can't support this.
}
public int length ()
diff --git a/gnu/javax/net/ssl/provider/ServerHandshake.java b/gnu/javax/net/ssl/provider/ServerHandshake.java
index d339c1cc5..0d77bda04 100644
--- a/gnu/javax/net/ssl/provider/ServerHandshake.java
+++ b/gnu/javax/net/ssl/provider/ServerHandshake.java
@@ -38,8 +38,9 @@ exception statement from your version. */
package gnu.javax.net.ssl.provider;
-import static gnu.javax.net.ssl.provider.ServerHandshake.State.*;
import static gnu.javax.net.ssl.provider.Handshake.Type.*;
+import static gnu.javax.net.ssl.provider.KeyExchangeAlgorithm.*;
+import static gnu.javax.net.ssl.provider.ServerHandshake.State.*;
import gnu.classpath.debug.Component;
import gnu.java.security.action.GetSecurityPropertyAction;
@@ -54,6 +55,7 @@ import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
+import java.security.KeyManagementException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
@@ -73,9 +75,11 @@ import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
@@ -192,22 +196,44 @@ class ServerHandshake extends AbstractHandshake
throws SSLException
{
// Figure out which SignatureAlgorithms we can support.
- HashSet<SignatureAlgorithm> sigs = new HashSet<SignatureAlgorithm>(2);
+ HashSet<KeyExchangeAlgorithm> kexes = new HashSet<KeyExchangeAlgorithm>(8);
+
X509ExtendedKeyManager km = engine.contextImpl.keyManager;
- if (km.getServerAliases(SignatureAlgorithm.DSA.name(), null).length != 0)
- sigs.add(SignatureAlgorithm.DSA);
- if (km.getServerAliases(SignatureAlgorithm.RSA.name(), null).length != 0)
- sigs.add(SignatureAlgorithm.RSA);
+ if (km != null)
+ {
+ if (km.getServerAliases(DH_DSS.name(), null).length > 0)
+ kexes.add(DH_DSS);
+ if (km.getServerAliases(DH_RSA.name(), null).length > 0)
+ kexes.add(DH_RSA);
+ if (km.getServerAliases(DHE_DSS.name(), null).length > 0)
+ kexes.add(DHE_DSS);
+ if (km.getServerAliases(DHE_RSA.name(), null).length > 0)
+ kexes.add(DHE_RSA);
+ if (km.getServerAliases(RSA.name(), null).length > 0)
+ kexes.add(RSA);
+ if (km.getServerAliases(RSA_PSK.name(), null).length > 0
+ && engine.contextImpl.pskManager != null)
+ kexes.add(RSA_PSK);
+ }
+ if (engine.contextImpl.pskManager != null)
+ {
+ kexes.add(DHE_PSK);
+ kexes.add(PSK);
+ }
if (Debug.DEBUG)
- logger.logv(Component.SSL_HANDSHAKE, "we have certs for signature algorithms {0}", sigs);
+ logger.logv(Component.SSL_HANDSHAKE,
+ "we have certs for key exchange algorithms {0}", kexes);
- HashSet<CipherSuite> suites = new HashSet<CipherSuite>(enabledSuites.length);
+ HashSet<CipherSuite> suites = new HashSet<CipherSuite>();
for (String s : enabledSuites)
{
CipherSuite suite = CipherSuite.forName(s);
- if (suite != null && sigs.contains(suite.signatureAlgorithm()))
- suites.add (suite);
+ if (suite == null)
+ continue;
+ if (!kexes.contains(suite.keyExchangeAlgorithm()))
+ continue;
+ suites.add (suite);
}
for (CipherSuite suite : clientSuites)
{
@@ -438,27 +464,130 @@ class ServerHandshake extends AbstractHandshake
throw new SSLException("expecting client key exchange");
ClientKeyExchange kex = (ClientKeyExchange) handshake.body();
- if (engine.session().suite.keyExchangeAlgorithm() ==
- KeyExchangeAlgorithm.DIFFIE_HELLMAN)
+ KeyExchangeAlgorithm alg = engine.session().suite.keyExchangeAlgorithm();
+ switch (alg)
{
- ClientDiffieHellmanPublic pub = (ClientDiffieHellmanPublic)
- kex.exchangeKeys();
- DHPublicKey myKey = (DHPublicKey) dhPair.getPublic();
- DHPublicKey clientKey =
- new GnuDHPublicKey(null, myKey.getParams().getP(),
- myKey.getParams().getG(),
- pub.publicValue());
- keyExchangeTask = new DHPhase(clientKey);
- tasks.add(keyExchangeTask);
- }
+ case DHE_DSS:
+ case DHE_RSA:
+ case DH_anon:
+ {
+ ClientDiffieHellmanPublic pub = (ClientDiffieHellmanPublic)
+ kex.exchangeKeys();
+ DHPublicKey myKey = (DHPublicKey) dhPair.getPublic();
+ DHPublicKey clientKey =
+ new GnuDHPublicKey(null, myKey.getParams().getP(),
+ myKey.getParams().getG(),
+ pub.publicValue());
+ keyExchangeTask = new DHPhase(clientKey);
+ tasks.add(keyExchangeTask);
+ }
+ break;
- if (engine.session().suite.keyExchangeAlgorithm() ==
- KeyExchangeAlgorithm.RSA)
- {
- EncryptedPreMasterSecret secret = (EncryptedPreMasterSecret)
- kex.exchangeKeys();
- keyExchangeTask = new RSAKeyExchange(secret.encryptedSecret());
- tasks.add(keyExchangeTask);
+ case RSA:
+ {
+ EncryptedPreMasterSecret secret = (EncryptedPreMasterSecret)
+ kex.exchangeKeys();
+ keyExchangeTask = new RSAKeyExchange(secret.encryptedSecret());
+ tasks.add(keyExchangeTask);
+ }
+ break;
+
+ case PSK:
+ {
+ ClientPSKParameters params = (ClientPSKParameters)
+ kex.exchangeKeys();
+ SecretKey key = null;
+ try
+ {
+ key = engine.contextImpl.pskManager.getKey(params.identity());
+ }
+ catch (KeyManagementException kme)
+ {
+ // Ignore; we hide the fact that a PSK identity was
+ // not found.
+ }
+ if (key != null)
+ {
+ byte[] keyb = key.getEncoded();
+ preMasterSecret = new byte[(2 * keyb.length) + 4];
+ preMasterSecret[0] = (byte) (keyb.length >>> 8);
+ preMasterSecret[1] = (byte) keyb.length;
+ preMasterSecret[keyb.length + 2]
+ = (byte) (keyb.length >>> 8);
+ preMasterSecret[keyb.length + 3]
+ = (byte) keyb.length;
+ System.arraycopy(keyb, 0, preMasterSecret,
+ keyb.length + 4, keyb.length);
+ }
+ else
+ {
+ // Generate a random, fake secret.
+ preMasterSecret = new byte[8];
+ preMasterSecret[1] = 2;
+ preMasterSecret[5] = 2;
+ preMasterSecret[6] = (byte) engine.session().random().nextInt();
+ preMasterSecret[7] = (byte) engine.session().random().nextInt();
+ }
+
+ generateMasterSecret(clientRandom, serverRandom,
+ engine.session());
+ byte[][] keys = generateKeys(clientRandom, serverRandom,
+ engine.session());
+ setupSecurityParameters(keys, false, engine, compression);
+ }
+ break;
+
+ case DHE_PSK:
+ {
+ ClientDHE_PSKParameters params = (ClientDHE_PSKParameters)
+ kex.exchangeKeys();
+ DHPublicKey serverKey = (DHPublicKey) dhPair.getPublic();
+ DHPublicKey clientKey =
+ new GnuDHPublicKey(null, serverKey.getParams().getP(),
+ serverKey.getParams().getG(),
+ params.params().publicValue());
+ SecretKey psk = null;
+ try
+ {
+ psk = engine.contextImpl.pskManager.getKey(params.identity());
+ }
+ catch (KeyManagementException kme)
+ {
+ }
+ if (psk == null)
+ {
+ byte[] fakeKey = new byte[16];
+ engine.session().random().nextBytes(fakeKey);
+ psk = new SecretKeySpec(fakeKey, "DHE_PSK");
+ }
+ keyExchangeTask = new DHE_PSKGen(clientKey, psk, false);
+ tasks.add(keyExchangeTask);
+ }
+ break;
+
+ case RSA_PSK:
+ {
+ ClientRSA_PSKParameters params = (ClientRSA_PSKParameters)
+ kex.exchangeKeys();
+ SecretKey psk = null;
+ try
+ {
+ psk = engine.contextImpl.pskManager.getKey(params.identity());
+ }
+ catch (KeyManagementException kme)
+ {
+ }
+ if (psk == null)
+ {
+ byte[] fakeKey = new byte[16];
+ engine.session().random().nextBytes(fakeKey);
+ psk = new SecretKeySpec(fakeKey, "DHE_PSK");
+ }
+ keyExchangeTask =
+ new RSA_PSKExchange(params.secret().encryptedSecret(), psk);
+ tasks.add(keyExchangeTask);
+ }
+ break;
}
// XXX SRP
@@ -733,7 +862,7 @@ output_loop:
fragment.put((ByteBuffer) outBuffer.duplicate().limit(outBuffer.position() + l));
outBuffer.position(outBuffer.position() + l);
-
+ CipherSuite cs = engine.session().suite;
if (continuedSession)
{
byte[][] keys = generateKeys(clientRandom, serverRandom,
@@ -742,15 +871,27 @@ output_loop:
engine.changeCipherSpec();
state = WRITE_FINISHED;
}
- else if (engine.session().suite.signatureAlgorithm()
- != SignatureAlgorithm.ANONYMOUS)
+ else if (cs.signatureAlgorithm() != SignatureAlgorithm.ANONYMOUS
+ || cs.keyExchangeAlgorithm() == RSA_PSK)
{
certLoader = new CertLoader();
tasks.add(certLoader);
state = WRITE_CERTIFICATE;
+ if (cs.keyExchangeAlgorithm() == DHE_DSS
+ || cs.keyExchangeAlgorithm() == DHE_RSA)
+ {
+ genDH = new GenDH();
+ tasks.add(genDH);
+ state = WRITE_SERVER_KEY_EXCHANGE;
+ }
break output_loop;
}
- else if (engine.session().suite.isEphemeralDH())
+ else if (engine.session().suite.keyExchangeAlgorithm() == PSK)
+ {
+ state = WRITE_SERVER_KEY_EXCHANGE;
+ }
+ else if (cs.keyExchangeAlgorithm() == DHE_PSK
+ || cs.keyExchangeAlgorithm() == DH_anon)
{
genDH = new GenDH();
tasks.add(genDH);
@@ -808,9 +949,8 @@ output_loop:
outBuffer.position(outBuffer.position() + l);
CipherSuite s = engine.session().suite;
- if (s.isEphemeralDH()
- || (s.keyExchangeAlgorithm() == KeyExchangeAlgorithm.DIFFIE_HELLMAN
- && s.signatureAlgorithm() == SignatureAlgorithm.ANONYMOUS))
+ KeyExchangeAlgorithm kexalg = s.keyExchangeAlgorithm();
+ if (kexalg == DHE_DSS || kexalg == DHE_RSA)
{
genDH = new GenDH();
tasks.add(genDH);
@@ -839,7 +979,8 @@ output_loop:
ByteBuffer paramBuffer = null;
ByteBuffer sigBuffer = null;
- if (kex == KeyExchangeAlgorithm.DIFFIE_HELLMAN)
+ if (kex == DHE_DSS || kex == DHE_RSA || kex == DH_anon
+ || kex == DHE_PSK)
{
assert(genDH != null);
assert(genDH.hasRun());
@@ -852,6 +993,15 @@ output_loop:
engine.session().random());
paramBuffer = genDH.paramsBuffer;
sigBuffer = genDH.sigBuffer;
+
+ if (kex == DHE_PSK)
+ {
+ String identityHint
+ = engine.contextImpl.pskManager.chooseIdentityHint();
+ ServerDHE_PSKParameters psk =
+ new ServerDHE_PSKParameters(identityHint, paramBuffer);
+ paramBuffer = psk.buffer();
+ }
}
// XXX handle SRP
@@ -1102,54 +1252,16 @@ output_loop:
public void implRun() throws SSLException
{
- String sigAlg = null;
- switch (engine.session().suite.keyExchangeAlgorithm())
- {
- case NONE:
- break;
-
- case RSA:
- sigAlg = "RSA";
- break;
-
- case DIFFIE_HELLMAN:
- if (engine.session().suite.isEphemeralDH())
- sigAlg = "DHE_";
- else
- sigAlg = "DH_";
- switch (engine.session().suite.signatureAlgorithm())
- {
- case RSA:
- sigAlg += "RSA";
- break;
-
- case DSA:
- sigAlg += "DSS";
- break;
- }
-
- case SRP:
- switch (engine.session().suite.signatureAlgorithm())
- {
- case RSA:
- sigAlg = "SRP_RSA";
- break;
-
- case DSA:
- sigAlg = "SRP_DSS";
- break;
- }
- }
+ KeyExchangeAlgorithm kexalg = engine.session().suite.keyExchangeAlgorithm();
X509ExtendedKeyManager km = engine.contextImpl.keyManager;
Principal[] issuers = null; // XXX use TrustedAuthorities extension.
- keyAlias = km.chooseEngineServerAlias(sigAlg, issuers, engine);
+ keyAlias = km.chooseEngineServerAlias(kexalg.name(), issuers, engine);
if (keyAlias == null)
throw new SSLException("no certificates available");
X509Certificate[] chain = km.getCertificateChain(keyAlias);
engine.session().setLocalCertificates(chain);
localCert = chain[0];
- if (engine.session().suite.keyExchangeAlgorithm() == KeyExchangeAlgorithm.DIFFIE_HELLMAN
- && !engine.session().suite.isEphemeralDH())
+ if (kexalg == DH_DSS || kexalg == DH_RSA)
dhPair = new KeyPair(localCert.getPublicKey(),
km.getPrivateKey(keyAlias));
}
@@ -1213,4 +1325,38 @@ output_loop:
setupSecurityParameters(keys, false, engine, compression);
}
}
+
+ class RSA_PSKExchange extends DelegatedTask
+ {
+ private final byte[] encryptedPreMasterSecret;
+ private final SecretKey psKey;
+
+ RSA_PSKExchange(byte[] encryptedPreMasterSecret, SecretKey psKey)
+ {
+ this.encryptedPreMasterSecret = encryptedPreMasterSecret;
+ this.psKey = psKey;
+ }
+
+ public @Override void implRun()
+ throws BadPaddingException, IllegalBlockSizeException, InvalidKeyException,
+ NoSuchAlgorithmException, NoSuchPaddingException, SSLException
+ {
+ Cipher rsa = Cipher.getInstance("RSA");
+ rsa.init(Cipher.DECRYPT_MODE, localCert);
+ byte[] rsaSecret = rsa.doFinal(encryptedPreMasterSecret);
+ byte[] psSecret = psKey.getEncoded();
+ preMasterSecret = new byte[rsaSecret.length + psSecret.length + 4];
+ preMasterSecret[0] = (byte) (rsaSecret.length >>> 8);
+ preMasterSecret[1] = (byte) rsaSecret.length;
+ System.arraycopy(rsaSecret, 0, preMasterSecret, 2, rsaSecret.length);
+ preMasterSecret[rsaSecret.length + 2] = (byte) (psSecret.length >>> 8);
+ preMasterSecret[rsaSecret.length + 3] = (byte) psSecret.length;
+ System.arraycopy(psSecret, 0, preMasterSecret, rsaSecret.length+4,
+ psSecret.length);
+
+ generateMasterSecret(clientRandom, serverRandom, engine.session());
+ byte[][] keys = generateKeys(clientRandom, serverRandom, engine.session());
+ setupSecurityParameters(keys, false, engine, compression);
+ }
+ }
} \ No newline at end of file
diff --git a/gnu/javax/net/ssl/provider/ServerKeyExchange.java b/gnu/javax/net/ssl/provider/ServerKeyExchange.java
index d698156d2..6c5a72000 100644
--- a/gnu/javax/net/ssl/provider/ServerKeyExchange.java
+++ b/gnu/javax/net/ssl/provider/ServerKeyExchange.java
@@ -94,14 +94,22 @@ public class ServerKeyExchange implements Handshake.Body
public ServerKeyExchangeParams params ()
{
KeyExchangeAlgorithm kex = suite.keyExchangeAlgorithm ();
- if (kex.equals (KeyExchangeAlgorithm.RSA))
- return new ServerRSAParams (buffer.duplicate ());
- else if (kex.equals (KeyExchangeAlgorithm.DIFFIE_HELLMAN))
- return new ServerDHParams (buffer.duplicate ());
+ if (kex == KeyExchangeAlgorithm.RSA)
+ return new ServerRSAParams(buffer.duplicate ());
+ else if (kex == KeyExchangeAlgorithm.DHE_DSS
+ || kex == KeyExchangeAlgorithm.DHE_RSA
+ || kex == KeyExchangeAlgorithm.DH_anon)
+ return new ServerDHParams(buffer.duplicate());
// else if (kex.equals (KeyExchangeAlgorithm.SRP))
// return new ServerSRPParams (buffer.duplicate ());
- else if (kex.equals (KeyExchangeAlgorithm.NONE))
+ else if (kex == KeyExchangeAlgorithm.NONE)
return null;
+ else if (kex == KeyExchangeAlgorithm.DHE_PSK)
+ return new ServerDHE_PSKParameters(buffer.duplicate());
+ else if (kex == KeyExchangeAlgorithm.PSK)
+ return new ServerPSKParameters(buffer.duplicate());
+ else if (kex == KeyExchangeAlgorithm.RSA_PSK)
+ return new ServerPSKParameters(buffer.duplicate());
throw new IllegalArgumentException ("unsupported key exchange: " + kex);
}
@@ -112,10 +120,15 @@ public class ServerKeyExchange implements Handshake.Body
*/
public Signature signature ()
{
- if (suite.keyExchangeAlgorithm ().equals (KeyExchangeAlgorithm.NONE))
+ KeyExchangeAlgorithm kex = suite.keyExchangeAlgorithm();
+ if (kex == KeyExchangeAlgorithm.NONE
+ || kex == KeyExchangeAlgorithm.DH_anon
+ || kex == KeyExchangeAlgorithm.DHE_PSK
+ || kex == KeyExchangeAlgorithm.PSK
+ || kex == KeyExchangeAlgorithm.RSA_PSK)
return null;
- ServerKeyExchangeParams params = params ();
- ByteBuffer sigbuf = ((ByteBuffer) buffer.position (params.length ())).slice ();
+ ServerKeyExchangeParams params = params();
+ ByteBuffer sigbuf = ((ByteBuffer) buffer.position(params.length ())).slice ();
return new Signature (sigbuf, suite.signatureAlgorithm ());
}
diff --git a/gnu/javax/net/ssl/provider/ServerNameList.java b/gnu/javax/net/ssl/provider/ServerNameList.java
index f119be637..5a268f542 100644
--- a/gnu/javax/net/ssl/provider/ServerNameList.java
+++ b/gnu/javax/net/ssl/provider/ServerNameList.java
@@ -1,3 +1,41 @@
+/* ServerNameList.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
@@ -7,7 +45,11 @@ import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.util.List;
import java.util.NoSuchElementException;
/**
@@ -39,18 +81,35 @@ struct {
*/
public class ServerNameList extends Value implements Iterable<ServerNameList.ServerName>
{
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
public ServerNameList (final ByteBuffer buffer)
{
this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
}
+
+ public ServerNameList(List<ServerName> names)
+ {
+ int length = 2;
+ for (ServerName name : names)
+ length += name.length();
+ buffer = ByteBuffer.allocate(length);
+ buffer.putShort((short) (length - 2));
+ for (ServerName name : names)
+ buffer.put(name.buffer());
+ buffer.rewind();
+ }
public int length()
{
return (buffer.getShort(0) & 0xFFFF) + 2;
}
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
public int size()
{
int n = 0;
@@ -153,16 +212,42 @@ public class ServerNameList extends Value implements Iterable<ServerNameList.Ser
public static class ServerName implements Constructed
{
- private final ByteBuffer buffer;
+ private ByteBuffer buffer;
public ServerName(final ByteBuffer buffer)
{
this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
}
+ public ServerName(NameType type, String name)
+ {
+ CharsetEncoder utf8 = Charset.forName("UTF-8").newEncoder();
+ ByteBuffer nameBuf = null;
+ try
+ {
+ nameBuf = utf8.encode(CharBuffer.wrap(name));
+ }
+ catch (CharacterCodingException cce)
+ {
+ // We don't expect this to happen; it's UTF-8.
+ throw new IllegalArgumentException(cce);
+ }
+ int length = 3 + nameBuf.remaining();
+ buffer = ByteBuffer.allocate(length);
+ buffer.put((byte) type.getValue());
+ buffer.putShort((short) (length - 3));
+ buffer.put(nameBuf);
+ buffer.rewind();
+ }
+
public int length()
{
- return buffer.getShort(1) & 0xFFFF;
+ return (buffer.getShort(1) & 0xFFFF) + 3;
+ }
+
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
}
public NameType type()
diff --git a/gnu/javax/net/ssl/provider/ServerPSKParameters.java b/gnu/javax/net/ssl/provider/ServerPSKParameters.java
new file mode 100644
index 000000000..8acce6dde
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ServerPSKParameters.java
@@ -0,0 +1,127 @@
+/* ServerPSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * <pre>
+ struct {
+ select (KeyExchangeAlgorithm) {
+ /* other cases for rsa, diffie_hellman, etc. &ast;/
+ case psk: /* NEW &ast;/
+ opaque psk_identity_hint&lt;0..2^16-1&gt;;
+ };
+ } ServerKeyExchange;</pre>
+ *
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ServerPSKParameters implements Builder, Constructed, ServerKeyExchangeParams
+{
+ private ByteBuffer buffer;
+
+ public ServerPSKParameters(ByteBuffer buffer)
+ {
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
+ }
+
+ public ServerPSKParameters(String identityHint)
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ ByteBuffer identityHintBuffer = utf8.encode(identityHint);
+ buffer = ByteBuffer.allocate(2 + identityHintBuffer.remaining());
+ buffer.putShort((short) identityHintBuffer.remaining());
+ buffer.put(identityHintBuffer);
+ buffer.rewind();
+ }
+
+ public KeyExchangeAlgorithm algorithm()
+ {
+ return KeyExchangeAlgorithm.PSK;
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Builder#buffer()
+ */
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().rewind().limit(length());
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#length()
+ */
+ public int length()
+ {
+ return (buffer.getShort(0) & 0xFFFF) + 2;
+ }
+
+ public String identityHint()
+ {
+ Charset utf8 = Charset.forName("UTF-8");
+ return utf8.decode((ByteBuffer) buffer.duplicate().position(2).limit(length())).toString();
+ }
+
+ public @Override String toString()
+ {
+ return toString(null);
+ }
+
+ /* (non-Javadoc)
+ * @see gnu.javax.net.ssl.provider.Constructed#toString(java.lang.String)
+ */
+ public String toString(String prefix)
+ {
+ StringWriter str = new StringWriter();
+ PrintWriter out = new PrintWriter(str);
+ if (prefix != null) out.print(prefix);
+ out.println("struct {");
+ if (prefix != null) out.print(prefix);
+ out.print(" identity_hint = ");
+ out.print(identityHint());
+ out.println(";");
+ if (prefix != null) out.print(prefix);
+ out.print("} ServerPSKParamaters;");
+ return str.toString();
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java b/gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java
new file mode 100644
index 000000000..0d7b590d2
--- /dev/null
+++ b/gnu/javax/net/ssl/provider/ServerRSA_PSKParameters.java
@@ -0,0 +1,62 @@
+/* ServerRSA_PSKParameters.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.net.ssl.provider;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author Casey Marshall (csm@gnu.org)
+ */
+public class ServerRSA_PSKParameters extends ServerPSKParameters
+{
+ public ServerRSA_PSKParameters(ByteBuffer buffer)
+ {
+ super(buffer);
+ }
+
+ public ServerRSA_PSKParameters(String identityHint)
+ {
+ super(identityHint);
+ }
+
+ public @Override KeyExchangeAlgorithm algorithm()
+ {
+ return KeyExchangeAlgorithm.RSA_PSK;
+ }
+}
diff --git a/gnu/javax/net/ssl/provider/TruncatedHMAC.java b/gnu/javax/net/ssl/provider/TruncatedHMAC.java
index 147b8ed1d..0595f87a7 100644
--- a/gnu/javax/net/ssl/provider/TruncatedHMAC.java
+++ b/gnu/javax/net/ssl/provider/TruncatedHMAC.java
@@ -1,7 +1,47 @@
+/* TruncatedHMAC.java --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
+import java.nio.ByteBuffer;
+
/**
* The value type for the {@link Extension.Type#TRUNCATED_HMAC} extension.
* This extension has an empty value; this class is thusly empty.
@@ -16,6 +56,11 @@ public class TruncatedHMAC extends Value
return 0;
}
+ public ByteBuffer buffer()
+ {
+ return ByteBuffer.wrap(new byte[0]);
+ }
+
public String toString()
{
return toString(null);
diff --git a/gnu/javax/net/ssl/provider/TrustedAuthorities.java b/gnu/javax/net/ssl/provider/TrustedAuthorities.java
index 89cf868b8..1e4b17359 100644
--- a/gnu/javax/net/ssl/provider/TrustedAuthorities.java
+++ b/gnu/javax/net/ssl/provider/TrustedAuthorities.java
@@ -1,3 +1,41 @@
+/* TrustedAuthorities.java
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.java.security.x509.X500DistinguishedName;
@@ -6,6 +44,7 @@ import gnu.javax.net.ssl.provider.Extension.Value;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -45,14 +84,21 @@ public class TrustedAuthorities extends Value
public TrustedAuthorities(final ByteBuffer buffer)
{
- this.buffer = buffer;
+ this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
}
+ // XXX really implement Builder.
+
public int length()
{
return 2 + (buffer.getShort(0) & 0xFFFF);
}
+ public ByteBuffer buffer()
+ {
+ return (ByteBuffer) buffer.duplicate().limit(length());
+ }
+
public int size()
{
int len = buffer.getShort(0) & 0xFFFF;
diff --git a/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java b/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java
index 720249e85..2094daf90 100644
--- a/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java
+++ b/gnu/javax/net/ssl/provider/UnresolvedExtensionValue.java
@@ -1,3 +1,41 @@
+/* UnresolvedExtensionValue.jav --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
package gnu.javax.net.ssl.provider;
import gnu.javax.net.ssl.provider.Extension.Value;
@@ -20,6 +58,11 @@ public class UnresolvedExtensionValue extends Value
return buffer.limit();
}
+ public ByteBuffer buffer()
+ {
+ return value();
+ }
+
public ByteBuffer value()
{
return buffer.slice();
diff --git a/gnu/javax/net/ssl/provider/Util.java b/gnu/javax/net/ssl/provider/Util.java
index 0dae5a712..ba8ea7db7 100644
--- a/gnu/javax/net/ssl/provider/Util.java
+++ b/gnu/javax/net/ssl/provider/Util.java
@@ -71,6 +71,33 @@ public final class Util
// Class methods.
// -------------------------------------------------------------------------
+ public static Object wrapBuffer(ByteBuffer buffer)
+ {
+ return wrapBuffer(buffer, "");
+ }
+
+ public static Object wrapBuffer(ByteBuffer buffer, String prefix)
+ {
+ return new WrappedBuffer(buffer, prefix);
+ }
+
+ private static class WrappedBuffer
+ {
+ private final ByteBuffer buffer;
+ private final String prefix;
+
+ WrappedBuffer(ByteBuffer buffer, String prefix)
+ {
+ this.buffer = buffer;
+ this.prefix = prefix;
+ }
+
+ public String toString()
+ {
+ return hexDump(buffer, prefix);
+ }
+ }
+
/**
* Convert a hexadecimal string into its byte representation.
*
diff --git a/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java b/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
index b82f5b71e..dc7728866 100644
--- a/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
+++ b/gnu/javax/net/ssl/provider/X509KeyManagerFactory.java
@@ -333,7 +333,8 @@ public class X509KeyManagerFactory extends KeyManagerFactorySpi
if (keyType.equalsIgnoreCase("RSA")
|| keyType.equalsIgnoreCase("DHE_RSA")
|| keyType.equalsIgnoreCase("SRP_RSA")
- || keyType.equalsIgnoreCase("rsa_sign"))
+ || keyType.equalsIgnoreCase("rsa_sign")
+ || keyType.equalsIgnoreCase("RSA_PSK"))
{
if (!(privKey instanceof RSAPrivateKey) ||
!(pubKey instanceof RSAPublicKey))