Skip to content

Commit

Permalink
Limited TLS 1.3 client implementation
Browse files Browse the repository at this point in the history
* replace handshake protocol internals
    Add TLS 1.3 specific Handshake_Layer, Handshake_State,
    Handshake_Transitions, Transcript_Hash to replace
    functionality of TLS 1.2 Handshake_State.
    Related refactorings and module rearrangements.

* handling of Hello Retry Request
* handling alerts
* ensure handshake messages are not interleaved
* implement Exporters (RFC8446 7.5)
* Implement middlebox compatibility mode (RFC 8446 Appendix D.4)
* handle protocol version downgrade
* Post-Handshake-Message Key_Update
* OCSP stapling
* update of traffic secrets via a user-facing API
* Record_Size_Limit extension for TLS 1.3
* BoGo Tests integration/fixes for TLS 1.3
    ... we rebased the changes in jack/runner-20210401 to the current boringssl origin master (currently on reneme/boringssl)
    ... tests that are not applicable (yet) were disabled
    * prepend dummy ccs record for any second flight
    * too large decrypted plaintext
    * client hello version when renegotiating 1.2
    * don't try 1.3 if we have a 1.2 session to resume
    * server selected version handling
    * ALPN handling in TLS 1.3
    * segfault on empty certificate
    * user_canceled should be ignored
    * handle record padding
    * detect session ID downgrade attack
    * illegal compression method shall be 'decode error'
    * add missing check for unusable cipher suites
    * less scrutiny when checking version of initial rcv'd record
    * memory reservations for large records
    * detect unexpected extensions in EE
    * allow for better validation of OCSP responses
    * check for forbidden extensions in EE msg
    * validate allowed extensions in cert msg
    * empty Encrypted Extensions are not allowed
    * more explicit validation of Hello Retry Request
    * check signature algo in certificate
    * certificate constraint checking too loose
    * validate handshake type byte
    * refuse unprotected traffic after kex
    * detect bad alerts
    * support ALPN in TLS 1.3
    * allow 1.2 warning alerts in 1.3

Co-authored-by: René Meusel <[email protected]>
  • Loading branch information
Hannes Rantzsch and reneme committed Apr 5, 2022
1 parent 225cc9a commit 0ab571f
Show file tree
Hide file tree
Showing 94 changed files with 10,111 additions and 150 deletions.
182 changes: 166 additions & 16 deletions src/bogo_shim/bogo_shim.cpp

Large diffs are not rendered by default.

148 changes: 133 additions & 15 deletions src/bogo_shim/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
"Resume-Client-CipherMismatch": "Unexpected error",
"InvalidECDHPoint-Server": "Unexpected error",
"NoSharedCipher": "Unexpected error",
"NoSharedCipher-TLS13": "Unexpected error",

"PartialFinishedWithServerHelloDone": "Unexpected record vs excess handshake data"
"PartialFinishedWithServerHelloDone": "Unexpected record vs excess handshake data",
"HelloRetryRequest-DuplicateCurve-TLS13": "expects 'illegal parameter' but we want to stick with 'decode error'",
"HelloRetryRequest-DuplicateCookie-TLS13": "expects 'illegal parameter' but we want to stick with 'decode error'",
"EncryptedExtensionsWithKeyShare-TLS13": "expects 'unsupported extension' but RFC requires 'illegal parameter'"
},

