+ # Treat ECONNRESET the same as ECONNREFUSED. At least some systems give
+ # us the former on a new connection.
+ s/(could not connect to .*: Connection) reset by peer$/$1 refused/;
+
+ # ======== TLS certificate algorithms ========
+ #
+ # In Received: headers, convert RFC 8314 style ciphersuite to
+ # the older (comment) style, keeping only the Auth element
+ # (discarding kex, cipher, mac). For TLS 1.3 there is no kex
+ # element (and no _WITH); insert a spurious "RSA".
+
+ s/^\s+by .+ with .+ \K tls TLS_.*?([^_]+)_WITH.+$/(TLS1.x:ke-$1-AES256-SHAnnn:xxx)/;
+ s/^\s+by .+ with .+ \K tls TLS_.+$/(TLS1.x:ke-RSA-AES256-SHAnnn:xxx)/;
+
+ # Test machines might have various different TLS library versions supporting
+ # different protocols; can't rely upon TLS 1.2's AES256-GCM-SHA384, so we
+ # treat the standard algorithms the same.
+ #
+ # TLSversion : KeyExchange? - Authentication/Signature - C_iph_er - MAC : ???
+ #
+ # So far, have seen:
+ # TLSv1:AES128-GCM-SHA256:128
+ # TLSv1:AES256-SHA:256
+ # TLSv1.1:AES256-SHA:256
+ # TLSv1.2:AES256-GCM-SHA384:256
+ # TLSv1.2:DHE-RSA-AES256-SHA:256
+ # TLSv1.3:TLS_AES_256_GCM_SHA384:256
+ # TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128
+ # We also need to handle the ciphersuite without the TLS part present, for
+ # client-ssl's output. We also see some older forced ciphersuites, but
+ # negotiating TLS 1.2 instead of 1.0.
+ # Mail headers (...), log-lines X=..., client-ssl output ...
+ # (and \b doesn't match between ' ' and '(' )
+ #
+ # Retain the authentication algorith field as we want to test that.
+
+ s/( (?: (?:\b|\s) [\(=] ) | \s )TLSv1(\.[123])?:/$1TLS1.x:/xg;
+ s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA)(?!:)/ke-$3-AES256-SHAnnn/g;
+ s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA):(128|256)/ke-$3-AES256-SHAnnn:xxx/g;
+
+ # OpenSSL TLSv1.3 - unsure what to do about the authentication-variant testcases now,
+ # as it seems the protocol no longer supports a user choice. Replace the "TLS" field with "RSA".
+ # Also insert a key-exchange field for back-compat, even though 1.3 doesn't do that.
+ #
+ # TLSversion : "TLS" - C_iph_er - MAC : ???
+ #
+ s/TLS_AES(_256)?_GCM_SHA384(?!:)/ke-RSA-AES256-SHAnnn/g;
+ s/:TLS_AES(_256)?_GCM_SHA384:256/:ke-RSA-AES256-SHAnnn:xxx/g;
+
+ # LibreSSL
+ # TLSv1:AES256-GCM-SHA384:256
+ # TLSv1:ECDHE-RSA-CHACHA20-POLY1305:256
+ #
+ # ECDHE-RSA-CHACHA20-POLY1305
+ # AES256-GCM-SHA384
+
+ s/(?<!-)(AES256-GCM-SHA384)/RSA-$1/;
+ s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305)(?!:)/ke-$3-AES256-SHAnnn/g;
+ s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305):256/ke-$3-AES256-SHAnnn:xxx/g;
+
+ # GnuTLS have seen:
+ # TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256
+ # TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM__AEAD:256
+ # TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256
+ # TLS1.3:ECDHE_PSK_SECP256R1__AES_256_GCM__AEAD:256
+ #
+ # TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256
+ # TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128
+ # TLS1.2:RSA_AES_256_CBC_SHA1:256 (canonical)
+ # TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128
+ # TLS1.2:ECDHE_SECP256R1__RSA_SHA256__AES_256_GCM:256
+ # TLS1.2:ECDHE_SECP256R1__RSA_SHA256__AES_128_CBC__SHA256:128
+ # TLS1.2:ECDHE_SECP256R1__ECDSA_SHA512__AES_256_GCM:256
+ # TLS1.2:ECDHE_SECP256R1__AES_256_GCM:256 (3.6.7 resumption)
+ # TLS1.2:ECDHE_RSA_SECP256R1__AES_256_GCM:256 (! 3.5.18 !)
+ # TLS1.2:RSA__CAMELLIA_256_GCM:256 (leave the cipher name)
+ # TLS1.2-PKIX:RSA__AES_128_GCM__AEAD:128 (the -PKIX seems to be a 3.1.20 thing)
+ # TLS1.2-PKIX:ECDHE_RSA_SECP521R1__AES_256_GCM__AEAD:256
+ #
+ # X=TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256
+ # X=TLS1.2:RSA_AES_256_CBC_SHA1:256
+ # X=TLS1.1:RSA_AES_256_CBC_SHA1:256
+ # X=TLS1.0:RSA_AES_256_CBC_SHA1:256
+ # X=TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256
+ # X=TLS1.0-PKIX:RSA__AES_256_CBC__SHA1:256
+ # and as stand-alone cipher:
+ # ECDHE-RSA-AES256-SHA
+ # DHE-RSA-AES256-SHA256
+ # DHE-RSA-AES256-SHA
+ # picking latter as canonical simply because regex easier that way.
+ s/\bDHE_RSA_AES_128_CBC_SHA1:128/RSA-AES256-SHA1:256/g;
+ s/TLS1.[0123](-PKIX)?: # TLS version
+ ((EC)?DHE(_((?<psk>PSK)_)?((?<auth>RSA|ECDSA)_)?
+ (SECP(256|521)R1|X25519))?__?)? # key-exchange
+ ((?<auth>RSA|ECDSA)((_PSS_RSAE)?_SHA(512|256))?__?)? # authentication
+ AES_(256|128)_(CBC|GCM) # cipher
+ (__?AEAD)? # pseudo-MAC
+ (__?SHA(1|256|384))? # PRF
+ :(256|128) # cipher strength
+ /"TLS1.x:ke-"
+ . (defined($+{psk}) ? $+{psk} : "")
+ . (defined($+{auth}) ? $+{auth} : "")
+ . "-AES256-SHAnnn:xxx"/gex;
+ s/TLS1.2:RSA__CAMELLIA_256_GCM(_SHA384)?:256/TLS1.2:RSA_CAMELLIA_256_GCM-SHAnnn:256/g;
+ s/\b(ECDHE-(RSA|ECDSA)-AES256-SHA|DHE-RSA-AES256-SHA256)\b/ke-$2-AES256-SHAnnn/g;
+
+ # GnuTLS library error message changes
+ s/(No certificate was found|Certificate is required)/The peer did not send any certificate/g;
+#(dodgy test?) s/\(certificate verification failed\): invalid/\(gnutls_handshake\): The peer did not send any certificate./g;
+ s/\(gnutls_priority_set\): No or insufficient priorities were set/\(gnutls_handshake\): Could not negotiate a supported cipher suite/g;
+ s/\(gnutls_handshake\): \KNo supported cipher suites have been found.$/Could not negotiate a supported cipher suite./;
+
+ # (this new one is a generic channel-read error, but the testsuite
+ # only hits it in one place)
+ s/TLS error on connection \(gnutls_handshake\): Error in the pull function\./a TLS session is required but an attempt to start TLS failed/g;
+
+ # (replace old with new, hoping that old only happens in one situation)
+ s/TLS error on connection to \d{1,3}(.\d{1,3}){3} \[\d{1,3}(.\d{1,3}){3}\] \(gnutls_handshake\): A TLS packet with unexpected length was received./a TLS session is required for ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4], but an attempt to start TLS failed/g;
+ s/TLS error on connection from \[127.0.0.1\] \(recv\): A TLS packet with unexpected length was received./TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated./g;
+
+ # signature algorithm names
+ s/RSA-SHA1/RSA-SHA/;
+