use of javax.net.ssl.SSLProtocolException in project service-proxy by membrane.
the class SSLExplorer method exploreSNIExt.
/*
* struct {
* NameType name_type;
* select (name_type) {
* case host_name: HostName;
* } name;
* } ServerName;
*
* enum {
* host_name(0), (255)
* } NameType;
*
* opaque HostName<1..2^16-1>;
*
* struct {
* ServerName server_name_list<1..2^16-1>
* } ServerNameList;
*/
private static List<SNIServerName> exploreSNIExt(ByteBuffer input, int extLen) throws IOException {
Map<Integer, SNIServerName> sniMap = new LinkedHashMap<Integer, SNIServerName>();
int remains = extLen;
if (extLen >= 2) {
// "server_name" extension in ClientHello
// length of server_name_list
int listLen = getInt16(input);
if (listLen == 0 || listLen + 2 != extLen) {
throw new SSLProtocolException("Invalid server name indication extension");
}
// 0x02: the length field of server_name_list
remains -= 2;
while (remains > 0) {
// name_type
int code = getInt8(input);
// length field of server name
int snLen = getInt16(input);
if (snLen > remains) {
throw new SSLProtocolException("Not enough data to fill declared vector size");
}
byte[] encoded = new byte[snLen];
input.get(encoded);
SNIServerName serverName;
switch(code) {
case StandardConstants.SNI_HOST_NAME:
if (encoded.length == 0) {
throw new SSLProtocolException("Empty HostName in server name indication");
}
serverName = new SNIHostName(encoded);
break;
default:
serverName = new UnknownServerName(code, encoded);
}
// check for duplicated server name type
if (sniMap.put(serverName.getType(), serverName) != null) {
throw new SSLProtocolException("Duplicated server name of type " + serverName.getType());
}
// NameType: 1 byte
remains -= encoded.length + 3;
// HostName length: 2 bytes
}
} else if (extLen == 0) {
// "server_name" extension in ServerHello
throw new SSLProtocolException("Not server name indication extension in client");
}
if (remains != 0) {
throw new SSLProtocolException("Invalid server name indication extension");
}
return Collections.<SNIServerName>unmodifiableList(new ArrayList<SNIServerName>(sniMap.values()));
}
use of javax.net.ssl.SSLProtocolException in project service-proxy by membrane.
the class SSLExplorer method exploreTLSRecord.
/*
* struct {
* uint8 major;
* uint8 minor;
* } ProtocolVersion;
*
* enum {
* change_cipher_spec(20), alert(21), handshake(22),
* application_data(23), (255)
* } ContentType;
*
* struct {
* ContentType type;
* ProtocolVersion version;
* uint16 length;
* opaque fragment[TLSPlaintext.length];
* } TLSPlaintext;
*/
private static SSLCapabilities exploreTLSRecord(ByteBuffer input, byte firstByte, byte secondByte, byte thirdByte) throws IOException {
// Is it a handshake message?
if (firstByte != 22) {
// 22: handshake record
throw new SSLException("Not handshake record");
}
// We need the record version to construct SSLCapabilities.
byte recordMajorVersion = secondByte;
byte recordMinorVersion = thirdByte;
// Is there enough data for a full record?
int recordLength = getInt16(input);
if (recordLength > input.remaining()) {
throw new BufferUnderflowException();
}
// We have already had enough source bytes.
try {
return exploreHandshake(input, recordMajorVersion, recordMinorVersion, recordLength);
} catch (BufferUnderflowException bufe) {
throw new SSLProtocolException("Invalid handshake record");
}
}
use of javax.net.ssl.SSLProtocolException in project Bytecoder by mirkosertic.
the class HandshakeStateManager method changeCipherSpec.
void changeCipherSpec(boolean isInput, boolean isClient) throws SSLProtocolException {
if (debugIsOn) {
System.out.println("update handshake state: change_cipher_spec");
}
String exceptionMsg = "ChangeCipherSpec message sequence violation";
HandshakeState expectedState;
if ((isClient && isInput) || (!isClient && !isInput)) {
expectedState = HS_SERVER_CHANGE_CIPHER_SPEC;
} else {
expectedState = HS_CLIENT_CHANGE_CIPHER_SPEC;
}
boolean hasPresentState = false;
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState == expectedState) {
hasPresentState = true;
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
throw new SSLProtocolException(exceptionMsg);
}
if (debugIsOn) {
for (HandshakeState handshakeState : upcomingStates) {
System.out.println("upcoming handshake states: " + handshakeState);
}
for (HandshakeState handshakeState : alternatives) {
System.out.println("upcoming handshake alternative state: " + handshakeState);
}
}
}
use of javax.net.ssl.SSLProtocolException in project Bytecoder by mirkosertic.
the class HandshakeStateManager method update.
void update(HandshakeMessage handshakeMessage, boolean isAbbreviated) throws SSLProtocolException {
byte handshakeType = (byte) handshakeMessage.messageType();
String exceptionMsg = "Handshake message sequence violation, " + handshakeType;
if (debugIsOn) {
System.out.println("update handshake state: " + toString(handshakeType));
}
boolean hasPresentState = false;
switch(handshakeType) {
case HandshakeMessage.ht_hello_request:
// Add the upcoming states.
if (!upcomingStates.isEmpty()) {
// A ClientHello message should be followed.
upcomingStates.add(HS_CLIENT_HELLO);
}
break;
case HandshakeMessage.ht_client_hello:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_CLIENT_HELLO.
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState != HS_CLIENT_HELLO) {
throw new SSLProtocolException(exceptionMsg);
}
}
// Add the upcoming states.
ClientHello clientHello = (ClientHello) handshakeMessage;
if (isDTLS) {
// Is it an initial ClientHello message?
if (clientHello.cookie == null || clientHello.cookie.length == 0) {
// Is it an abbreviated handshake?
if (clientHello.sessionId.length() != 0) {
// A HelloVerifyRequest message or a ServerHello
// message may follow the abbreviated session
// resuming handshake request.
upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
alternatives.add(HS_SERVER_HELLO);
} else {
// A HelloVerifyRequest message should follow
// the initial ClientHello message.
upcomingStates.add(HS_HELLO_VERIFY_REQUEST);
}
} else {
// A HelloVerifyRequest may be followed if the cookie
// cannot be verified.
upcomingStates.add(HS_SERVER_HELLO);
alternatives.add(HS_HELLO_VERIFY_REQUEST);
}
} else {
upcomingStates.add(HS_SERVER_HELLO);
}
break;
case HandshakeMessage.ht_hello_verify_request:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_HELLO_VERIFY_REQUEST.
HandshakeState handshakeState = upcomingStates.pop();
HandshakeState alternative = null;
if (!alternatives.isEmpty()) {
alternative = alternatives.pop();
}
if ((handshakeState != HS_HELLO_VERIFY_REQUEST) && (alternative != HS_HELLO_VERIFY_REQUEST)) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
// Add the upcoming states.
upcomingStates.add(HS_CLIENT_HELLO);
break;
case HandshakeMessage.ht_server_hello:
// Check and update the present state.
if (!upcomingStates.isEmpty()) {
// The current state should be HS_SERVER_HELLO
HandshakeState handshakeState = upcomingStates.pop();
HandshakeState alternative = null;
if (!alternatives.isEmpty()) {
alternative = alternatives.pop();
}
if ((handshakeState != HS_SERVER_HELLO) && (alternative != HS_SERVER_HELLO)) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
// Add the upcoming states.
ServerHello serverHello = (ServerHello) handshakeMessage;
HelloExtensions hes = serverHello.extensions;
if (isAbbreviated) {
// Not support SessionTicket extension yet.
//
// // Mandatory NewSessionTicket message
// if (hasSessionTicketExt) {
// upcomingStates.add(HS_NEW_SESSION_TICKET);
// }
// Mandatory server ChangeCipherSpec and Finished messages
upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_SERVER_FINISHED);
// Mandatory client ChangeCipherSpec and Finished messages
upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_CLEINT_FINISHED);
} else {
// Not support SupplementalData extension yet.
//
// boolean hasSupplementalDataExt =
// (hes.get(HandshakeMessage.ht_supplemental_data) != null);
// Not support CertificateURL extension yet.
//
// boolean hasCertificateUrlExt =
// (hes.get(ExtensionType EXT_CLIENT_CERTIFICATE_URL)
// != null);
// Not support SupplementalData extension yet.
//
// // Optional SupplementalData message
// if (hasSupplementalDataExt) {
// upcomingStates.add(HS_SERVER_SUPPLEMENTAL_DATA);
// }
// Need server Certificate message or not?
KeyExchange keyExchange = serverHello.cipherSuite.keyExchange;
if ((keyExchange != K_KRB5) && (keyExchange != K_KRB5_EXPORT) && (keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
// Mandatory Certificate message
upcomingStates.add(HS_SERVER_CERTIFICATE);
}
// Optional CertificateStatus message
if (hes.get(ExtensionType.EXT_STATUS_REQUEST) != null || hes.get(ExtensionType.EXT_STATUS_REQUEST_V2) != null) {
upcomingStates.add(HS_CERTIFICATE_STATUS);
}
// Need ServerKeyExchange message or not?
if ((keyExchange == K_RSA_EXPORT) || (keyExchange == K_DHE_RSA) || (keyExchange == K_DHE_DSS) || (keyExchange == K_DH_ANON) || (keyExchange == K_ECDHE_RSA) || (keyExchange == K_ECDHE_ECDSA) || (keyExchange == K_ECDH_ANON)) {
// Optional ServerKeyExchange message
upcomingStates.add(HS_SERVER_KEY_EXCHANGE);
}
// Optional CertificateRequest message
upcomingStates.add(HS_CERTIFICATE_REQUEST);
// Mandatory ServerHelloDone message
upcomingStates.add(HS_SERVER_HELLO_DONE);
// Not support SupplementalData extension yet.
//
// // Optional SupplementalData message
// if (hasSupplementalDataExt) {
// upcomingStates.add(HS_CLIENT_SUPPLEMENTAL_DATA);
// }
// Optional client Certificate message
upcomingStates.add(HS_CLIENT_CERTIFICATE);
// Not support CertificateURL extension yet.
//
// // Alternative CertificateURL message, optional too.
// //
// // Please put CertificateURL rather than Certificate
// // message in the alternatives list. So that we can
// // simplify the process of this alternative pair later.
// if (hasCertificateUrlExt) {
// alternatives.add(HS_CERTIFICATE_URL);
// }
// Mandatory ClientKeyExchange message
upcomingStates.add(HS_CLIENT_KEY_EXCHANGE);
// Optional CertificateVerify message
upcomingStates.add(HS_CERTIFICATE_VERIFY);
// Mandatory client ChangeCipherSpec and Finished messages
upcomingStates.add(HS_CLIENT_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_CLEINT_FINISHED);
// Not support SessionTicket extension yet.
//
// // Mandatory NewSessionTicket message
// if (hasSessionTicketExt) {
// upcomingStates.add(HS_NEW_SESSION_TICKET);
// }
// Mandatory server ChangeCipherSpec and Finished messages
upcomingStates.add(HS_SERVER_CHANGE_CIPHER_SPEC);
upcomingStates.add(HS_SERVER_FINISHED);
}
break;
case HandshakeMessage.ht_certificate:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == handshakeType) {
hasPresentState = true;
// the alternative list.
if ((handshakeState != HS_CLIENT_CERTIFICATE) && (handshakeState != HS_SERVER_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
// Is it an expected client Certificate message?
boolean isClientMessage = false;
if (!upcomingStates.isEmpty()) {
// If the next expected message is ClientKeyExchange,
// this one should be an expected client Certificate
// message.
HandshakeState nextState = upcomingStates.getFirst();
if (nextState == HS_CLIENT_KEY_EXCHANGE) {
isClientMessage = true;
}
}
if (isClientMessage) {
if (handshakeState != HS_CLIENT_CERTIFICATE) {
throw new SSLProtocolException(exceptionMsg);
}
// Not support CertificateURL extension yet.
/**
*****************************************
* // clear up the alternatives list
* if (!alternatives.isEmpty()) {
* HandshakeState alternative = alternatives.pop();
*
* if (alternative != HS_CERTIFICATE_URL) {
* throw new SSLProtocolException(exceptionMsg);
* }
* }
*******************************************
*/
} else {
if ((handshakeState != HS_SERVER_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
}
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
throw new SSLProtocolException(exceptionMsg);
}
break;
/**
**********************************************
*/
case HandshakeMessage.ht_certificate_url:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
// The current state should be HS_CLIENT_CERTIFICATE.
//
// Note that we won't put HS_CLIENT_CERTIFICATE into
// the alternative list.
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == HS_CLIENT_CERTIFICATE.handshakeType) {
hasPresentState = true;
// Look for HS_CERTIFICATE_URL state track.
if (!alternatives.isEmpty()) {
HandshakeState alternative = alternatives.pop();
if (alternative != HS_CERTIFICATE_URL) {
throw new SSLProtocolException(exceptionMsg);
}
} else {
// No alternative CertificateUR state track.
throw new SSLProtocolException(exceptionMsg);
}
if ((handshakeState != HS_CLIENT_CERTIFICATE)) {
throw new SSLProtocolException(exceptionMsg);
}
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
// No present state.
throw new SSLProtocolException(exceptionMsg);
}
break;
default:
// Check and update the present state.
while (!upcomingStates.isEmpty()) {
HandshakeState handshakeState = upcomingStates.pop();
if (handshakeState.handshakeType == handshakeType) {
hasPresentState = true;
break;
} else if (!handshakeState.isOptional) {
throw new SSLProtocolException(exceptionMsg);
}
// Otherwise, looking for next state track.
}
// No present state.
if (!hasPresentState) {
throw new SSLProtocolException(exceptionMsg);
}
}
if (debugIsOn) {
for (HandshakeState handshakeState : upcomingStates) {
System.out.println("upcoming handshake states: " + handshakeState);
}
for (HandshakeState handshakeState : alternatives) {
System.out.println("upcoming handshake alternative state: " + handshakeState);
}
}
}
use of javax.net.ssl.SSLProtocolException in project keystore-explorer by kaikramer.
the class SslUtils method readSSLConnectionInfos.
/**
* Load certificates from an SSL connection.
*
* @param host
* Connection host
* @param port
* Connection port
* @param keyStore
* KeyStore with a key pair for SSL client authentication
* @param password
* The password for the KeyStore
* @return SSL infos
* @throws CryptoException
* Problem encountered while loading the certificate(s)
* @throws IOException
* An I/O error occurred
*/
public static SslConnectionInfos readSSLConnectionInfos(String host, int port, KeyStore keyStore, char[] password) throws CryptoException, IOException {
URL url = new URL(MessageFormat.format("https://{0}:{1}/", host, "" + port));
HttpsURLConnection connection = null;
System.setProperty("javax.net.debug", "ssl");
try {
connection = (HttpsURLConnection) url.openConnection();
// create a key manager for client authentication
X509KeyManager km = null;
if (keyStore != null) {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509", "SunJSSE");
keyManagerFactory.init(keyStore, password);
for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
if (keyManager instanceof X509KeyManager) {
km = (X509KeyManager) keyManager;
break;
}
}
}
// We are only interested in getting the SSL certificates even if they are invalid
// either in and of themselves or for the host name they are associated with
// 1) set connection's SSL Socket factory to have a very trusting trust manager
SSLContext context = SSLContext.getInstance("TLS");
X509TrustingManager tm = new X509TrustingManager();
context.init(new KeyManager[] { km }, new TrustManager[] { tm }, null);
// 2) set a host name verifier that always verifies the host name
connection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession sslSession) {
return true;
}
});
// register our handshake completed listener in order to retrieve SSL connection infos later
SSLSocketFactory factory = context.getSocketFactory();
RetrieveSslInfosHandshakeListener handshakeListener = new RetrieveSslInfosHandshakeListener();
boolean sniEnabled = true;
connection.setSSLSocketFactory(new CustomSslSocketFactory(factory, handshakeListener, sniEnabled));
try {
connection.connect();
} catch (SSLProtocolException e) {
// handle server misconfiguration (works only in Java 8 or higher)
if (e.getMessage().contains("unrecognized_name")) {
sniEnabled = false;
connection.setSSLSocketFactory(new CustomSslSocketFactory(factory, handshakeListener, sniEnabled));
connection.connect();
} else {
throw e;
}
}
// this is necessary in order to cause a handshake exception when the client cert is not accepted
if (keyStore != null) {
connection.getResponseMessage();
}
SslConnectionInfos sslConnectionInfos = handshakeListener.getSslConnectionInfos();
sslConnectionInfos.setSniEnabled(sniEnabled);
return sslConnectionInfos;
} catch (GeneralSecurityException ex) {
throw new CryptoException(res.getString("NoLoadCertificate.exception.message"), ex);
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
Aggregations