4/16 email'
Dear Colleagues:
Many of you have asked what the current process is for reporting students who have COVID-19 or symptoms of COVID-19.
As you may be aware, beginning in early March the Division of Student Affairs connected with all students reported to us who either had COVID-19 or had symptoms consistent with COVID-19. We reached out to each student and helped those who needed it connect to resources such as medical advice, emergency funds, and food. We also assisted students in need of mobile devices so they could continue to engage in distance learning. Most importantly, under the guidance of CUNY and public health officials, we notified those on campus who may have been exposed to these students so they could seek medical advice based on their personal situations.
Given that in-person classes have not been held since March 11, 2020, and we no longer have reporting requirements for the larger campus community because the majority of students, faculty, and staff are not on campus, we are writing to inform you of what you should do now if a student reports a positive test for COVID-19 or symptoms consistent with COVID-19.
Based on NYC and NYS public health officials, COVID-19 is widespread among the population. Thus, you should expect that many students might become ill.  I would encourage you to consider what standard of proof is required (e.g., doctor’s note) since given the significant burden on healthcare providers right now, students might not be able to readily get those documents from primary care physicians.
Next, continue to refer students to my office who as a result of being ill report having a financial hardship, food insecurity, mental health or other medical issues, and any other concerns that you think should be reported. You may email us at<EMAIL_ADDRESS>and we will promptly respond.
COVID-19 has had an unprecedented impact upon our entire community. No aspect of our work or professional lives has been untouched. Our students are in the same position with the added burden of some having lost their employment and in some cases their health insurance as well. If you know of a student in need of health insurance, Health and Wellness Services will assist students in contacting our Metro Plus health insurance facilitator. Metro Plus phone consultations are available Monday through Friday from 9:00 a.m. to 5:00 p.m. They have been very helpful in locating no or low-cost insurance for our students. Interested students should contact<EMAIL_ADDRESS>for more information.
Also, if you encounter a student or situation that is a cause for concern, such as personal distress, please contact our CARES Team – the Campus Assessment Referral and Evaluation System (CARES) Team. The CARES Team provides a coordinated response to situations where students are experiencing distress or engaging in harmful or disruptive behaviors. Please report these concerns here: http://www.csi.cuny.edu/cares/.
As always, the Division of Student Affairs will continue to support and engage students as we all adjust to this new normal. Thank you for your support of CSI students and for communicating the Division’s services and resources.
Best regards,
Jennifer S. Borrero, J.D. Vice President for Student Affairs and Alumni Engagement


ARDUINO DATA ON A WEB PAGE
This week we will start looking at how to send data from an Arduino to a web page. You will be doing this by creating a Node.js application. This application will have code so you can use your computer as a local server, as well the code needed to get the data from the Arduino. You will be using visual studio code, Arduino, and Node.js to do this. You will also be referencing the port your Arduino is attached to bring in the data. I will go through getting started with Visual Studio code and setting up the folder and files for the Node.js server. Then I will go through the connection to the Arduino and how to transfer data from the Arduino, to the server, to a web page.
I’ll be walking through setting up with visual studio code, if you are using a different coding editor, it will be similar, but you may need to do some things differently.
Node.js is an open-source, cross-platform, back-end, JavaScript runtime environment that executes JavaScript code outside a web browser. Node.js lets developers use JavaScript to write command line tools and for server-side scripting—running scripts server-side to produce dynamic web page content before the page is sent to the user's web browser.
Wikipedia
Breaking this down:
with Node.js you can use JavaScript to code on the server, not just the browser
You can use it to update a web page dynamically. This means the page updates as soon as there is new data, not when the person refreshes their browser
It is a runtime environment not a JavaScript framework so,
It is not limited to creating web applications, you can do basic robotics, or program a drone
It is a runtime environment;
A RUNTIME ENVIRONMENT
A runtime environment is different from a JavaScript framework or library as it acts as a small operating system that provides all the functionality for a program to run.
It means that Node.js lets you create an environment to use JavaScript on the server
It has a way to translate the JavaScript to the machine language the computer hardware can understand
It uses event loops, which means it transmits data without constantly querying, this makes it faster
Today's Project
Today you will be creating a Node.js application that can import data from an Arduino and send it to a web page. In order to do this the application will use your computer as a local server, so you can use your computer to see the back and front end of the application.
You should have Node.js installed on your computer, and you could write the everything without other libraries, but that would get quite difficult. There are a number of libraries, called modules, that you can import into your application to make it easier. One of the frameworks you will use a lot with Node.js is Express. With Express you can create a server with a few lines of code, and also create the routes to web pages.
Node Package manager
You will be using Node Package Manager (npm) to install the packages for your application. Npm is the default package manager for Node.js and uses the command line interface to install packages. It is a repository for packages, anyone can make a package, and Express is available on npm. You will also be using npm to initialize your Node.js application.
Node Package manager
When you look up a package on the npm site for example Express https://www.npmjs.com/package/express it will give you information on how to install it, its features and some information on getting started.
I just want to say a few words about JSON files. They are used quite a lot with JavaScript and there is a package.json file created for Node.js application. The JSON file extension stands for JavaScript Object Notation. It is an open standard file and data exchange format, which means it can be used to input into an application. It uses text to store and transmit data objects consisting of attribute–value pairs and array data types, it uses key value pairs. In week one you saw the JavaScript object data type, the JSON format is similar to this. The package.json file for my application looks like this:
SETTING UP THE ARDUINO
- Arduino
- A Button component
- 220 Ohm resistor
- A Bread Board
- 4 Jump Wires
For this you will need an Arduino, a button component a 220-ohm resistor a bread board and 4 jump wires.
Connect the button to the Arduino, this diagram is in week 4 on the github.
Create a new Arduino sketch and use the code button_serial.ino from week 4 github


To display the current ruby selection string in your prompt there are two steps necessary.
First copy scripts/rvm-prompt to somewhere a bin directory in your path and then add this to your profile file:
PS1="\$(rvm-prompt) $PS1"
This ends up looking like this during usage:
∴ rvm 1.9.1
[ruby:1.9.1:p243] ∴
[ruby:1.9.1:p243] ∴ rvm 1.8.6
[ruby:1.8.6:p383] ∴ rvm jruby
[jruby:1.3.1] ∴


|
| onesdk_webapplicationinfo_handle_t | onesdk_webapplicationinfo_create (onesdk_string_t web_server_name, onesdk_string_t application_id, onesdk_string_t context_root) |
| | Creates a web application info object. More...
|
| |
| void | onesdk_webapplicationinfo_delete (onesdk_webapplicationinfo_handle_t webapplicationinfo_handle) |
| | Releases a web application info object. More...
|
| |
| onesdk_tracer_handle_t | onesdk_incomingwebrequesttracer_create (onesdk_webapplicationinfo_handle_t webapplicationinfo_handle, onesdk_string_t url, onesdk_string_t method) |
| | Creates a tracer for tracing an incoming web request. More...
|
| |
| void | onesdk_incomingwebrequesttracer_set_remote_address (onesdk_tracer_handle_t tracer_handle, onesdk_string_t remote_address) |
| | Sets the remote address of an incoming web request. More...
|
| |
| void | onesdk_incomingwebrequesttracer_add_request_header (onesdk_tracer_handle_t tracer_handle, onesdk_string_t name, onesdk_string_t value) |
| | Adds an HTTP request header of an incoming web request. More...
|
| |
| void | onesdk_incomingwebrequesttracer_add_parameter (onesdk_tracer_handle_t tracer_handle, onesdk_string_t name, onesdk_string_t value) |
| | Adds an HTTP POST parameter of an incoming web request. More...
|
| |
| void | onesdk_incomingwebrequesttracer_add_response_header (onesdk_tracer_handle_t tracer_handle, onesdk_string_t name, onesdk_string_t value) |
| | Adds an HTTP response header for an incoming web request. More...
|
| |
| void | onesdk_incomingwebrequesttracer_set_status_code (onesdk_tracer_handle_t tracer_handle, onesdk_int32_t status_code) |
| | Sets the HTTP status code for an incoming web request. More...
|
| |
Incoming web request tracers are used to capture information about HTTP requests that the application services (processes, answers).
To create an incoming web request tracer, an application must first create a web application info object which describes the web application - see onesdk_webapplicationinfo_create.
For further information, see the high level SDK documentation at https://github.com/Dynatrace/OneAgent-SDK/#webrequests
- Since
- Incoming web request tracers were added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_add_parameter()
Adds an HTTP POST parameter of an incoming web request.
- Parameters
-
| tracer_handle | A valid incoming web request tracer handle. |
| name | The name of the HTTP POST parameter. |
| value | [optional] The value of the HTTP POST parameter. |
- Note
- The native SDK agent will currently capture all provided parameters.
- Since
- This function was added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_add_request_header()
Adds an HTTP request header of an incoming web request.
- Parameters
-
| tracer_handle | A valid incoming web request tracer handle. |
| name | The name of the HTTP request header. |
| value | [optional] The value of the HTTP request header. |
To allow the agent to determine various bits of useful information, an application should add all HTTP request headers.
- Note
- The native SDK agent will currently capture all provided headers.
-
If an HTTP request contains multiple header lines with the same header name, an application should call this function once per line. Alternatively, depending on the header, the application can call this function once per header name, with an appropriately concatenated header value.
-
This function can not be used after the tracer was started.
- Since
- This function was added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_add_response_header()
Adds an HTTP response header for an incoming web request.
- Parameters
-
| tracer_handle | A valid incoming web request tracer handle. |
| name | The name of the HTTP response header. |
| value | [optional] The value of the HTTP response header. |
- Note
- The native SDK agent will currently capture all provided headers.
-
If the HTTP response contains multiple header lines with the same header name, an application should call this function once per line. Alternatively, depending on the header, the application can call this function once per header name, with an appropriately concatenated header value.
- Since
- This function was added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_create()
Creates a tracer for tracing an incoming web request.
- Parameters
-
| webapplicationinfo_handle | A valid web application info handle. |
| url | The requested URL. Will be parsed into scheme , host /port , path and query . |
| method | The HTTP method of the request. |
- Returns
- A handle for the newly created incoming web request tracer or ONESDK_INVALID_HANDLE.
- Note
url
does not have to contain a scheme
or host
. You can use the URL as it was sent in the HTTP request.
-
If
url
contains a host name it will be resolved by the agent (asynchronously) after onesdk_tracer_start was called.
- Since
- This function was added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_set_remote_address()
Sets the remote address of an incoming web request.
- Parameters
-
| tracer_handle | A valid incoming web request tracer handle. |
| remote_address | The remote IP address. |
The remote address is very useful to gain information about load balancers, proxies and ultimately the end user that is sending the request.
- Note
- The remote address is the peer address of the socket connection via which the request was received. In case one or more proxies are used, this will be the address of the last proxy in the proxy chain. To enable the agent to determine the client IP address (=the address where the request originated), an application should also call onesdk_incomingwebrequesttracer_add_request_header to add any HTTP request headers.
-
Calling this function with
remote_address
= onesdk_nullstr() will reset/clear any value that was set previously.
-
This function can not be used after the tracer was started.
- Since
- This function was added in version 1.1.0.
◆ onesdk_incomingwebrequesttracer_set_status_code()
Sets the HTTP status code for an incoming web request.
- Parameters
-
| tracer_handle | A valid incoming web request tracer handle. |
| status_code | The HTTP status code of the response sent to the client. |
- Note
- If an application can not send a response to the client, it should not call this function. Instead the application can use onesdk_tracer_error to signal that the request could not be processed successfully.
- Since
- This function was added in version 1.1.0.
◆ onesdk_webapplicationinfo_create()
Creates a web application info object.
- Parameters
-
| web_server_name | The logical name of the web server that hosts the application. In case of a cluster, every node in the cluster must use the same web_server_name . |
| application_id | A unique ID for the web application. This will also be used as the display name. |
| context_root | The context root of the web application. This is the common path prefix for requests which will be routed to the web application. |
- Returns
- A handle for the newly created web application info object or ONESDK_INVALID_HANDLE.
This function creates a web application info object which is required for tracing incoming web requests (see onesdk_incomingwebrequesttracer_create).
The provided information determines the identity and name of the resulting web request service in Dynatrace.
See https://www.dynatrace.com/support/help/server-side-services/introduction/how-does-dynatrace-detect-and-name-services/#web-request-services for more information about the meaning of the parameters.
- Since
- This function was added in version 1.1.0.
◆ onesdk_webapplicationinfo_delete()
Releases a web application info object.
- Parameters
-
| webapplicationinfo_handle | A valid web application info handle. |
This function releases the specified web application info object. Allocated resources are freed and the handle is invalidated.
An application should call onesdk_webapplicationinfo_delete exactly once for each web application info object that it has created.
- Note
- Calling onesdk_webapplicationinfo_delete with a handle to a web application info object which is still referenced by existing tracers is supported. In that case the lifetime of the web application info object is extended as necessary. The handle will always become invalid immediately though.
- Since
- This function was added in version 1.1.0.


