Hi Piotr, Radu,
continued to play with the SNI-Relay and implemented a server side "CN" and/or "SAN" verification code. Seems that this technique could be securely used to relay SNI values between client/server side and use the provided SNI value to verify the serverside CN or SAN values.
when CLIENTSSL_HANDSHAKE {
if { [SSL::extensions exists -type 0] } then {
set tls_sni_extension [SSL::extensions -type 0]
} else {
set tls_sni_extension ""
}
}
when SERVERSSL_CLIENTHELLO_SEND {
if { $tls_sni_extension ne "" } then {
SSL::extensions insert $tls_sni_extension
}
}
when SERVERSSL_HANDSHAKE {
set cname_valid 0
if { [SSL::cert count] > 0 } then {
set cnames [string tolower [string map { "*" "" } [findstr [X509::subject [SSL::cert 0]] "CN=" 3 ","]]]
set cnames [lsort -unique "$cnames [string tolower [string map { ", DNS:*" " " ", DNS:" " " ",DNS:*" " " ",DNS:" " " "*" "" ", " " " "," " " } [findstr [X509::extensions [SSL::cert 0]] "DNS:" 4 "\n"]]]"]
}
foreach cname $cnames {
if { $cname starts_with "." } then {
if { [llength [split $tls_sni_extension "."]] == [llength [split $cname "."]] } then {
if { [findstr $tls_sni_extension "\." 0 end] ends_with $cname } then {
set cname_valid 1
return
}
}
} else {
if { $tls_sni_extension equals $cname } then {
set cname_valid 1
return
}
}
}
}
when HTTP_REQUEST_SEND {
clientside {
HTTP::respond 200 content "Client/Server SSL SNI = [string range $tls_sni_extension 9 end], Server SSL CNAMES = $cnames, Verification Result = $cname_valid" Content-Type "text/txt"
}
}
Note: This is a proof of concept code. Don't use it in production environments without further testings. And by any means implement OneConnect to reduce the overhead of the iRule... 😉
Cheers, Kai