You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/10/27 10:33:30 UTC

svn commit: r468315 - in /incubator/harmony/enhanced/classlib/trunk/modules/x-net/src: main/java/org/apache/harmony/xnet/provider/jsse/ test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/

Author: tellison
Date: Fri Oct 27 01:33:28 2006
New Revision: 468315

URL: http://svn.apache.org/viewvc?view=rev&rev=468315
Log:
Apply patch HARMONY-1937 ([classlib][xnet] Problem connecting using SSLSocketImpl. Recieved decode_error)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateVerify.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeIODataStream.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
    incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/CertificateVerifyTest.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateRequest.java Fri Oct 27 01:33:28 2006
@@ -29,6 +29,7 @@
 
 import java.io.IOException;
 import java.security.cert.X509Certificate;
+import java.util.Vector;
 
 import javax.security.auth.x500.X500Principal;
 
@@ -57,7 +58,7 @@
     /**
      * Certificate authorities
      */
-    final X500Principal[] certificate_authorities;
+    X500Principal[] certificate_authorities;
 
     //Requested certificate types as Strings
     // ("RSA", "DSA", "DH_RSA" or "DH_DSA")
@@ -109,12 +110,17 @@
         certificate_authorities = new X500Principal[size];
         int totalPrincipalsLength = 0;
         int principalLength = 0;