| Package | Description |
|---|---|
| org.opensaml.xml |
Base classes for working with XML as Java objects and configuring the library.
|
| org.opensaml.xml.encryption |
XMLObject interfaces and helper classes for representing encrypted content and encrypting/decrypting content.
|
| org.opensaml.xml.encryption.impl |
Implementations of the interfaces for XMLObjects that represent XML encryption types.
|
| org.opensaml.xml.io |
Interfaces and abstract implementations of marshallers and unmarshallers.
|
| org.opensaml.xml.schema.impl |
Implementations of the interfaces for XMLObjects that represent XML schema types.
|
| org.opensaml.xml.security.keyinfo |
Interfaces and classes for working with XML KeyInfo elements.
|
| org.opensaml.xml.signature.impl |
Implementations of the interfaces for XMLObjects that represent XML signature types.
|
| org.opensaml.xml.util |
Utility classes for working with XML, XMLObjects, and various data types.
|
| Class and Description |
|---|
| AbstractXMLObjectMarshaller
A thread safe, abstract implementation of the
Marshaller interface. |
| AbstractXMLObjectUnmarshaller
An thread safe abstract unmarshaller.
|
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| MarshallerFactory
This thread-safe factory creates
Marshaller s that can be used to convert
XMLObject s into W3C DOM elements. |
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallerFactory
This thread-safe factory creates
Unmarshaller s that can be used to convert W3C DOM
elements into XMLObject s. |
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
| Class and Description |
|---|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallerFactory
This thread-safe factory creates
Unmarshaller s that can be used to convert W3C DOM
elements into XMLObject s. |
| Class and Description |
|---|
| AbstractXMLObjectMarshaller
A thread safe, abstract implementation of the
Marshaller interface. |
| AbstractXMLObjectUnmarshaller
An thread safe abstract unmarshaller.
|
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
| Class and Description |
|---|
| AbstractXMLObjectMarshaller
A thread safe, abstract implementation of the
Marshaller interface. |
| AbstractXMLObjectUnmarshaller
An thread safe abstract unmarshaller.
|
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| MarshallerFactory
This thread-safe factory creates
Marshaller s that can be used to convert
XMLObject s into W3C DOM elements. |
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallerFactory
This thread-safe factory creates
Unmarshaller s that can be used to convert W3C DOM
elements into XMLObject s. |
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
| Class and Description |
|---|
| AbstractXMLObjectMarshaller
A thread safe, abstract implementation of the
Marshaller interface. |
| AbstractXMLObjectUnmarshaller
An thread safe abstract unmarshaller.
|
| BaseXMLObjectMarshaller
Base class for
Marshaller classes. |
| BaseXMLObjectUnmarshaller
Base class for
Unmarshaller classes. |
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
| Class and Description |
|---|
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| Class and Description |
|---|
| AbstractXMLObjectMarshaller
A thread safe, abstract implementation of the
Marshaller interface. |
| AbstractXMLObjectUnmarshaller
An thread safe abstract unmarshaller.
|
| Marshaller
Marshallers are used to marshall a
XMLObject into a W3C DOM element. |
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| Unmarshaller
Unmarshallers are used to unmarshall a W3C DOM element into a
XMLObject . |
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
| Class and Description |
|---|
| MarshallingException
Exception thrown when error occurs marshalling an XMLObject to a DOM Element.
|
| UnmarshallingException
Exception thrown when error occurs unmarshalling a DOM Element to a XMLObject.
|
Copyright © 1999-2014. All Rights Reserved.


