/* *uint8V2CipherSpec[3]; *struct{ *uint16msg_length;// The highest bit MUST be 1; *// the remaining bits contain the length *// of the following data in bytes. *uint8msg_type;// MUST be 1 *Versionversion; *uint16cipher_spec_length;// It cannot be zero and MUST be a *// multiple of the V2CipherSpec length. *uint16session_id_length;// This field MUST be empty. *uint16challenge_length;// SHOULD use a 32-byte challenge *V2CipherSpeccipher_specs[V2ClientHello.cipher_spec_length]; *opaquesession_id[V2ClientHello.session_id_length]; *opaquechallenge[V2ClientHello.challenge_length; *}V2ClientHello;
*/ privatestatic SSLCapabilities exploreV2HelloRecord(
ByteBuffer input, byte firstByte, byte secondByte, byte thirdByte) throws IOException {
// We only need the header. We have already had enough source bytes. // int recordLength = (firstByte & 0x7F) << 8) | (secondByte & 0xFF); try { // Is it a V2ClientHello? if (thirdByte != 0x01) { thrownew SSLException( "Unsupported or Unrecognized SSL record");
}
// 0x00: major version of SSLv20 // 0x02: minor version of SSLv20 // // SNIServerName is an extension, SSLv20 doesn't support extension. returnnew SSLCapabilitiesImpl((byte)0x00, (byte)0x02,
helloVersionMajor, helloVersionMinor,
Collections.<SNIServerName>emptyList());
} catch (BufferUnderflowException bufe) { thrownew SSLProtocolException( "Invalid handshake record");
}
}
// Is it a handshake message? if (firstByte != 22) { // 22: handshake record thrownew 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()) { thrownew BufferUnderflowException();
}
// We have already had enough source bytes. try { return exploreHandshake(input,
recordMajorVersion, recordMinorVersion, recordLength);
} catch (BufferUnderflowException bufe) { thrownew SSLProtocolException( "Invalid handshake record");
}
}
// What is the handshake type? byte handshakeType = input.get(); if (handshakeType != 0x01) { // 0x01: client_hello message thrownew IllegalStateException("Not initial handshaking");
}
// What is the handshake body length? int handshakeLength = getInt24(input);
// Theoretically, a single handshake message might span multiple // records, but in practice this does not occur. if (handshakeLength > (recordLength - 4)) { // 4: handshake header size thrownew SSLException("Handshake message spans multiple records");
}
int length = getInt16(input); // length of extensions while (length > 0) { int extType = getInt16(input); // extenson type int extLen = getInt16(input); // length of extension data
if (extType == 0x00) { // 0x00: type of server name indication return exploreSNIExt(input, extLen);
} else { // ignore other extensions
ignoreByteVector(input, extLen);
}
Map<Integer, SNIServerName> sniMap = new LinkedHashMap<>();
int remains = extLen; if (extLen >= 2) { // "server_name" extension in ClientHello int listLen = getInt16(input); // length of server_name_list if (listLen == 0 || listLen + 2 != extLen) { thrownew SSLProtocolException( "Invalid server name indication extension");
}
remains -= 2; // 0x02: the length field of server_name_list while (remains > 0) { int code = getInt8(input); // name_type int snLen = getInt16(input); // length field of server name if (snLen > remains) { thrownew SSLProtocolException( "Not enough data to fill declared vector size");
} byte[] encoded = newbyte[snLen];
input.get(encoded);
SNIServerName serverName; switch (code) { case StandardConstants.SNI_HOST_NAME: if (encoded.length == 0) { thrownew 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) { thrownew SSLProtocolException( "Duplicated server name of type " +
serverName.getType());
}
remains -= encoded.length + 3; // NameType: 1 byte // HostName length: 2 bytes
}
} elseif (extLen == 0) { // "server_name" extension in ServerHello thrownew SSLProtocolException( "Not server name indication extension in client");
}
if (remains != 0) { thrownew SSLProtocolException( "Invalid server name indication extension");
}
return Collections.<SNIServerName>unmodifiableList( new ArrayList<>(sniMap.values()));
}
privatestaticvoid ignoreByteVector(ByteBuffer input, int length) { if (length != 0) { int position = input.position();
input.position(position + length);
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.131Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.