"DisabledTests": {
Expand All @@ -27,21 +31,111 @@

"*SCSV*": "SCSV is meaningless without TLS 1.0/1.1 support",

"*KeyUpdate*": "No TLS 1.3",
"*TLS13*": "No TLS 1.3",
"Server-JDK11*": "No TLS 1.3",
"AllExtensions-*": "Not all extensions are implemented",

"EchoTLS13CompatibilitySessionID": "Succeeds, but we prepend a TLS 1.3 CCS and BoGo doesn't like that",

"Client-RejectJDK11DowngradeRandom": "We don't implement this workaround",
"ExportTrafficSecrets-*": "Exporting traffic secrets is not implemented",
"TooManyChangeCipherSpec-Client-TLS13": "Limits on the number of CCS are not implemented",
"TooManyKeyUpdates": "Limits on the number of KeyUpdates are not implemented",

"CertificateVerificationSucceed-Client-TLS13-*" : "TLS 1.3 session resumption is NYI",
"Client-VerifyDefault-*-TLS13" : "TLS 1.3 session resumption is NYI",
"Client-Verify-*-TLS13" : "TLS 1.3 session resumption is NYI",
"ExportKeyingMaterial-TLS13" : "TLS 1.3 session resumption is NYI",
"InvalidPSKIdentity-TLS13" : "TLS 1.3 session resumption is NYI",
"NegotiatePSKResumption-TLS13" : "TLS 1.3 session resumption is NYI",
"Resume-Client-CipherMismatch-TLS13" : "TLS 1.3 session resumption is NYI",
"Resume-Client-Mismatch-TLS13-TLS12-TLS" : "TLS 1.3 session resumption is NYI",
"Resume-Client-TLS13-TLS13-TLS" : "TLS 1.3 session resumption is NYI",
"TLS-TLS13-AES_128_GCM_SHA256-client" : "TLS 1.3 session resumption is NYI",
"TLS-TLS13-AES_256_GCM_SHA384-client" : "TLS 1.3 session resumption is NYI",
"TLS-TLS13-CHACHA20_POLY1305_SHA256-client" : "TLS 1.3 session resumption is NYI",
"TLS12SessionID-TLS13" : "TLS 1.3 session resumption is NYI",
"TLS13-HonorServerSessionTicketLifetime" : "TLS 1.3 session resumption is NYI",
"TLS13-TestBadTicketAge-Client" : "TLS 1.3 session resumption is NYI",
"TLS13-TestValidTicketAge-Client" : "TLS 1.3 session resumption is NYI",
"TLS13SessionID-TLS13" : "TLS 1.3 session resumption is NYI",
"TolerateServerNameAck-TLS-TLS13" : "TLS 1.3 session resumption is NYI",
"OCSPStapling-Client-TLS13-*" : "TLS 1.3 session resumption is NYI",
"Resume-Client-NoResume-TLS12-TLS13-TLS": "TLS 1.3 session resumption is NYI",
"Resume-Client-Mismatch-TLS12-TLS13-TLS": "TLS 1.3 session resumption is NYI",
"Ticket-Forbidden-TLS13": "TLS 1.3 session resumption is NYI",
"Resume-Client-PRFMismatch-TLS13": "TLS 1.3 session resumption is NYI",
"TLS13-HelloRetryRequest-Client-*": "TLS 1.3 session resumption is NYI",
"TLS13-TicketAgeSkew-*": "TLS 1.3 session resumption is NYI",
"CurveID-Resume-Client-TLS13": "TLS 1.3 session resumption is NYI",
"ALPNClient-TLS-TLS13": "TLS 1.3 session resumption is NYI",

"KeyUpdate-FromServer": "No TLS 1.3 server, yet",
"FragmentedClientVersion": "No TLS 1.3 server, yet",
"DelegatedCredentials*": "No TLS 1.3 server, yet",
"IgnoreClientVersionOrder": "No TLS 1.3 server, yet",
"Resume-Server-OmitPSKsOnSecondClientHello": "No TLS 1.3 server, yet",
"PartialClientFinishedWithSecondClientHello": "No TLS 1.3 server, yet",
"Server-JDK11*": "No TLS 1.3 server, yet",

"CertCompression*-TLS13": "No TLS 1.3 server, yet",
"DuplicateKeyShares-TLS13": "No TLS 1.3 server, yet",
"ECDSACurveMismatch-Sign-TLS13": "No TLS 1.3 server, yet",
"MinimumVersion-Server*-TLS13*": "No TLS 1.3 server, yet",
"Resume-Server*TLS13*": "No TLS 1.3 server, yet",
"Server-Sign-*-TLS13": "No TLS 1.3 server, yet",
"Server-Verify-*-TLS13": "No TLS 1.3 server, yet",
"Server-VerifyDefault-*-TLS13": "No TLS 1.3 server, yet",

"TLS-TLS13-*-server": "No TLS 1.3 server, yet",
"TLS13-Server-*": "No TLS 1.3 server, yet",
"TLS13-*-Server*": "No TLS 1.3 server, yet",
"*-Server-TLS13": "No TLS 1.3 server, yet",
"*-TLS13-Server": "No TLS 1.3 server, yet",
"RSAKeyUsage-Server-*-TLS13": "No TLS 1.3 server, yet",

"ExportKeyingMaterial-Server-HalfRTT-TLS13": "No TLS 1.3 server, yet",
"ExtraClientEncryptedExtension-TLS-TLS13": "No TLS 1.3 server, yet",
"ExtraCompressionMethods-TLS13": "No TLS 1.3 server, yet",
"LooseInitialRecordVersion-TLS13": "No TLS 1.3 server, yet",
"NoSupportedCurves-TLS13": "No TLS 1.3 server, yet",
"RequireAnyClientCertificate-TLS13": "No TLS 1.3 server, yet",
"SecondClientHelloMissingKeyShare-TLS13": "No TLS 1.3 server, yet",
"SecondClientHelloWrongCurve-TLS13": "No TLS 1.3 server, yet",
"SendExtensionOnClientCertificate-TLS13": "No TLS 1.3 server, yet",
"ServerAuth-NoFallback-TLS13": "No TLS 1.3 server, yet",
"ServerSkipCertificateVerify-TLS13": "No TLS 1.3 server, yet",
"SkipClientCertificate-TLS13": "No TLS 1.3 server, yet",
"TLS13-NoTicket-NoMint": "No TLS 1.3 server, yet",
"TrailingKeyShareData-TLS13": "No TLS 1.3 server, yet",
"UnexpectedClientEncryptedExtensions-TLS-TLS13": "No TLS 1.3 server, yet",
"UnknownCipher-TLS13": "No TLS 1.3 server, yet",
"VersionTolerance-TLS13": "No TLS 1.3 server, yet",

"*EarlyData*": "No TLS 1.3 Early Data, yet",
"TLS13-1RTT-Client-*": "No TLS 1.3 Early Data, yet",

"FailCertCallback-Client-TLS13": "No client auth in TLS 1.3, yet",
"Client-Sign*-TLS13": "No client auth in TLS 1.3, yet",
"TLS13-Client-ClientAuth-": "No client auth in TLS 1.3, yet",
"ClientAuth-*-TLS13": "No client auth in TLS 1.3, yet",
"TLS13-Client-ClientAuth-*": "No client auth in TLS 1.3, yet",
"NoClientCertificate-TLS13": "No client auth in TLS 1.3, yet",
"NoCommonAlgorithms-TLS13": "No client auth in TLS 1.3, yet",
"ClientAuth-*-TLS13-*": "No client auth in TLS 1.3, yet",
"TrailingMessageData-TLS13-CertificateRequest-TLS": "No client auth in TLS 1.3, yet",
"RequestContextInHandshake-TLS13": "No client auth in TLS 1.3, yet",
"UnknownExtensionInCertificateRequest-TLS13": "No client auth in TLS 1.3, yet",
"MissingSignatureAlgorithmsInCertificateRequest-TLS13": "No client auth in TLS 1.3, yet",
"ClientSkipCertificateVerify-TLS13": "No client auth in TLS 1.3, yet",
"SendReceiveIntermediate-Client-TLS13": "No client auth in TLS 1.3, yet",
"TLS13-Client-CertReq-CA-List": "No client auth in TLS 1.3, yet",
"SendNoClientCertificateExtensions-TLS13": "No client auth in TLS 1.3, yet",

"KeyUpdate-RequestACK-UnfinishedWrite": "-read-with-unfinished-write currently not supported in the shim",

"*Binder*": "No TLS 1.3",
"PartialEncryptedExtensionsWithServerHello": "No TLS 1.3",
"Client-RejectJDK11DowngradeRandom": "No TLS 1.3",
"FragmentedClientVersion": "No TLS 1.3",
"NoExportEarlyKeyingMaterial*": "No TLS 1.3",
"EarlyDataEnabled*": "No TLS 1.3",
"DelegatedCredentials*": "No TLS 1.3",
"ExportTrafficSecrets-*": "No TLS 1.3",
"IgnoreClientVersionOrder": "No TLS 1.3",
"Resume-Server-OmitPSKsOnSecondClientHello": "No TLS 1.3",
"PartialServerHelloWithHelloRetryRequest": "No TLS 1.3",
"PartialClientFinishedWithSecondClientHello": "No TLS 1.3",
"TLS-ECH*": "No ECH support",
"ECH*": "No ECH support",

"DuplicateCertCompressionExt*": "No support for 1.3 cert compression extension",
Expand Down Expand Up @@ -73,6 +167,8 @@
"*SCT*": "No support for SCT",
"Renegotiation-ChangeAuthProperties": "No support for SCT",
"UnsolicitedCertificateExtensions-*": "No support for SCT",
"IgnoreExtensionsOnIntermediates-TLS13": "No support for SCT",
"SendNoExtensionsOnIntermediate-TLS13": "No support for SCT",

"CertificateVerificationSoftFail*": "Fail, but don't fail... wtf?",

Expand Down Expand Up @@ -156,6 +252,28 @@
"PartialClientFinishedWithClientHello": "Need to check for buffered messages when CCS (bug)",
"SendUnencryptedFinished-DTLS": "Need to check for buffered messages when CCS (bug)",

"RSAKeyUsage-*-UnenforcedTLS*": "We always enforce key usage"
}
"RSAKeyUsage-*-UnenforcedTLS*": "We always enforce key usage",