In the fall of 2009, a flaw was discovered in the SSL/TLS protocols. A fix to the protocol was developed by the IETF TLS Working Group, and current versions of the JDK contain this fix. This section describes the situation in much more detail, along with interoperability issues when communicating with older implementations that do not contain this protocol fix.
The vulnerability allowed for man-in-the-middle (MITM) attacks where chosen plain text could be injected as a prefix to a TLS connection. This vulnerability did not allow an attacker to decrypt or modify the intercepted network communication once the client and server have successfully negotiated a session between themselves.
Additional information is available at CVE-2009-3555 (posted on Mitre's Common Vulnerabilities and Exposures List, 2009) and Understanding the TLS Renegotiation Attack (posted on Eric Rescorla's blog, Educated Guesswork, November 5, 2009).
The fix for this issue was handled in two phases:
Phase 1: Until a protocol fix could be developed, an interim fix that disabled SSL/TLS renegotiations by default was made available in the March 30, 2010 Java SE and Java for Business Critical Patch Update.
Phase 2: The IETF issued RFC 5746, which addresses the renegotiation protocol flaw. The following table lists the JDK and JRE releases that include the fix which implements RFC 5746 and supports secure renegotiation.
| JDK Family | Vulnerable Releases | Phase 1 Fix (Disable Renegotiations) | Phase 2 Fix (RFC 5746) |
|---|---|---|---|
| JDK and JRE 6 | Update 18 and earlier | Updates 19 through 21 | Update 22 |
| JDK and JRE 5.0 | Update 23 and earlier | Updates 24 through 25 | Update 26 |
| JDK and JRE 1.4.2 | Update 25 and earlier | Updates 26 through 27 | Update 28 |
Note: Applications that do not require renegotiations are not affected by the Phase 2 default configuration. However applications that require renegotiations (for example, web servers that initially allow for anonymous client browsing, but later require SSL/TLS authenticated clients):
The SunJSSE implementation reenables renegotiations by default for connections to peers compliant with RFC 5746. That is, both the client and server must support RFC 5746 in order to securely renegotiate. SunJSSE provides some interoperability modes for connections with peers that have not been upgraded, but users are strongly encouraged to update both their client and server implementations as soon as possible.
With the Phase 2 fix, SunJSSE has three renegotiation interoperability modes. Each mode fully supports the RFC 5746 secure renegotiation, but has these added semantics when communicating with a peer that has not been upgraded:
Strict mode: Requires both client and server be upgraded to RFC 5746 and to send the proper RFC 5746 messages. If not, the initial (or subsequent) handshaking will fail and the connection will be terminated.
Interoperable mode (default): Use of the proper RFC 5746 messages is optional; however, legacy (original SSL/TLS specifications) renegotiations are disabled if the proper messages are not used. Initial legacy connections are still allowed, but legacy renegotiations are disabled. This is the best mix of security and interoperability, and is the default setting.
Insecure mode: Permits full legacy renegotiation. Most interoperable with legacy peers but vulnerable to the original MITM attack.
The three mode distinctions only affect a connection with a peer that has not been upgraded. Ideally, strict (full RFC 5746) mode should be used for all clients and servers; however, it will take some time for all deployed SSL/TLS implementations to support RFC 5746, because the interoperable mode is the current default.
Table 8 contains interoperability information about the modes for various cases in which the client and/or server are either updated to support RFC 5746 or not.
| Client | Server | Mode |
|---|---|---|
| Updated | Updated |
Secure renegotiation in all modes. |
| Legacy Footnote 1 | Updated |
|
| Updated | Legacy Footnote 1 |
|
| Legacy Footnote 1 | Legacy Footnote 1 | Existing SSL/TLS behavior, vulnerable to the MITM attack. |
Footnote 1 "Legacy" means the original SSL/TLS specifications (that is, not RFC 5746).
Footnote 2 SunJSSE Phase 1 implementations reject renegotiations unless specifically reenabled. If renegotiations are reenabled, then they will be treated as "Legacy" by the peer that is compliant with RFC 5746, because they do not send the proper RFC 5746 messages.
Footnote 3 In SSL/TLS, renegotiations can
be initiated by either side. Like the Phase 1 fix, applications
communicating with a peer that has not been upgraded in
Interoperable mode and that attempt to initiate renegotiation (via
SSLSocket.startHandshake()
or
SSLEngine.beginHandshake()
) will receive an
SSLHandshakeException
(IOException
) and
the connection will be shut down (handshake_failure
).
Applications that receive a renegotiation request from a peer that
has not been upgraded will respond according to the type of
connection in place:
no_renegotiation(100)
will be sent to the peer and the connection will remain open. Older
versions of SunJSSE will shut down the connection when a
no_renegotiation
alert is received.SSLHandshakeException
,
and the connection will be closed (handshake_failure
).
The no_renegotiation
alert is not defined in the SSLv3
specification.The following system properties are used to set the mode:
sun.security.ssl.allowUnsafeRenegotiation
(introduced in Phase 1) controls whether legacy (unsafe)
renegotiations are permitted.sun.security.ssl.allowLegacyHelloMessages
(introduced in Phase 2) allows the peer to perform the handshake
process without requiring the proper RFC 5746 messages.| Mode | allowLegacyHelloMessages |
allowUnsafeRenegotiation |
|---|---|---|
| Strict | false | false |
| Interoperable (default) | true | false |
| Insecure | true | true |
Caution: Do not reenable the insecure SSL/TLS renegotiation, as this would reestablish the vulnerability.
For information about how to configure a specific mode by setting a system property, see How to Specify a java.lang.System Property.
All peers should be updated to RFC 5746-compliant implementation as soon as possible. Even with this RFC 5746 fix, communications with peers that have not been upgraded will be affected if a renegotiation is necessary. Here are a few suggested options:
Restructure the peer to not require renegotiation.
Renegotiations are typically used by web servers that initially allow for anonymous client browsing but later require SSL/TLS authenticated clients, or that may initially allow weak cipher suites but later need stronger ones. The alternative is to require client authentication or strong cipher suites during the initial negotiation. There are a couple of options for doing so:
If an application has a browse mode until a certain point is reached and a renegotiation is required, then you can restructure the server to eliminate the browse mode and require all initial connections be strong.
Break the server into two entities, with the browse mode occurring on one entity, and using a second entity for the more secure mode. When the renegotiation point is reached, transfer any relevant information between the servers.
Both of these options require a fair amount of work, but will not reopen the original security flaw.
Set renegotiation interoperability mode to "insecure" using the system properties.
See the Description of the Phase 2 Fix for information and warnings.
RFC 5746 defines two new data structures, which are mentioned here for advanced users:
Either of these can be used to signal that an implementation is RFC 5746-compliant and can perform secure renegotiations. For more relevant technical discussions, see the IETF email discussion from November 2009 to February 2010.
RFC 5746 enables clients to send either an SCSV or RI in the
first ClientHello
. For maximum interoperability,
SunJSSE uses the SCSV by default, as a few TLS/SSL servers do not
handle unknown extensions correctly. The presence of the SCSV in
the enabled cipher suites
(SSLSocket.setEnabledCipherSuites()
or
SSLEngine.setEnabledCipherSuites()
) determines whether
the SCSV is sent in the initial ClientHello
, or if an
RI should be sent instead.
SSLv2 does not support SSL/TLS extensions. If the
SSLv2Hello
protocol is enabled, then the SCSV is sent
in the initial ClientHello
.
As previously mentioned, the Phase 1 Fix was to disable
renegotiations by default until a fix compliant with RFC 5746 could
be developed. Renegotiations could be reenabled by setting the
sun.security.ssl.allowUnsafeRenegotiation
system
property. The Phase 2 fix uses the same
sun.security.ssl.allowUnsafeRenegotiation
system
property, but also requires it to use RFC 5746 messages.
All applications should upgrade to the Phase 2 RFC 5746 fix as soon as possible.
Server certificate change in an SSL/TLS renegotiation may be unsafe:
Two certificates can be considered to represent the same identity:
Starting with JDK 8u25, unsafe server certificate change in
SSL/TLS renegotiations is not allowed by default. The new system
property jdk.tls.allowUnsafeServerCertChange
, can be
used to define whether unsafe server certificate change in an
SSL/TLS renegotiation should be restricted or not.
The default value of this system property is
"false"
.
Caution: DO NOT set the system property to
"true"
unless it is really necessary, as this would
re-establish the unsafe server certificate change
vulnerability.
The Java Cryptography Architecture (JCA) is a set of packages that provides a framework and implementations for encryption, key generation and key agreement, and message authentication code (MAC) algorithms. The SunJSSE provider uses JCA exclusively for all of its cryptographic operations and can automatically take advantage of JCE features and enhancements, including JCA's support for PKCS#11. This support enables the SunJSSE provider to use hardware cryptographic accelerators for significant performance improvements and to use smartcards as keystores for greater flexibility in key and trust management.
Use of hardware cryptographic accelerators is automatic if JCA has been configured to use the Oracle PKCS#11 provider, which in turn has been configured to use the underlying accelerator hardware. The provider must be configured before any other JCA providers in the provider list. For details on how to configure the Oracle PKCS#11 provider, see the PKCS#11 Guide.
Support for PKCS#11 in JCA also enables access to smartcards as
a keystore. For details on how to configure the type and location
of the keystores to be used by JSSE, see the Customizing JSSE section. To
use a smartcard as a keystore or truststore, set the
javax.net.ssl.keyStoreType
and
javax.net.ssl.trustStoreType
system properties,
respectively, to pkcs11
, and set the
javax.net.ssl.keyStore
and
javax.net.ssl.trustStore
system properties,
respectively, to NONE
. To specify the use of a
specific provider, use the
javax.net.ssl.keyStoreProvider
and
javax.net.ssl.trustStoreProvider
system properties
(for example, set them to SunPKCS11-joe
). By using
these properties, you can configure an application that previously
depended on these properties to access a file-based keystore to use
a smartcard keystore with no changes to the application.
Some applications request the use of keystores programmatically.
These applications can continue to use the existing APIs to
instantiate a Keystore
and pass it to its key manager
and trust manager. If the Keystore
instance refers to
a PKCS#11 keystore backed by a Smartcard, then the JSSE application
will have access to the keys on the smartcard.
smartcards (and other removable tokens) have additional
requirements for an X509KeyManager
. Different
smartcards can be present in a smartcard reader during the lifetime
of a Java application, and they can be protected using different
passwords.
The java.security.KeyStore.Builder
class abstracts the construction and initialization of a
KeyStore
object. It supports the use of
CallbackHandler
for password prompting, and its
subclasses can be used to support additional features as desired by
an application. For example, it is possible to implement a
Builder
that allows individual KeyStore
entries to be protected with different passwords. The
javax.net.ssl.KeyStoreBuilderParameters
class then can
be used to initialize a KeyManagerFactory using one or more of
these Builder
objects.
A X509KeyManager
implementation in the SunJSSE
provider called NewSunX509 supports these parameters. If multiple
certificates are available, it attempts to pick a certificate with
the appropriate key usage and prefers valid to expired
certificates.
The following example illustrates how to tell JSSE to use both a PKCS#11 keystore (which might in turn use a smartcard) and a PKCS#12 file-based keystore.
import javax.net.ssl.*; import java.security.KeyStore.*; ... // Specify keystore builder parameters for PKCS#11 keystores Builder scBuilder = Builder.newInstance("PKCS11", null, new CallbackHandlerProtection(myGuiCallbackHandler)); // Specify keystore builder parameters for a specific PKCS#12 keystore Builder fsBuilder = Builder.newInstance("PKCS12", null, new File(pkcsFileName), new PasswordProtection(pkcsKsPassword)); // Wrap them as key manager parameters ManagerFactoryParameters ksParams = new KeyStoreBuilderParameters( Arrays.asList(new Builder[] { scBuilder, fsBuilder }) ); // Create KeyManagerFactory KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509"); // Pass builder parameters to factory factory.init(ksParams); // Use factory SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(factory.getKeyManagers(), null, null);
The SunJSSE provider has support for Kerberos cipher suites, as described in RFC 2712. The following cipher suites are supported but not enabled by default:
To enable the use of these cipher suites, you must do so
explicitly. For more information, see the API documentation for the
SSLEngine.setEnabledCipherSuites()
and
SSLSocket.setEnabledCipherSuites()
methods. As
with all other SSL/TLS cipher suites, if a cipher suite is not
supported by the peer, then it will not be selected during cipher
negotiation. Furthermore, if the application and/or server cannot
acquire the necessary Kerberos credentials, then the Kerberos
cipher suites also will not be selected.
The following is an example of a TLS client that will only use
the TLS_KRB5_WITH_DES_CBC_SHA
cipher suite:
// Create socket SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(tlsServer, serverPort); // Enable only one cipher suite String enabledSuites[] = { "TLS_KRB5_WITH_DES_CBC_SHA" }; sslSocket.setEnabledCipherSuites(enabledSuites);
You must have the Kerberos infrastructure set up in your
deployment environment before you can use the Kerberos cipher
suites with JSSE. In particular, both the TLS client and server
must have accounts set up with the Kerberos Key Distribution Center
(KDC). At runtime, if one or more of the Kerberos cipher suites
have been enabled, then the TLS client and server will acquire
their Kerberos credentials associated with their respective account
from the KDC. For example, a TLS server running on the machine
mach1.imc.org
in the Kerberos realm
IMC.ORG
must have an account with the name
<EMAIL_ADDRESS>and be configured to use
the KDC for IMC.ORG
. For information about using
Kerberos with Java SE, see the Kerberos Requirements
document.
An application can acquire its Kerberos credentials by using the Java Authentication and Authorization Service (JAAS) and a Kerberos login module. The JDK comes with a Kerberos login module. You can use the Kerberos cipher suites with JSSE with or without JAAS programming, similar to how you can use the Java Generic Security Services (Java GSS) with or without JAAS programming.
To use the Kerberos cipher suites with JSSE without JAAS
programming, you must use the index names
com.sun.net.ssl.server
or other
for the
TLS server JAAS configuration entry, and
com.sun.net.ssl.client
or other
for the
TLS client, and set the
javax.security.auth.useSubjectCredsOnly
system
property to false. For example, a TLS server that is not using JAAS
programming might have the following JAAS configuration file:
com.sun.net.ssl.server { com.sun.security.auth.module.Krb5LoginModule required<EMAIL_ADDRESS>useKeyTab=true keyTab=mach1.keytab storeKey=true; };
An example of how to use Java GSS and Kerberos without JAAS programming is described in the Java GSS Tutorial. You can adapt it to use JSSE by replacing Java GSS calls with JSSE calls.
To use the Kerberos cipher suites with JAAS programming, you can
use any index name because your application is responsible for
creating the JAAS LoginContext
using the index name,
and then wrapping the JSSE calls inside of a
Subject.doAs()
or
Subject.doAsPrivileged()
call. An example of how to
use JAAS with Java GSS and Kerberos is described in the Java GSS Tutorial. You
can adapt it to use JSSE by replacing Java GSS calls with JSSE
calls.
If you have trouble using or configuring the JSSE application to use Kerberos, see the Troubleshooting section of the Java GSS Tutorial.
To determine the identity of the peer of an SSL connection, use
the getPeerPrincipal()
method in the following
classes:
javax.net.ssl.SSLSession
javax.net.ssl.HttpsURLConnection
javax.net.HandshakeCompletedEvent
Similarly, to get the identity that was sent to the peer (to
identify the local entity), use the
getLocalPrincipal()
method in these classes. For
X509-based cipher suites, these methods will return an instance of
javax.security.auth.x500.X500Principal
; for Kerberos
cipher suites, these methods will return an instance of
javax.security.auth.kerberos.KerberosPrincipal
.
JSSE applications use getPeerCertificates()
and
similar methods in javax.net.ssl.SSLSession
,
javax.net.ssl.HttpsURLConnection
, and
javax.net.HandshakeCompletedEvent
classes to obtain
information about the peer. When the peer does not have any
certificates, SSLPeerUnverifiedException
is
thrown.
If the application must determine only the identity of the peer
or identity sent to the peer, then it should use the
getPeerPrincipal()
and
getLocalPrincipal()
methods, respectively. It should
use getPeerCertificates()
and
getLocalCertificates()
methods only if it must examine
the contents of those certificates. Furthermore, the application
must be prepared to handle the case where an authenticated peer
might not have any certificate.
When the security manager has been enabled, in addition to the
SocketPermission
needed to communicate with the peer,
a TLS client application that uses the Kerberos cipher suites also
needs the following permission:
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "initiate");
In the preceding code, serverPrincipal is the Kerberos
principal name of the TLS server that the TLS client will be
communicating with (such as
<EMAIL_ADDRESS>). A TLS server application
needs the following permission:
javax.security.auth.kerberos.ServicePermission(serverPrincipal, "accept");
In the preceding code, serverPrincipal is the Kerberos
principal name of the TLS server (such as
<EMAIL_ADDRESS>). If the server or client
must contact the KDC (for example, if its credentials are not
cached locally), then it also needs the following permission:
javax.security.auth.kerberos.ServicePermission(tgtPrincipal, "initiate");In the preceding code, tgtPrincipal is the principal name of the KDC (such as
<EMAIL_ADDRESS>).
The PKCS#12 (Personal
Information Exchange Syntax Standard) specifies a portable
format for storage and/or transport of a user's private keys,
certificates, miscellaneous secrets, and other items. The SunJSSE
provider supplies a complete implementation of the PKCS12
java.security.KeyStore
format for reading and writing
PKCS12 files. This format is also supported by other toolkits and
applications for importing and exporting keys and certificates,
such as Netscape/Mozilla, Microsoft's Internet Explorer, and
OpenSSL. For example, these implementations can export client
certificates and keys into a file using the .p12 file name
extension.
With the SunJSSE provider, you can access PKCS12 keys through
the KeyStore
API with a keystore type of PKCS12. In
addition, you can list the installed keys and associated
certificates by using the keytool
command with the
-storetype
option set to pkcs12
. For more
information about keytool
, see Security Tools.
The SNI extension is a feature that extends the SSL/TLS
protocols to indicate what server name the client is attempting to
connect to during handshaking. Servers can use server name
indication information to decide if specific SSLSocket
or SSLEngine
instances should accept a connection. For
example, when multiple virtual or name-based servers are hosted on
a single underlying network address, the server application can use
SNI information to determine whether this server is the exact
server that the client wants to access. Instances of this class can
be used by a server to verify the acceptable server names of a
particular type, such as host names. For more information, see
section 3 of TLS
Extensions (RFC 6066).
Developers of client applications can explicitly set the server
name indication using the
SSLParameters.setServerNames(List<SNIServerName>
serverNames)
method. The following example illustrates this
functionality:
SSLSocketFactory factory = ... SSLSocket sslSocket = factory.createSocket("<IP_ADDRESS>", 443); // SSLEngine sslEngine = sslContext.createSSLEngine("<IP_ADDRESS>", 443); SNIHostName serverName = new SNIHostName("www.example.com"); List<SNIServerName> serverNames = new ArrayList<>(1); serverNames.add(serverName); SSLParameters params = sslSocket.getSSLParameters(); params.setServerNames(serverNames); sslSocket.setSSLParameters(params); // sslEngine.setSSLParameters(params);
Developers of server applications can use the
SNIMatcher
class to decide how to recognize server
name indication. The following two examples illustrate this
functionality:
Example 1
SSLSocket sslSocket = sslServerSocket.accept(); SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)"); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); SSLParameters params = sslSocket.getSSLParameters(); params.setSNIMatchers(matchers); sslSocket.setSSLParameters(params);
Example 2
SSLServerSocket sslServerSocket = ...; SNIMatcher matcher = SNIHostName.createSNIMatcher("www\\.example\\.(com|org)"); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); SSLParameters params = sslServerSocket.getSSLParameters(); params.setSNIMatchers(matchers); sslServerSocket.setSSLParameters(params); SSLSocket sslSocket = sslServerSocket.accept();
The following list provides examples for the behavior of the
SNIMatcher
when receiving various server name
indication requests in the ClientHello message:
Matcher configured to www\\.example\\.com
:
www.example.com
,
then it will be accepted and a confirmation will be sent in the
ServerHello message.www.example.org
,
then it will be rejected with an unrecognized_name
fatal error.Matcher configured to www\\.invalid\\.com
:
www.example.com
,
then it will be rejected with an unrecognized_name
fatal error.www.example.org
,
then it will be accepted and a confirmation will be sent in the
ServerHello message.Matcher is not configured:
Any requested host name will be accepted but no confirmation will be sent in the ServerHello message.
For descriptions of new classes that implement the SNI extension, see:
For examples, see Using the Server Name Indication (SNI) Extension.
This section contains information for troubleshooting JSSE. First, it provides some common configuration problems and ways to solve them, and then it describes helpful debugging utilities.
This section describes some common configuration problems that might arise when you use JSSE.
Problem: When negotiating an SSL connection, the client
or server throws a CertificateException
.
Cause 1: This is generally caused by the remote side sending a certificate that is unknown to the local side.
Solution 1: The best way to debug this type of problem is to turn on debugging (see Debugging Utilities) and watch as certificates are loaded and when certificates are received via the network connection. Most likely, the received certificate is unknown to the trust mechanism because the wrong trust file was loaded. Refer to the following sections for more information:
Cause 2: The system clock is not set correctly. In this case, the perceived time may be outside the validity period on one of the certificates, and unless the certificate can be replaced with a valid one from a truststore, the system must assume that the certificate is invalid, and therefore throw the exception.
Solution 2: Correct the system clock time.
Problem: Attempt to store trusted certificates in PKCS12
keystore throws java.security.KeyStoreException:
TrustedCertEntry not supported.
Cause: Storing trusted certificates in a PKCS12 keystore is not supported. PKCS12 is mainly used to deliver private keys with the associated certificate chains. It does not have any notion of "trusted" certificates. In terms of interoperability, other PKCS12 vendors have the same restriction. Browsers such as Mozilla and Internet Explorer do not accept a PKCS12 file with only trusted certificates.
Solution: Use the JKS keystore for storing trusted certificates.
Problem: When running a program that uses JSSE, an exception occurs indicating that an SSL service is not available. For example, an exception similar to one of the following is thrown:
Exception in thread "main" java.net.SocketException: no SSL Server Sockets Exception in thread "main": SSL implementation not available
Cause: There was a problem with SSLContext
initialization, for example, due to an incorrect password on a
keystore or a corrupted keystore (a JDK vendor once shipped a
keystore in an unknown format, and that caused this type of
error).
Solution: Check initialization parameters. Ensure that
any keystores specified are valid and that the passwords specified
are correct. One way that you can check this is by trying to use
the keytool
command-line utility to examine the keystores and the relevant
contents.
Problem: When trying to run a simple SSL server program, the following exception is thrown:
Exception in thread "main" javax.net.ssl.SSLException: No available certificate corresponding to the SSL cipher suites which are enabled...
Cause: Various cipher suites require certain types of key
material. For example, if an RSA cipher suite is enabled, then an
RSA keyEntry
must be available in the keystore. If no
such key is available, then this cipher suite cannot be used. This
exception is thrown if there are no available key entries for all
of the cipher suites enabled.
Solution: Create key entries for the various cipher suite types, or use an anonymous suite. Anonymous cipher suites are inherently dangerous because they are vulnerable to MITM (man-in-the-middle) attacks. For more information, see RFC 2246.
Refer to the following sections to learn how to pass the correct keystore and certificates:
Problem 1: When handshaking, the client and/or server throw this exception.
Cause 1: Both sides of an SSL connection must agree on a common cipher suite. If the intersection of the client's cipher suite set with the server's cipher suite set is empty, then you will see this exception.
Solution 1: Configure the enabled cipher suites to
include common cipher suites, and be sure to provide an appropriate
keyEntry
for asymmetric cipher suites. Also see
Runtime Exception: "No available
certificate..." in this section.)
Problem 2: When using Netscape Navigator or Microsoft Internet Explorer to access files on a server that only has DSA-based certificates, a runtime exception occurs indicating that there are no cipher suites in common.
Cause 2: By default, keyEntries
created with
keytool
use DSA public keys. If only DSA
keyEntries
exist in the keystore, then only DSA-based
cipher suites can be used. By default, Navigator and Internet
Explorer send only RSA-based cipher suites. Because the
intersection of client and server cipher suite sets is empty, this
exception is thrown.
Solution 2: To interact with Navigator or Internet
Explorer, you should create certificates that use RSA-based keys.
To do this, specify the -keyalg
RSA option when using
keytool. For example:
keytool -genkeypair -alias duke -keystore testkeys -keyalg rsa
Problem: JSSE seems to stall on first access.
Cause: JSSE must have a secure source of random numbers. The initialization takes a while.
Solution: Provide an alternative generator of random numbers, or initialize ahead of time when the overhead will not be noticed:
SecureRandom sr = new SecureRandom(); sr.nextInt(); SSLContext.init(..., ..., sr);
The java-home/lib/security/java.security file also
provides a way to specify the source of seed data for
SecureRandom
. See the contents of the file for more
information.
Problem: The following code snippet was written using
com.sun.net.ssl.HttpsURLConnection
in JSSE 1.0.x:
import com.sun.net.ssl.*; ...deleted... HttpsURLConnection urlc = new URL("https://example.com/").openConnection();
When running under JSSE 1.0.x, this code returns a
javax.net.ssl.HttpsURLConnection
object and throws a
ClassCastException
.
Cause: By default, opening an HTTPS URL will create a
javax.net.ssl.HttpsURLConnection
.
Solution: Previous releases of the JDK (release 6 and
earlier) did not ship with an HTTPS URL implementation. The JSSE
1.0.x implementation did provide such an HTTPS URL handler, and the
installation guide described how to set the URL handler search path
to obtain a JSSE 1.0.x
com.sun.net.ssl.HttpsURLConnection
implementation.
In the JDK, there is an HTTPS handler in the default URL handler
search path. It returns an instance of
javax.net.ssl.HttpsURLConnection
. By prepending the
old JSSE 1.0.x implementation path to the URL search path via the
java.protocol.handler.pkgs
variable, you can still
obtain a com.sun.net.ssl.HttpsURLConnection
, and the
code will no longer throw cast exceptions.
% java -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol YourClass
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
Problem: A socket attempts to connect, sends a ClientHello message, and is immediately disconnected.
Cause: Some SSL/TLS servers will disconnect if a ClientHello message is received in a format they do not understand or with a protocol version number that they do not support.
Solution: Try adjusting the enabled protocols on the client side. This involves modifying or invoking some of the following system properties and methods:
https.protocols
for the
HttpsURLConnection
classjdk.tls.client.protocols
SSLContext.getInstance
methodSSLEngine.setEnabledProtocols
methodSSLSocket.setEnabledProtocols
methodSSLParameters.setProtocols
and
SSLEngine.setSSLParameters
methodsSSLParameters.setProtocols
and
SSLSocket.setSSLParameters
methodsFor backwards compatibility, some SSL/TLS implementations (such as SunJSSE) can send SSL/TLS ClientHello messages encapsulated in the SSLv2 ClientHello format. The SunJSSE provider supports this feature. If you want to use this feature, add the "SSLv2Hello" protocol to the enabled protocol list, if necessary. (Also see the Protocols section, which lists the protocols that are enabled by default for the SunJSSE provider.)
The SSL/TLS RFC standards require that implementations negotiate to the latest version both sides speak, but some non-conforming implementation simply hang up if presented with a version they don't understand. For example, some older server implementations that speak only SSLv3 will shutdown if TLSv1.2 is requested. In this situation, consider using a SSL/TLS version fallback scheme:
For example, if the enabled protocol list on the client is TLSv1, TLSv1.1, and TLSv1.2, a typical SSL/TLS version fallback scheme may look like:
Note: A fallback to a previous version normally means security strength downgrading to a weaker protocol. It is not suggested to use a fallback scheme unless it is really necessary, and you clearly know that the server does not support a higher protocol version.
Note: As part of disabling SSLv3, some servers have also disabled SSLv2Hello, which means communications with SSLv2Hello-active clients (e.g. JDK 1.5/6) will fail. Starting with JDK 7, SSLv2Hello default to disabled on clients, enabled on servers.
Problem: A handshake is attempted and fails when it cannot find a required algorithm. Examples might include:
Exception in thread ...deleted... ...deleted... Caused by java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/PKCS1Paddingor
Caused by java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/NoPadding
Cause: SunJSSE uses JCE for all its cryptographic
algorithms. By default, the Oracle JDK will use the Standard
Extension ClassLoader to load the SunJCE provider located in
java-home/lib/ext/sunjce_provider.jar. If the file
cannot be found or loaded, or if the SunJCE provider has been
deregistered from the Provider
mechanism and an
alternative implementation from JCE is not available, then this
exception will be thrown.
Solution: Ensure that the SunJCE is available by checking
that the file is loadable and that the provider is registered with
the Provider
interface. Try to run the following code
in the context of your SSL connection:
import javax.crypto.*; System.out.println("=====Where did you get AES====="); Cipher c = Cipher.getInstance("AES/CBC/NoPadding"); System.out.println(c.getProvider());
Problem: If you receive a
com.sun.deploy.net.FailedDownloadException
when trying
to obtain application resources from your web server over SSL, and
your web server uses the virtual host with Server Name Indication
(SNI) extension (such as Apache HTTP Server), then you may have not
configured your web server correctly.
Cause: Because Java SE 7 supports the SNI extension in
the JSSE client, the requested host name of the virtual server is
included in the first message sent from the client to the server
during the SSL handshake. The server may deny the client's request
for a connection if the requested host name (the server name
indication) does not match the expected server name, which should
be specified in the virtual host's configuration. This triggers an
SSL handshake unrecognized name alert, which results in a
FailedDownloadException
being thrown.
Solution: To better diagnose the problem, enable tracing
through the Java Console. See Java Console, Tracing, and
Logging for more information. If the cause of the problem is
javax.net.ssl.SSLProtocolException: handshake alert:
unrecognized_name
, it is likely that the virtual host
configuration for SNI is incorrect. If you are using Apache HTTP
Server, see Name-based
Virtual Host Support for information about configuring virtual
hosts. In particular, ensure that the ServerName
directive is configured properly in a
<VirtualHost>
block.
For more information, see the following:
JSSE provides dynamic debug tracing support. This is similar to
the support used for debugging access control failures in the Java
SE platform. The generic Java dynamic debug tracing support is
accessed with the java.security.debug
system property,
whereas the JSSE-specific dynamic debug tracing support is accessed
with the javax.net.debug
system property.
Note: The debug
utility is not an
officially supported feature of JSSE.
To view the options of the JSSE dynamic debug utility, use the
following command-line option on the java
command:
-Djavax.net.debug=help
Note: If you specify the value
help
with either dynamic debug utility when running a
program that does not use any classes that the utility was designed
to debug, you will not get the debugging options.
The following complete example shows how to get a list of the
debug options for an application named MyApp
that uses
some of the JSSE classes:
java -Djavax.net.debug=help MyApp
The MyApp
application will not run after the debug
help information is printed, as the help code causes the
application to exit.
Current options are:
all
: Turn on all debuggingssl
: Turn on SSL debuggingThe following can be used with the ssl
option:
record
: Enable per-record tracinghandshake
: Print each handshake messagekeygen
: Print key generation datasession
: Print session activitydefaultctx
: Print default SSL initializationsslctx
: Print SSLContext
tracingsessioncache
: Print session cache tracingkeymanager
: Print key manager tracingtrustmanager
: Print trust manager tracingMessages generated from the handshake
option can be
widened with these options:
data
: Hex dump of each handshake messageverbose
: Verbose handshake message printingMessages generated from the record
option can be
widened with these options:
plaintext
: Hex dump of record plaintextpacket
: Print raw SSL/TLS packetsThe javax.net.debug
property value must be either
all
or ssl
, optionally followed by debug
specifiers. You can use one or more options. You do not have
to have a separator between options, although a separator such as a
colon (:) or a comma (,) helps readability. It does not matter what
separators you use, and the ordering of the option keywords is also
not important.
For an introduction to reading this debug information, see the guide, Debugging SSL/TLS Connections.
The following are examples of using the
javax.net.debug
property:
To view all debugging messages:
java -Djavax.net.debug=all MyApp
To view the hexadecimal dumps of each handshake message, enter the following (the colons are optional):
java -Djavax.net.debug=ssl:handshake:data MyApp
To view the hexadecimal dumps of each handshake message, and to print trust manager tracing, enter the following (the commas are optional):
java -Djavax.net.debug=SSL,handshake,data,trustmanager MyApp
The following code examples are included in this section:
This section provides examples of source code that illustrate how to use JSSE to convert an unsecure socket connection to a secure socket connection. The code in this section is excerpted from the book Java SE 6 Network Security by Marco Pistoia, et. al.
First, "Socket Example Without SSL" shows sample code that can be used to set up communication between a client and a server using unsecure sockets. This code is then modified in "Socket Example with SSL" to use JSSE to set up secure socket communication.
The following examples demonstrates server-side and client-side code for setting up an unsecure socket connection.
In a Java program that acts as a server and communicates with a client using sockets, the socket communication is set up with code similar to the following:
import java.io.*; import java.net.*; . . . int port = availablePortNumber; ServerSocket s; try { s = new ServerSocket(port); Socket c = s.accept(); OutputStream out = c.getOutputStream(); InputStream in = c.getInputStream(); // Send messages to the client through // the OutputStream // Receive messages from the client // through the InputStream } catch (IOException e) { }
The client code to set up communication with a server using sockets is similar to the following:
import java.io.*; import java.net.*; . . . int port = availablePortNumber; String host = "hostname"; try { s = new Socket(host, port); OutputStream out = s.getOutputStream(); InputStream in = s.getInputStream(); // Send messages to the server through // the OutputStream // Receive messages from the server // through the InputStream } catch (IOException e) { }
The following examples demonstrate server-side and client-side code for setting up a secure socket connection.
In a Java program that acts as a server and communicates with a client using secure sockets, the socket communication is set up with code similar to the following. Differences between this program and the one for communication using unsecure sockets are highlighted in bold.
import java.io.*; import javax.net.ssl.*; . . . int port = availablePortNumber; SSLServerSocket s; try { SSLServerSocketFactory sslSrvFact = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); s = (SSLServerSocket)sslSrvFact.createServerSocket(port); SSLSocket c = (SSLSocket)s.accept(); OutputStream out = c.getOutputStream(); InputStream in = c.getInputStream(); // Send messages to the client through // the OutputStream // Receive messages from the client // through the InputStream } catch (IOException e) { }
The client code to set up communication with a server using secure sockets is similar to the following, where differences with the unsecure version are highlighted in bold:
import java.io.*; import javax.net.ssl.*; . . . int port = availablePortNumber; String host = "hostname"; try { SSLSocketFactory sslFact = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket s = (SSLSocket)sslFact.createSocket(host, port); OutputStream out = s.getOutputStream(); InputStream in = s.getInputStream(); // Send messages to the server through // the OutputStream // Receive messages from the server // through the InputStream } catch (IOException e) { }
The JSSE sample programs illustrate how to use JSSE to:
When you use the sample code, be aware that the sample programs are designed to illustrate how to use JSSE. They are not designed to be robust applications.
Note: Setting up secure communications involves
complex algorithms. The sample programs provide no feedback during
the setup process. When you run the programs, be patient: you may
not see any output for a while. If you run the programs with the
javax.net.debug
system property set to
all
, you will see more feedback. For an introduction
to reading this debug information, see the guide, Debugging SSL/TLS Connections.
Most of the sample code is located in the samples subdirectory of the same directory as that containing the document you are reading. Follow that link to see a listing of all the sample code files and text files. That page also provides a link to a ZIP file that you can download to obtain all the sample code files, which is helpful if you are viewing this documentation from the web.
The following sections describe the samples. For more information, see README.txt.
The sample programs in the samples/sockets
directory illustrate how to set up a secure socket connection
between a client and a server.
When running the sample client programs, you can communicate
with an existing server, such as a commercial web server, or you
can communicate with the sample server program,
ClassFileServer
. You can run the sample client and the
sample server programs on different machines connected to the same
network, or you can run them both on one machine but from different
terminal windows.
All the sample SSLSocketClient*
programs in the
samples/sockets/client directory (and URLReader*
programs described in Sample Code
Illustrating HTTPS Connections) can be run with the
ClassFileServer
sample server program. An example of
how to do this is shown in Running
SSLSocketClientWithClientAuth with ClassFileServer. You can
make similar changes to run URLReader
,
SSLSocketClient
, or
SSLSocketClientWithTunneling
with
ClassFileServer
.
If an authentication error occurs during communication between
the client and the server (whether using a web server or
ClassFileServer
), it is most likely because the
necessary keys are not in the truststore
(trust key database). For example, the ClassFileServer
uses a keystore called testkeys
containing the private
key for localhost
as needed during the SSL handshake.
The testkeys
keystore is included in the same
samples/sockets/server directory as the
ClassFileServer
source. If the client cannot find a
certificate for the corresponding public key of
localhost
in the truststore it consults, then an
authentication error will occur. Be sure to use the
samplecacerts
truststore (which contains the public
key and certificate of the localhost
), as described in
the next section.
When running the sample programs that create a secure socket
connection between a client and a server, you will need to make the
appropriate certificates file (truststore) available. For both the
client and the server programs, you should use the certificates
file samplecacerts
from the samples
directory. Using this certificates file will allow the client to
authenticate the server. The file contains all the common
Certificate Authority (CA) certificates shipped with the JDK (in
the cacerts file), plus a certificate for localhost
needed by the client to authenticate localhost
when
communicating with the sample server ClassFileServer
.
The ClassFileServer
uses a keystore containing the
private key for localhost
that corresponds to the
public key in samplecacerts
.
To make the samplecacerts
file available to both
the client and the server, you can either copy it to the file
java-home/lib/security/jssecacerts, rename it to
cacerts, and use it to replace the
java-home/lib/security/cacerts file, or add the
following option to the command line when running the
java
command for both the client and the server:
-Djavax.net.ssl.trustStore=path_to_samplecacerts_file
For more information about java-home, see The JRE Installation Directory.
The password for the samplecacerts
truststore is
changeit
. You can substitute your own certificates in
the samples by using the keytool
utility.
If you use a browser, such as Netscape Navigator or Microsoft's
Internet Explorer, to access the sample SSL server provided in the
ClassFileServer
example, then a dialog box may pop up
with the message that it does not recognize the certificate. This
is normal because the certificate used with the sample programs is
self-signed and is for testing only. You can accept the certificate
for the current session. After testing the SSL server, you should
exit the browser, which deletes the test certificate from the
browser's namespace.
For client authentication, a separate duke
certificate is available in the appropriate directories. The public
key and certificate is also stored in the
samplecacerts
file.
The SSLSocketClient.java
program demonstrates how to create a client that uses an
SSLSocket
to send an HTTP request and to get a
response from an HTTPS server. The output of this program is the
HTML source for
https://www.verisign.com/index.html
.
You must not be behind a firewall to run this program as
provided. If you run it from behind a firewall, you will get an
UnknownHostException
because JSSE cannot find a path
through your firewall to www.verisign.com
. To create
an equivalent client that can run from behind a firewall, set up
proxy tunneling as illustrated in the sample program
SSLSocketClientWithTunneling
.
The SSLSocketClientWithTunneling.java program illustrates how to do proxy tunneling to access a secure web server from behind a firewall. To run this program, you must set the following Java system properties to the appropriate values:
java -Dhttps.proxyHost=webproxy -Dhttps.proxyPort=ProxyPortNumber SSLSocketClientWithTunneling
Note: Proxy specifications with the
-D
options are optional. Replace webproxy with
the name of your proxy host and ProxyPortNumber with the
appropriate port number.
The program will return the HTML source file from
https://www.verisign.com/index.html
.
The SSLSocketClientWithClientAuth.java
program shows how to set up a key manager to do client
authentication if required by a server. This program also assumes
that the client is not outside a firewall. You can modify the
program to connect from inside a firewall by following the example
in SSLSocketClientWithTunneling
.
To run this program, you must specify three parameters: host,
port, and requested file path. To mirror the previous examples, you
can run this program without client authentication by setting the
host to www.verisign.com
, the port to
443
, and the requested file path to
https://www.verisign.com/
. The output when using these
parameters is the HTML for the website
https://www.verisign.com/
.
To run SSLSocketClientWithClientAuth
to do client
authentication, you must access a server that requests client
authentication. You can use the sample program
ClassFileServer
as this server. This is described in
the following sections.
The program referred to herein as ClassFileServer
is made up of two files: ClassFileServer.java
and ClassServer.java.
To execute them, run ClassFileServer.class
, which
requires the following parameters:
port
can be any available unused port number, for
example, you can use the number 2001
.docroot
indicates the directory on the server that
contains the file you want to retrieve. For example, on Solaris,
you can use /home/userid/ (where userid refers to
your particular UID), whereas on Microsoft Windows systems, you can
use c:\.TLS
is an optional parameter that indicates that
the server is to use SSL or TLS.true
is an optional parameter that indicates that
client authentication is required. This parameter is only consulted
if the TLS parameter is set.Note: The TLS
and
true
parameters are optional. If you omit them,
indicating that an ordinary (not TLS) file server should be used,
without authentication, then nothing happens. This is because one
side (the client) is trying to negotiate with TLS, while the other
(the server) is not, so they cannot communicate.
Note: The server expects GET requests in the
form GET /path_to_file
.
You can use the sample programs SSLSocketClientWithClientAuth
and ClassFileServer
to set up authenticated
communication, where the client and server are authenticated to
each other. You can run both sample programs on different machines
connected to the same network, or you can run them both on one
machine but from different terminal windows or command prompt
windows. To set up both the client and the server, do the
following:
ClassFileServer
from one machine
or terminal window, as described in Running
ClassFileServer.SSLSocketClientWithClientAuth
on
another machine or terminal window.
SSLSocketClientWithClientAuth
requires the following
parameters:
host
is the host name of the machine that you are
using to run ClassFileServer
.port
is the same port that you specified for
ClassFileServer
.requestedfilepath
indicates the path to the file
that you want to retrieve from the server. You must give this
parameter as /filepath
. Forward slashes are required
in the file path because it is used as part of a GET statement,
which requires forward slashes regardless of what type of operating
system you are running. The statement is formed as follows:
"GET " + requestedfilepath + " HTTP/1.0"
Note: You can modify the other
SSLClient*
applications' GET
commands to
connect to a local machine running
ClassFileServer
.
There are two primary APIs for accessing secure communications
through JSSE. One way is through a socket-level API that can be
used for arbitrary secure communications, as illustrated by the
SSLSocketClient
,
SSLSocketClientWithTunneling
, and
SSLSocketClientWithClientAuth
(with and without
ClassFileServer
) sample programs.
A second, and often simpler, way is through the standard Java
URL API. You can communicate securely with an SSL-enabled web
server by using the HTTPS URL protocol or scheme using the
java.net.URL
class.
Support for HTTPS URL schemes is implemented in many of the common browsers, which allows access to secured communications without requiring the socket-level API provided with JSSE.
An example URL is https://www.verisign.com
.
The trust and key management for the HTTPS URL implementation is
environment-specific. The JSSE implementation provides an HTTPS URL
implementation. To use a different HTTPS protocol implementation,
set the java.protocol.handler.pkgs
system property to the package name. See the
java.net.URL
class documentation for details.
The samples that you can download with JSSE include two sample
programs that illustrate how to create an HTTPS connection. Both of
these sample programs (URLReader.java
and
URLReaderWithOptions.java
)
are in the samples/urls directory.
The URLReader.java
program illustrates using the URL class to access a secure site.
The output of this program is the HTML source for
https://www.verisign.com/
. By default, the HTTPS
protocol implementation included with JSSE is used. To use a
different implementation, set the system property
java.protocol.handler.pkgs
value to be the name of the
package containing the implementation.
If you are running the sample code behind a firewall, then you
must set the https.proxyHost
and
https.proxyPort
system properties. For example, to use
the proxy host "webproxy" on port 8080, you can use the following
options for the java
command:
-Dhttps.proxyHost=webproxy -Dhttps.proxyPort=8080
Alternatively, you can set the system properties within the
source code with the java.lang.System
method
setProperty()
. For example, instead of using the
command-line options, you can include the following lines in your
program:
System.setProperty("java.protocol.handler.pkgs", "com.ABC.myhttpsprotocol"); System.setProperty("https.proxyHost", "webproxy"); System.setProperty("https.proxyPort", "8080");
The URLReaderWithOptions.java program is essentially the same as the URLReader.java program, except that it allows you to optionally input any or all of the following system properties as arguments to the program when you run it:
java.protocol.handler.pkgs
https.proxyHost
https.proxyPort
https.cipherSuites
To run URLReaderWithOptions
, enter the following
command:
java URLReaderWithOptions [-h proxyhost -p proxyport] [-k protocolhandlerpkgs] [-c ciphersarray]
Note: Multiple protocol handlers can be
included in the protocolhandlerpkgs
argument as a list
with items separated by vertical bars. Multiple SSL cipher suite
names can be included in the ciphersarray
argument as
a list with items separated by commas. The possible cipher suite
names are the same as those returned by the
SSLSocket.getSupportedCipherSuites()
method. The suite
names are taken from the SSL and TLS protocol specifications.
You need a protocolhandlerpkgs
argument only if you
want to use an HTTPS protocol handler implementation other than the
default one provided by Oracle.
If you are running the sample code behind a firewall, then you must include arguments for the proxy host and the proxy port. Additionally, you can include a list of cipher suites to enable.
Here is an example of running URLReaderWithOptions
and specifying the proxy host "webproxy" on port 8080:
java URLReaderWithOptions -h webproxy -p 8080
The sample code in the samples/rmi directory illustrates how to create a secure Java Remote Method Invocation (RMI) connection. The sample code is based on an RMI example that is basically a "Hello World" example modified to install and use a custom RMI socket factory.
For more information about Java RMI, see the Java RMI documentation. This web page points to Java RMI tutorials and other information about Java RMI.
SSLEngine
gives application developers flexibility
when choosing I/O and compute strategies. Rather than tie the
SSL/TLS implementation to a specific I/O abstraction (such as
single-threaded SSLSockets
), SSLEngine
removes the I/O and compute constraints from the SSL/TLS
implementation.
As mentioned earlier, SSLEngine
is an advanced API,
and is not appropriate for casual use. Some introductory sample
code is provided here that helps illustrate its use. The first demo
removes most of the I/O and threading issues, and focuses on many
of the SSLEngine methods. The second demo is a more realistic
example showing how SSLEngine
might be combined with
Java NIO to create a rudimentary HTTP/HTTPS server.
The SSLEngineSimpleDemo
is a very simple application that focuses on the operation of the
SSLEngine
while simplifying the I/O and threading
issues. This application creates two SSLEngine
objects
that exchange SSL/TLS messages via common ByteBuffer
objects. A single loop serially performs all of the engine
operations and demonstrates how a secure connection is established
(handshaking), how application data is transferred, and how the
engine is closed.
The SSLEngineResult
provides a great deal of
information about the current state of the SSLEngine
.
This example does not examine all of the states. It simplifies the
I/O and threading issues to the point that this is not a good
example for a production environment; nonetheless, it is useful to
demonstrate the overall function of the SSLEngine
.
To fully exploit the flexibility provided by
SSLEngine
, you must first understand complementary
APIs, such as I/O and threading models.
An I/O model that large-scale application developers find of use
is the NIO SocketChannel
. NIO was introduced in part
to solve some of the scaling problem inherent in the
java.net.Socket
API. SocketChannel
has
many different modes of operation including:
Sample code for a basic HTTP server is provided that not only
demonstrates many of the new NIO APIs, but also shows how
SSLEngine
can be employed to create a secure HTTPS
server. The server is not production quality, but does show many of
these new APIs in action.
Inside the samples directory is a README.txt file that
introduces the server, explains how to build and configure the
server, and provides a brief overview of the code layout. The files
of most interest for SSLEngine
users are
ChannelIO.java
and
ChannelIOSecure.java
.
Note: The server example discussed in this section is included in the JDK. You can find the code bundled in the jdk-home/samples/nio/server directory.
This section demonstrates how you can use the
keytool
utility to create a simple JKS keystore
suitable for use with JSSE. First you make a keyEntry
(with public and private keys) in the keystore, and then you make a
corresponding trustedCertEntry
(public keys only) in a
truststore. For client authentication, you follow a similar process
for the client's certificates.
Note: Storing trust anchors and secret keys in PKCS12 is supported since JDK 8.
Note: It is beyond the scope of this example to
explain each step in detail. For more information, see the
keytool
documentation for Solaris, Linux, or Mac OS X
or Microsoft
Windows.
User input is shown in bold.
Create a new keystore and self-signed certificate with corresponding public and private keys.
% keytool -genkeypair -alias duke -keyalg RSA -validity 7 -keystore keystore Enter keystore password: password What is your first and last name? [Unknown]: Duke What is the name of your organizational unit? [Unknown]: Java Software What is the name of your organization? [Unknown]: Oracle, Inc. What is the name of your City or Locality? [Unknown]: Palo Alto What is the name of your State or Province? [Unknown]: CA What is the two-letter country code for this unit? [Unknown]: US Is CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US correct? [no]: yes Enter key password for <duke> (RETURN if same as keystore password): <CR>
Examine the keystore. Notice that the entry type is
keyEntry
, which means that this entry has a private
key associated with it).
% keytool -list -v -keystore keystore Enter keystore password: password Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry Alias name: duke Creation date: Dec 20, 2001 Entry type: keyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Serial number: 3c22adc1 Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001 Certificate fingerprints: MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0 SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
Export and examine the self-signed certificate.
% keytool -export -alias duke -keystore keystore -rfc -file duke.cer Enter keystore password: password Certificate stored in file <duke.cer> % cat duke.cer -----BEGIN CERTIFICATE----- MIICXjCCAccCBDwircEwDQYJKoZIhvcNAQEEBQAwdjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB MRIwEAYDVQQHEwlQYWxvIEFsdG8xHzAdBgNVBAoTFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xFjAU BgNVBAsTDUphdmEgU29mdHdhcmUxDTALBgNVBAMTBER1a2UwHhcNMDExMjIxMDMzNDI1WhcNMDEx MjI4MDMzNDI1WjB2MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVBhbG8gQWx0 bzEfMB0GA1UEChMWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEWMBQGA1UECxMNSmF2YSBTb2Z0d2Fy ZTENMAsGA1UEAxMERHVrZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1loObJzNXsi5aSr8 N4XzDksD6GjTHFeqG9DUFXKEOQetfYXvA8F9uWtz8WInrqskLTNzwXgmNeWkoM7mrPpK6Rf5M3G1 NXtYzvxyi473Gh1h9k7tjJvqSVKO7E1oFkQYeUPYifxmjbSMVirWZgvo2UmA1c76oNK+NhoHJ4qj eCUCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCRPoQYw9rWWvfLPQuPXowvFmuebsTc28qI7iFWm6BJ TT/qdmzti7B5MHOt9BeVEft3mMeBU0CS2guaBjDpGlf+zsK/UUi1w9C4mnwGDZzqY/NKKWtLxabZ 5M+4MAKLZ92ePPKGpobM2CPLfM8ap4IgAzCbBKd8+CMp8yFmifze9Q== -----END CERTIFICATE-----
Alternatively, you could generate a Certificate Signing Request
(CSR) with -certreq
and send that to a Certificate
Authority (CA) for signing, but that is beyond the scope of this
example.
Import the certificate into a new truststore.
% keytool -import -alias dukecert -file duke.cer -keystore truststore Enter keystore password: trustword Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Serial number: 3c22adc1 Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001 Certificate fingerprints: MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0 SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74 Trust this certificate? [no]: yes Certificate was added to keystore
Examine the truststore. Note that the entry type is
trustedCertEntry
, which means that a private key is
not available for this entry. It also means that this file is not
suitable as a keystore of the KeyManager
.
% keytool -list -v -keystore truststore Enter keystore password: trustword Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry Alias name: dukecert Creation date: Dec 20, 2001 Entry type: trustedCertEntry Owner: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Issuer: CN=Duke, OU=Java Software, O="Oracle, Inc.", L=Palo Alto, ST=CA, C=US Serial number: 3c22adc1 Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001 Certificate fingerprints: MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0 SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74
Now run your applications with the appropriate keystores.
Because this example assumes that the default
X509KeyManager
and X509TrustManager
are
used, you select the keystores using the system properties
described in Customizing
JSSE.
% java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password Server % java -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=trustword Client
Note: This example authenticated the server only. For client authentication, provide a similar keystore for the client's keys and an appropriate truststore for the server.
This section provides code examples that illustrate how you can use the Server Name Indication (SNI) extension for client-side and server-side applications, and how it can be applied to a virtual infrastructure.
For all examples in this section, to apply the parameters after
you set them, call the setSSLParameters(SSLParameters)
method on the corresponding SSLSocket
,
SSLEngine
, or SSLServerSocket
object.
The following is a list of use cases that require understanding of the SNI extension for developing a client application:
Case 1. The client wants to access
www.example.com
.
Set the host name explicitly:
SNIHostName serverName = new SNIHostName("www.example.com"); List<SNIServerName> serverNames = new ArrayList<>(1); serverNames.add(serverName); sslParameters.setServerNames(serverNames);
The client should always specify the host name explicitly.
Case 2. The client does not want to use SNI because the server does not support it.
Disable SNI with an empty server name list:
List<SNIServerName> serverNames = new ArrayList<>(1); sslParameters.setServerNames(serverNames);
Case 3. The client wants to access URL
https://www.example.com
.
Oracle providers will set the host name in the SNI extension by default, but third-party providers may not support the default server name indication. To keep your application provider-independent, always set the host name explicitly.
Case 4. The client wants to switch a socket from server mode to client mode.
First switch the mode with the following method:
sslSocket.setUseClientMode(true)
. Then reset the
server name indication parameters on the socket.
The following is a list of use cases that require understanding of the SNI extension for developing a server application:
Case 1. The server wants to accept all server name indication types.
If you do not have any code dealing with the SNI extension, then the server ignores all server name indication types.
Case 2. The server wants to deny all server name indications
of type host_name
.
Set an invalid server name pattern for
host_name
:
SNIMatcher matcher = SNIHostName.createSNIMatcher(""); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); sslParameters.setSNIMatchers(matchers);
Another way is to create an SNIMatcher
subclass
with a matches()
method that always returns
false
:
class DenialSNIMatcher extends SNIMatcher { DenialSNIMatcher() { super(StandardConstants.SNI_HOST_NAME); } @Override public boolean matches(SNIServerName serverName) { return false; } } SNIMatcher matcher = new DenialSNIMatcher(); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); sslParameters.setSNIMatchers(matchers);
Case 3. The server wants to accept connections to any host
names in the example.com
domain.
Set the recognizable server name for host_name
as a
pattern that includes all *.example.com
addresses:
SNIMatcher matcher = SNIHostName.createSNIMatcher("(.*\\.)*example\\.com"); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); sslParameters.setSNIMatchers(matchers);
Case 4. The server wants to switch a socket from client mode to server mode.
First switch the mode with the following method:
sslSocket.setUseClientMode(false)
. Then reset the
server name indication parameters on the socket.
This section describes how to use the Server Name Indication
(SNI) extension from within a virtual infrastructure. It
illustrates how to create a parser for ClientHello messages from a
socket, provides examples of virtual server dispatchers using
SSLSocket
and SSLEngine
, describes what
happens when the SNI extension is not available, and demonstrates
how to create a failover SSLContext
.
Applications must implement an API to parse the ClientHello
messages from a socket. The following examples illustrate the
SSLCapabilities
and SSLExplorer
classes
that can perform these functions.
SSLCapabilities.java
encapsulates the SSL/TLS security capabilities during handshaking
(that is, the list of cipher suites to be accepted in an SSL/TLS
handshake, the record version, the hello version, and the server
name indication). It can be retrieved by exploring the network data
of an SSL/TLS connection via the SSLExplorer.explore()
method.
SSLExplorer.java
explores the initial ClientHello message from a TLS client, but it
does not initiate handshaking or consume network data. The
SSLExplorer.explore()
method parses the ClientHello
message, and retrieves the security parameters into
SSLCapabilities
. The method must be called before
handshaking occurs on any TLS connections.
This section describes the procedure for using a virtual server
dispatcher based on SSLSocket
.
Register the server name handler.
At this step, the application may create different
SSLContext
objects for different server name
indications, or link a certain server name indication to a
specified virtual machine or distributed system.
For example, if the server name is www.example.org
,
then the registered server name handler may be for a local virtual
hosting web service. The local virtual hosting web service will use
the specified SSLContext
. If the server name is
www.example.com
, then the registered server name
handler may be for a virtual machine hosting on
<IP_ADDRESS>
. The handler may map this connection to the
virtual machine.
Create a ServerSocket
and accept the new
connection.
ServerSocket serverSocket = new ServerSocket(serverPort); Socket socket = serverSocket.accept();
Read and buffer bytes from the socket input stream, and then explore the buffered bytes.
InputStream ins = socket.getInputStream(); byte[] buffer = new byte[0xFF]; int position = 0; SSLCapabilities capabilities = null; // Read the header of TLS record while (position < SSLExplorer.RECORD_HEADER_SIZE) { int count = SSLExplorer.RECORD_HEADER_SIZE - position; int n = ins.read(buffer, position, count); if (n < 0) { throw new Exception("unexpected end of stream!"); } position += n; } // Get the required size to explore the SSL capabilities int recordLength = SSLExplorer.getRequiredSize(buffer, 0, position); if (buffer.length < recordLength) { buffer = Arrays.copyOf(buffer, recordLength); } while (position < recordLength) { int count = recordLength - position; int n = ins.read(buffer, position, count); if (n < 0) { throw new Exception("unexpected end of stream!"); } position += n; } // Explore capabilities = SSLExplorer.explore(buffer, 0, recordLength); if (capabilities != null) { System.out.println("Record version: " + capabilities.getRecordVersion()); System.out.println("Hello version: " + capabilities.getHelloVersion()); }
Get the requested server name from the explored capabilities.
List<SNIServerName> serverNames = capabilities.getServerNames();
Look for the registered server name handler for this server name indication.
If the service of the host name is resident in a virtual machine or another distributed system, then the application must forward the connection to the destination. The application will need to read and write the raw internet data, rather then the SSL application from the socket stream.
Socket destinationSocket = new Socket(serverName, 443);
// Forward buffered bytes and network data from the current socket to the destinationSocket
.
If the service of the host name is resident in the same process,
and the host name service can use the SSLSocket
directly, then the application will need to set the
SSLSocket
instance to the server:
// Get service context from registered handler // or create the context SSLContext serviceContext = ... SSLSocketFactory serviceSocketFac = serviceContext.getSSLSocketFactory(); // wrap the buffered bytes ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, position); SSLSocket serviceSocket = (SSLSocket)serviceSocketFac.createSocket(socket, bais, true); // Now the service can use serviceSocket as usual.
This section describes the procedure for using a virtual server
dispatcher based on SSLEngine
.
Register the server name handler.
At this step, the application may create different
SSLContext
objects for different server name
indications, or link a certain server name indication to a
specified virtual machine or distributed system.
For example, if the server name is www.example.org
,
then the registered server name handler may be for a local virtual
hosting web service. The local virtual hosting web service will use
the specified SSLContext
. If the server name is
www.example.com
, then the registered server name
handler may be for a virtual machine hosting on
<IP_ADDRESS>
. The handler may map this connection to the
virtual machine.
Create a ServerSocket
or
ServerSocketChannel
and accept the new
connection.
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(...); ... SocketChannel socketChannel = serverSocketChannel.accept();
Read and buffer bytes from the socket input stream, and then explore the buffered bytes.
ByteBuffer buffer = ByteBuffer.allocate(0xFF); SSLCapabilities capabilities = null; while (true) { // ensure the capacity if (buffer.remaining() == 0) { ByteBuffer oldBuffer = buffer; buffer = ByteBuffer.allocate(buffer.capacity() + 0xFF); buffer.put(oldBuffer); } int n = sc.read(buffer); if (n < 0) { throw new Exception("unexpected end of stream!"); } int position = buffer.position(); buffer.flip(); capabilities = explorer.explore(buffer); buffer.rewind(); buffer.position(position); buffer.limit(buffer.capacity()); if (capabilities != null) { System.out.println("Record version: " + capabilities.getRecordVersion()); System.out.println("Hello version: " + capabilities.getHelloVersion()); break; } } buffer.flip(); // reset the buffer position and limitation
Get the requested server name from the explored capabilities.
List<SNIServerName> serverNames = capabilities.getServerNames();
Look for the registered server name handler for this server name indication.
If the service of the host name is resident in a virtual machine or another distributed system, then the application must forward the connection to the destination. The application will need to read and write the raw internet data, rather then the SSL application from the socket stream.
Socket destinationSocket = new Socket(serverName, 443);
// Forward buffered bytes and network data from the current socket to the destinationSocket
.
If the service of the host name is resident in the same process,
and the host name service can use the SSLEngine
directly, then the application will simply feed the net data to the
SSLEngine
instance:
// Get service context from registered handler // or create the context SSLContext serviceContext = ... SSLEngine serviceEngine = serviceContext.createSSLEngine(); // Now the service can use the buffered bytes and other byte buffer as usual.
If there is no server name indication in a ClientHello message, then there is no way to select the proper service according to SNI. For such cases, the application may need to specify a default service, so that the connection can be delegated to it if there is no server name indication.
The SSLExplorer.explore()
method does not check the
validity of SSL/TLS contents. If the record format does not comply
with SSL/TLS specification, or the explore()
method is
invoked after handshaking has started, then the method may throw an
IOException
and be unable to produce network data. In
such cases, handle the exception thrown by
SSLExplorer.explore()
by using a failover
SSLContext
, which is not used to negotiate an SSL/TLS
connection, but to close the connection with the proper alert
message. The following example illustrates a failover
SSLContext
. You can find an example of the
DenialSNIMatcher
class in Case 2 of the Typical Server-Side Usage Examples.
byte[] buffer = ... // buffered network data boolean failed = true; // SSLExplorer.explore() throws an exception SSLContext context = SSLContext.getInstance("TLS"); // the failover SSLContext context.init(null, null, null); SSLSocketFactory sslsf = context.getSocketFactory(); ByteArrayInputStream bais = new ByteArrayInputStream(buffer, 0, position); SSLSocket sslSocket = (SSLSocket)sslsf.createSocket(socket, bais, true); SNIMatcher matcher = new DenialSNIMatcher(); Collection<SNIMatcher> matchers = new ArrayList<>(1); matchers.add(matcher); SSLParameters params = sslSocket.getSSLParameters(); params.setSNIMatchers(matchers); // no recognizable server name sslSocket.setSSLParameters(params); try { InputStream sslIS = sslSocket.getInputStream(); sslIS.read(); } catch (Exception e) { System.out.println("Server exception " + e); } finally { sslSocket.close(); }
The JDK Security API requires and uses a set of standard names for algorithms, certificates and keystore types. The specification names previously found here in Appendix A and in the other security specifications (JCA, CertPath) have been combined in the Standard Names document. Specific provider information can be found in the Oracle Provider Documentation.
JSSE is fully pluggable and does not restrict the use of third-party JSSE providers in any way.


| Server |
Description/ Example |
| Cuteflow Server |
The http-URL under that the application can be reached (i.e. http://<IP_ADDRESS>/cuteflow/).
|
After this period the Circulation will be send to the substitute person |
4 Days |
| System reply address |
the system reply address which is shown in the recievers e-mail |
| Standard for "Description text" |
You can enter a default description text for your circulations here |
| SMTP: Server |
Your E-Mail Server (i.e. IP-Adress or url) |
| SMTP: Port |
Port for SMTP on the server (likely: 25) |
| SMTP: User ID |
The user id if you use authentificate smtp (Account name) |
| SMTP: Password |
The password if you use authentificate smtp |
| SMTP: Use Authentification? |
Aktivate here if your email server uses Authentification for the SMTP
Protokoll. If aktivated, you have to provide the user id and
password (see above)
|
|
| GUI |
|
| Default language |
Choose your language here |
| Circulations default sort |
|
| Open details in seperate Window? |
Activate to show Circulation Details in a seperate Window |
| Show position in mail? |
Activate to show the position of a circulation in E-Mails |
| Filter auto regex wordstart? |
|
| EMail format |
The format for the E-Mails, either TEXT or HTML. Also you can
change the Mail's content (browserlink, only values, IFrame)
"HTML and IFrame" is the default - it's the format you
know from earlier Cuteflow Versions
|
| Default columns order (in Circulations) |
Change the order of the circulation's columns |
|
| Color of "Days in Progress" changes to... |
|
| xyz after ... days |
Change the period after which the color changes from yellow
over orange to red
|