-        for (int i = 0; i < size; i++) {
+        Vector principals = new Vector();
+        while (totalPrincipalsLength < size) {            
             principalLength = in.readUint16(); // encoded X500Principal size
-            certificate_authorities[i] = new X500Principal(in);
+            principals.add(new X500Principal(in));
             totalPrincipalsLength += 2;
             totalPrincipalsLength += principalLength;
         }
+        certificate_authorities = new X500Principal[principals.size()];
+        for (int i = 0; i < certificate_authorities.length; i++) {
+            certificate_authorities[i] = (X500Principal) principals.elementAt(i);
+        }
         this.length = 3 + certificate_types.length + totalPrincipalsLength;
         if (this.length != length) {
             fatalAlert(AlertProtocol.DECODE_ERROR,
@@ -134,7 +140,11 @@
         for (int i = 0; i < certificate_types.length; i++) {
             out.write(certificate_types[i]);
         }
-        out.writeUint16(certificate_authorities.length);
+        int authoritiesLength = 0;
+        for (int i = 0; i < certificate_authorities.length; i++) {
+            authoritiesLength += encoded_principals[i].length +2;
+        }
+        out.writeUint16(authoritiesLength);
         for (int i = 0; i < certificate_authorities.length; i++) {
             out.writeUint16(encoded_principals[i].length);
             out.write(encoded_principals[i]);

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateVerify.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateVerify.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateVerify.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/CertificateVerify.java Fri Oct 27 01:33:28 2006
@@ -48,8 +48,12 @@
      * @param hash
      */
     public CertificateVerify(byte[] hash) {
+        if (hash == null || hash.length == 0) {
+            fatalAlert(AlertProtocol.INTERNAL_ERROR,
+                    "INTERNAL ERROR: incorrect certificate verify hash");
+        }
         this.signedHash = hash;
-        length = hash.length;
+        length = hash.length + 2;
     }
 
     /**
@@ -62,12 +66,14 @@
     public CertificateVerify(HandshakeIODataStream in, int length)
             throws IOException {
         if (length == 0) {
-            signedHash = new byte[0];
-        } else if (length == 20 || length == 36) {
-            signedHash = in.read(length);
-        } else {
             fatalAlert(AlertProtocol.DECODE_ERROR,
                     "DECODE ERROR: incorrect CertificateVerify");
+        } else {
+            if (in.readUint16() != length - 2) {
+                fatalAlert(AlertProtocol.DECODE_ERROR,
+                        "DECODE ERROR: incorrect CertificateVerify");
+            }
+            signedHash = in.read(length -2);
         }
         this.length = length;
     }
@@ -79,6 +85,7 @@
      */
     public void send(HandshakeIODataStream out) {
         if (signedHash.length != 0) {
+            out.writeUint16(signedHash.length);
             out.write(signedHash);
         }
     }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java Fri Oct 27 01:33:28 2006
@@ -29,6 +29,7 @@
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
 import java.security.PrivilegedExceptionAction;
 import java.security.PublicKey;
 import java.security.cert.CertificateException;
@@ -366,6 +367,8 @@
      * client messages, computers masterSecret, sends ChangeCipherSpec
      */
     void processServerHelloDone() {
+        PrivateKey clientKey = null;
+
         if (serverCert != null) {
             if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon
                     || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
@@ -389,8 +392,10 @@
                     .getTypesAsString(),
                     certificateRequest.certificate_authorities, null);
             if (clientAlias != null) {
-                certs = ((X509ExtendedKeyManager) parameters.getKeyManager())
-                        .getCertificateChain((clientAlias));
+                X509ExtendedKeyManager km = (X509ExtendedKeyManager) parameters
+                        .getKeyManager();
+                certs = km.getCertificateChain((clientAlias));
+                clientKey = km.getPrivateKey(clientAlias);
             }
             session.localCertificates = certs;
             clientCert = new CertificateMessage(certs);
@@ -503,27 +508,29 @@
 
         computerMasterSecret();
 
-        if (clientCert != null) {
-            boolean[] keyUsage = clientCert.certs[0].getKeyUsage();
-            if (keyUsage != null && keyUsage[0]) {
-                // Certificate verify
-                DigitalSignature ds = new DigitalSignature(
-                        session.cipherSuite.keyExchange);
-                if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
-                        || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
-                        || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
-                    ds.setMD5(io_stream.getDigestMD5());
-                    ds.setSHA(io_stream.getDigestSHA());
-                } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
-                        || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
-                    ds.setSHA(io_stream.getDigestSHA());
-                // The Signature should be empty in case of anonimous signature algorithm:
-                // } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon ||
-                // session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
-                }
-                certificateVerify = new CertificateVerify(ds.sign());
-                send(certificateVerify);
+        // send certificate verify for all certificates except those containing
+        // fixed DH parameters
+        if (clientCert != null && !clientKeyExchange.isEmpty()) {
+            // Certificate verify
+            DigitalSignature ds = new DigitalSignature(
+                    session.cipherSuite.keyExchange);
+            ds.init(clientKey);
+
+            if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
+                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
+                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
+                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) { 
+                ds.setMD5(io_stream.getDigestMD5());
+                ds.setSHA(io_stream.getDigestSHA());
+            } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
+                    || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
+                ds.setSHA(io_stream.getDigestSHA());
+            // The Signature should be empty in case of anonimous signature algorithm:
+            // } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon ||
+            //         session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
             }
+            certificateVerify = new CertificateVerify(ds.sign());
+            send(certificateVerify);
         }
 
         sendChangeCipherSpec();

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/DigitalSignature.java Fri Oct 27 01:33:28 2006
@@ -71,6 +71,7 @@
     public DigitalSignature(int keyExchange) {
         try { 
             if (keyExchange == CipherSuite.KeyExchange_RSA_EXPORT ||
+                    keyExchange == CipherSuite.KeyExchange_RSA ||
                     keyExchange == CipherSuite.KeyExchange_DHE_RSA ||
                     keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
                 // SignatureAlgorithm is rsa

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeIODataStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeIODataStream.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeIODataStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeIODataStream.java Fri Oct 27 01:33:28 2006
@@ -425,6 +425,30 @@
     }
 
     /**
+     * Returns the MD5 digest of the data passed throught the stream
+     * except last message
+     * @return MD5 digest
+     */
+    protected byte[] getDigestMD5withoutLast() {
+        synchronized (md5) {
+            md5.update(buffer, 0, marked_pos);
+            return md5.digest();
+        }
+    }
+
+    /**
+     * Returns the SHA-1 digest of the data passed throught the stream
+     * except last message
+     * @return SHA-1 digest
+     */
+    protected byte[] getDigestSHAwithoutLast() {
+        synchronized (sha) {
+            sha.update(buffer, 0, marked_pos);
+            return sha.digest();
+        }
+    }
+
+    /**
      * Returns all the data passed throught the stream
      * @return all the data passed throught the stream at the moment
      */

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java Fri Oct 27 01:33:28 2006
@@ -184,29 +184,19 @@
                     certificateVerify = new CertificateVerify(io_stream, length);
 
                     DigitalSignature ds = new DigitalSignature(session.cipherSuite.keyExchange);
+                    ds.init(serverCert.certs[0]);                 
                     byte[] md5_hash = null;
                     byte[] sha_hash = null;
-                    PublicKey pk = serverCert.certs[0].getPublicKey();
-                    if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT) {
-                        int l;
-                        try {
-                            l = getRSAKeyLength(pk);
-                        } catch (Exception e) {
-                            fatalAlert(AlertProtocol.INTERNAL_ERROR,
-                                    "INTERNAL ERROR", e);
-                            return;
-                        }
-                        if (l > 512) { // key is longer than 512 bits
-                            md5_hash = io_stream.getDigestMD5();
-                            sha_hash = io_stream.getDigestSHA();
-                        }
-                    } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
+
+                    if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA_EXPORT
+                            || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_RSA
+                            || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA
                             || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_RSA_EXPORT) {
-                        md5_hash = io_stream.getDigestMD5();
-                        sha_hash = io_stream.getDigestSHA();
+                        md5_hash = io_stream.getDigestMD5withoutLast();
+                        sha_hash = io_stream.getDigestSHAwithoutLast();
                     } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS
                             || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DHE_DSS_EXPORT) {
-                        sha_hash = io_stream.getDigestSHA();
+                        sha_hash = io_stream.getDigestSHAwithoutLast();
                     } else if (session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon
                             || session.cipherSuite.keyExchange == CipherSuite.KeyExchange_DH_anon_EXPORT) {
                     }
@@ -712,7 +702,7 @@
         } else {
             if ((parameters.getNeedClientAuth() && clientCert == null)
                     || clientKeyExchange == null
-                    || (clientKeyExchange.isEmpty() && certificateVerify == null)) {
+                    || (clientCert != null && !clientKeyExchange.isEmpty() && certificateVerify == null)) {
                 unexpectedMessage();
             } else {
                 changeCipherSpecReceived = true;

Modified: incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/CertificateVerifyTest.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/CertificateVerifyTest.java?view=diff&rev=468315&r1=468314&r2=468315
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/CertificateVerifyTest.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/x-net/src/test/impl/java.injected/org/apache/harmony/xnet/provider/jsse/CertificateVerifyTest.java Fri Oct 27 01:33:28 2006
@@ -37,8 +37,19 @@
 		byte[] DSAHash  = new byte[] {
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
 				1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
-		byte[][] signatures = new byte[][] { anonHash, RSAHash, DSAHash };
-		for (int i = 0; i < 3; i++) {
+		byte[][] signatures = new byte[][] { RSAHash, DSAHash };
+        try {
+            new CertificateVerify(anonHash);
+            fail("Anonymous: No expected AlertException");
+        } catch (AlertException e) {
+        }
+        try {
+            HandshakeIODataStream in = new HandshakeIODataStream();
+            new CertificateVerify(in, 0);
+            fail("Anonymous: No expected AlertException");
+        } catch (AlertException e) {
+        }
+		for (int i = 0; i < signatures.length; i++) {
 			CertificateVerify message = new CertificateVerify(signatures[i]);
             assertEquals("incorrect type", Handshake.CERTIFICATE_VERIFY,
                     message.getType());