"Basic-Client-RenewTicket*" : "Needs investigation -- apparently Botan TLS 1.2 does not fully support renewing tickets after resumption?",

"AllExtensions-Client-Permute-TLS-TLS12" : "Requires new shim flags that are NYI (as of March 2022)",
"AllExtensions-Client-Permute-DTLS-TLS12" : "Requires new shim flags that are NYI (as of March 2022)",
"EarlyData-WriteAfterEncryptedExtensions" : "Requires new shim flags that are NYI (as of March 2022)",
"EarlyData-WriteAfterServerHello" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-SignatureInput" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-KeyShare" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-HandshakerHelloRetryRequest" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-ShimHelloRetryRequest" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-SignatureAlgorithm" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-NoTickets1" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-NoTickets2" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-Version2" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-CertificateRequest" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-CertificateCompression-HandshakerOnly" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-CertificateCompression-ShimOnly" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-CertificateCompression-AlgorithmMismatch" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-CertificateCompression-InputMismatch" : "Requires new shim flags that are NYI (as of March 2022)",
"TLS-HintMismatch-Version1" : "Requires new shim flags that are NYI (as of March 2022)"

}
}
25 changes: 15 additions & 10 deletions src/cli/tls_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* (C) 2014,2015 Jack Lloyd
* 2016 Matthias Gierlings
* 2017 René Korthaus, Rohde & Schwarz Cybersecurity
* 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
Expand Down Expand Up @@ -33,8 +34,8 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks
{
public:
TLS_Client()
: Command("tls_client host --port=443 --print-certs --policy=default "
"--skip-system-cert-store --trusted-cas= "
: Command("tls_client host --port=443 --print-certs --debug --policy=default "
"--skip-system-cert-store --trusted-cas= --tls-version=default "
"--session-db= --session-db-pass= --next-protocols= --type=tcp")
{
init_sockets();
Expand Down Expand Up @@ -73,6 +74,7 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks
const std::string next_protos = get_arg("next-protocols");
const bool use_system_cert_store = flag_set("skip-system-cert-store") == false;
const std::string trusted_CAs = get_arg("trusted-cas");
const auto tls_version = get_arg("tls-version");

if(!sessions_db.empty())
{
Expand All @@ -96,22 +98,25 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks
throw CLI_Usage_Error("Invalid transport type '" + transport + "' for TLS");
}

const bool use_tcp = (transport == "tcp");

const std::vector<std::string> protocols_to_offer = Command::split_on(next_protos, ',');

Botan::TLS::Protocol_Version version =
use_tcp ? Botan::TLS::Protocol_Version::TLS_V12 : Botan::TLS::Protocol_Version::DTLS_V12;

if(!policy)
{
policy.reset(new Botan::TLS::Policy);
}

if(policy->acceptable_protocol_version(version) == false)
{
throw CLI_Usage_Error("The policy specified does not allow the requested TLS version");
const bool use_tcp = (transport == "tcp");
Botan::TLS::Protocol_Version version = policy->latest_supported_version(!use_tcp);

if(tls_version != "default") {
if(tls_version == "1.2") {
version = Botan::TLS::Protocol_Version::TLS_V12;
} else if (tls_version == "1.3") {
version = Botan::TLS::Protocol_Version::TLS_V13;
} else {
error_output() << "Unknown TLS protocol version " << tls_version << '\n';
}
}

struct sockaddr_storage addrbuf;
std::string hostname;
Expand Down
1 change: 1 addition & 0 deletions src/cli/tls_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ class TLS_Client_Hello_Reader final : public Command

try
{
// TODO: deal with Client_Hello_13
Botan::TLS::Client_Hello_12 hello(input);

output() << format_hello(hello);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/tls/asio/asio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ class Stream
m_context.m_policy,
m_context.m_rng,
m_context.m_server_info,
Protocol_Version::latest_tls_version()));
Protocol_Version::TLS_V12)); // TODO don't hardcode
}
else
{
Expand Down
1 change: 0 additions & 1 deletion src/lib/tls/msg_cert_req.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,4 @@ std::vector<uint8_t> Certificate_Req::serialize() const

return buf;
}

}
Loading

0 comments on commit 0ab571f

Please sign in to comment.