Name: js151677 Date: 06/09/2004 FULL PRODUCT VERSION : java version "1.5.0-beta2" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51) Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing) ADDITIONAL OS VERSION INFORMATION : Microsoft Windows XP [Version 5.1.2600] A DESCRIPTION OF THE PROBLEM : I have a https server with a self issued certificate (I used keytool to generate it) and a java developed browser. When I try to connect the browser to my server using https://localhost:8080/ it fails under version 150-beta2, but it works under version 1.4.1_02 The exception message is different if the certificate was generate using RSA or DSA algorithm STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : generate certificate using keytool ------------------------------------------------------------------------------------ keytool -genkey -keystore serverkeys -keyalg rsa -alias myalias keytool -export -keystore serverkeys -alias myalias -file server.cer keytool -import -keystore trustedcerts -alias myalias -file server.cer ------------------------------------------------------------------------------------ create a file named index.html as start for server start server java HttpsServer start client java -Djavax.net.ssl.trustStore=trustedcerts HttpBrowser point browser to address https://localhost:8080/ EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - I expect to see the content of file index.html ACTUAL - I get an exception message ERROR MESSAGES/STACK TRACES THAT OCCUR : if the certificate is generate using RSA the exception is --------------------------------------------------------------------------------- javax.net.ssl.SSLKeyException: RSA premaster secret error javax.net.ssl.SSLKeyException: RSA premaster secret error at com.sun.net.ssl.internal.ssl.PreMasterSecret. (Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source) at HttpsBrowser.readURL(HttpsBrowser.java:78) at HttpsBrowser.run(HttpsBrowser.java:57) at java.lang.Thread.run(Unknown Source) Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/PKCS1Padding at javax.crypto.Cipher.getInstance(DashoA12275) at com.sun.net.ssl.internal.ssl.JsseJce.getCipher(Unknown Source) at com.sun.net.ssl.internal.ssl.RSACipher. (Unknown Source) at com.sun.net.ssl.internal.ssl.RSACipher.getInstance(Unknown Source) ... 15 more ---------------------------------------------------------------------------- if the certificate was generated using DSA ---------------------------------------------------------------------------- javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate secret javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate secret at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source) at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source) at HttpsBrowser.readURL(HttpsBrowser.java:78) at HttpsBrowser.run(HttpsBrowser.java:57) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.RuntimeException: Could not generate secret at com.sun.net.ssl.internal.ssl.DHKeyExchange.getAgreedSecret(Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) ... 8 more Caused by: java.security.NoSuchAlgorithmException: DiffieHellman KeyFactory not available at java.security.KeyFactory. (Unknown Source) at java.security.KeyFactory.getInstance(Unknown Source) ... 15 more REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- -------------- server -------------- import java.io.*; import java.net.*; import javax.net.*; import javax.net.ssl.*; import java.security.*; import java.util.StringTokenizer; public class HttpsServer { String keystore = "serverkeys"; char keystorepass[] = "pwdserverkeystore".toCharArray(); char keypassword[] = "pwdserverkeystore".toCharArray(); public static final int HTTPS_PORT = 8080; public ServerSocket getServer() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(keystore), keystorepass); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, keypassword); SSLContext sslcontext = SSLContext.getInstance("SSLv3"); sslcontext.init(kmf.getKeyManagers(), null, null); ServerSocketFactory ssf = sslcontext.getServerSocketFactory(); SSLServerSocket serversocket = (SSLServerSocket) ssf .createServerSocket(HTTPS_PORT); return serversocket; } public void run() { ServerSocket listen; try { listen = getServer(); while (true) { Socket client = listen.accept(); ProcessConnection cc = new ProcessConnection(client); } } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } class ProcessConnection extends Thread { Socket client; BufferedReader is; DataOutputStream os; public ProcessConnection(Socket s) { client = s; try { is = new BufferedReader(new InputStreamReader(client .getInputStream())); os = new DataOutputStream(client.getOutputStream()); } catch (IOException e) { System.out.println("Exception: " + e.getMessage()); } this.start(); } public void run() { try { String request = is.readLine(); System.out.println("Request: " + request); StringTokenizer st = new StringTokenizer(request); if ((st.countTokens() >= 2) && st.nextToken().equals("GET")) { if ((request = st.nextToken()).startsWith("/")) request = request.substring(1); if (request.equals("")) request = request + "index.html"; File f = new File(request); shipDocument(os, f); } else { os.writeBytes("400 Bad Request"); } client.close(); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } } public void shipDocument(DataOutputStream out, File f) throws Exception { try { DataInputStream in = new DataInputStream(new FileInputStream(f)); int len = (int) f.length(); byte[] buf = new byte[len]; in.readFully(buf); in.close(); out.writeBytes("HTTP/1.0 200 OK\r\n"); out.writeBytes("Content-Length: " + f.length() + "\r\n"); out.writeBytes("Content-Type: text/html\r\n\r\n"); out.write(buf); out.flush(); } catch (Exception e) { out.writeBytes("<html><head><title>error</title></head><body>\r\n\r\n"); out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n"); out.writeBytes("Content-Type: text/html\r\n\r\n"); out.writeBytes("</body></html>"); out.flush(); } finally { out.close(); } } } public static void main(String argv[]) throws Exception { HttpsServer https = new HttpsServer(); https.run(); } } -------------- browser -------------- import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class HttpsBrowser implements ActionListener, Runnable { private JFrame frame; private JButton go; private JEditorPane content; private JTextField url; private JLabel statusLine; public HttpsBrowser() { buildBrowserInterface(); } private void buildBrowserInterface() { frame = new JFrame("HTTPS Browser"); frame.setDefaultCloseOperation(3); url = new JTextField("https://localhost:8080/", 25); go = new JButton("Go"); go.addActionListener(this); JPanel controls = new JPanel(new FlowLayout()); controls.add(new JLabel("URL:")); controls.add(url); controls.add(go); content = new JEditorPane(); content.setEditable(false); content.setContentType("text/html"); content.setText(""); statusLine = new JLabel("Initialization Complete"); JPanel panel = new JPanel(new BorderLayout(0, 2)); frame.setContentPane(panel); panel.add(controls, "North"); panel.add(new JScrollPane(content), "Center"); panel.add(statusLine, "South"); frame.pack(); frame.setBounds(100, 100, 700, 500); frame.setExtendedState(6); frame.setVisible(true); } public void actionPerformed(ActionEvent event) { Thread thread = new Thread(this); thread.start(); } public void run() { try { String str = url.getText(); URL url = new URL(str); readURL(url); } catch (IOException ioe) { statusLine.setText("Error: " + ioe.getMessage()); showException(ioe); } } private void showException(Exception ex) { StringWriter trace = new StringWriter(); ex.printStackTrace(new PrintWriter(trace)); content.setContentType("text/html"); content.setText("<h3>" + ex + "</h3><pre>" + trace + "</pre>"); } private void readURL(URL url) throws IOException { statusLine.setText("Opening " + url.toExternalForm()); URLConnection connection = url.openConnection(); StringBuffer buffer = new StringBuffer(); BufferedReader in = null; try { in = new BufferedReader(new InputStreamReader(connection .getInputStream())); String line; while ((line = in.readLine()) != null) { buffer.append(line).append('\n'); statusLine.setText("Read " + buffer.length() + " bytes..."); } } finally { if (in != null) in.close(); } String type = connection.getContentType(); if (type == null) type = "text/plain"; statusLine.setText("Content type " + type); content.setContentType(type); content.setText(buffer.toString()); statusLine.setText("Done"); } public static void main(String[] args) { HttpsBrowser browser = new HttpsBrowser(); } } ---------- END SOURCE ---------- (Incident Review ID: 276708) ======================================================================
|