@ -179,6 +179,7 @@ var whitelistedCiphers = []string{
var blacklistedCiphers = [ ] string {
"TLS_NULL_WITH_NULL_NULL" ,
"TLS_RSA_WITH_AES_128_CBC_SHA" ,
}
func getCipherSuiteName ( value uint ) string {
@ -190,6 +191,16 @@ func getCipherSuiteName(value uint) string {
return val
}
func isBadCipher ( cname string ) bool {
for _ , cipher := range blacklistedCiphers {
if cipher == cname {
return true
}
}
return false
}
func gettlsExtensionName ( value uint ) string {
// 26-34: Unassigned
// 36-65280: Unassigned
@ -207,6 +218,52 @@ func gettlsExtensionName(value uint) string {
return val
}
func stripTLSData ( record [ ] byte , start_ind , end_ind int , len_ind int , len_size int ) [ ] byte {
var size uint = 0
if len_size < 1 || len_size > 2 {
return nil
} else if ( start_ind >= end_ind ) {
return nil
} else if len_ind >= start_ind {
return nil
}
rcopy := make ( [ ] byte , len ( record ) )
copy ( rcopy , record )
if len_size == 1 {
size = uint ( rcopy [ len_ind ] )
} else if len_size == 2 {
size = uint ( binary . BigEndian . Uint16 ( rcopy [ len_ind : len_ind + len_size ] ) )
}
size -= uint ( end_ind - start_ind )
// Put back the length size
if len_size == 1 {
rcopy [ len_ind ] = byte ( size )
} else if len_size == 2 {
binary . BigEndian . PutUint16 ( rcopy [ len_ind : len_ind + len_size ] , uint16 ( size ) )
}
// Patch the record size
rsize := binary . BigEndian . Uint16 ( rcopy [ 3 : 5 ] )
rsize -= uint16 ( end_ind - start_ind )
binary . BigEndian . PutUint16 ( rcopy [ 3 : 5 ] , rsize )
// And finally the 3 byte hello record
hsize := binary . BigEndian . Uint32 ( rcopy [ 5 : 9 ] )
saved_b := hsize & 0xff000000
hsize &= 0x00ffffff
hsize -= uint32 ( end_ind - start_ind )
hsize |= saved_b
binary . BigEndian . PutUint32 ( rcopy [ 5 : 9 ] , hsize )
result := append ( rcopy [ : start_ind ] , rcopy [ end_ind : ] ... )
return result
}
func connectionReader ( conn net . Conn , is_client bool , c chan connReader , done chan bool ) {
var ret_error error = nil
buffered := [ ] byte { }
@ -356,7 +413,7 @@ select_loop:
fmt . Println ( "SSL ALERT TYPE UNKNOWN" )
}
alert_desc := int ( int ( cr . data [ 6 ] ) << 8 | int ( cr . data [ 7 ] ) )
alert_desc := int ( int ( cr . data [ 5 ] ) << 8 | int ( cr . data [ 6 ] ) )
fmt . Println ( "ALERT DESCRIPTION: " , alert_desc )
if cr . data [ TLS_RECORD_HDR_LEN ] == SSL3_AL_FATAL {
@ -456,6 +513,9 @@ select_loop:
noCS := cs
fmt . Printf ( "cs = %v / %#x\n" , noCS , noCS )
var ciphersuite_excisions = [ ] int { }
saved_ciphersuite_size_off := hello_offset
if ! cr . client {
fmt . Printf ( "SERVER selected ciphersuite: %#x (%s)\n" , cs , getCipherSuiteName ( uint ( cs ) ) )
hello_offset += 2
@ -464,7 +524,14 @@ select_loop:
for csind := 0 ; csind < int ( noCS / 2 ) ; csind ++ {
off := hello_offset + 2 + ( csind * 2 )
cs = binary . BigEndian . Uint16 ( handshakeMsg [ off : off + 2 ] )
fmt . Printf ( "%s HELLO CIPHERSUITE: %d/%d: %#x (%s)\n" , SRC , csind + 1 , noCS / 2 , cs , getCipherSuiteName ( uint ( cs ) ) )
cname := getCipherSuiteName ( uint ( cs ) )
fmt . Printf ( "%s HELLO CIPHERSUITE: %d/%d: %#x (%s)\n" , SRC , csind + 1 , noCS / 2 , cs , cname )
if isBadCipher ( cname ) {
fmt . Println ( "BAD CIPHER: " , cname )
ciphersuite_excisions = append ( ciphersuite_excisions , off )
}
}
hello_offset += 2 + int ( noCS )
@ -541,15 +608,38 @@ select_loop:
rewrite_buf [ len ( rewrite_buf ) - 2 ] = 0
}
sendbuf := cr . data
if rewrite {
sendbuf = rewrite_buf
}
if len ( ciphersuite_excisions ) > 0 {
fmt . Printf ( "Rewriting client handshake with %d ciphersuite options removed\n" , len ( ciphersuite_excisions ) )
fmt . Println ( "PREVIOUS: " , hex . Dump ( sendbuf ) )
rewrite = true
mod := sendbuf
for _ , exind := range ciphersuite_excisions {
mod = stripTLSData ( mod , exind + TLS_RECORD_HDR_LEN , exind + TLS_RECORD_HDR_LEN + 2 , saved_ciphersuite_size_off + TLS_RECORD_HDR_LEN , 2 )
if mod == nil {
return errors . New ( "Unknown error occurred stripping ciphersuite from client TLS handshake" )
}
}
rewrite_buf = mod
sendbuf = rewrite_buf
}
if rewrite {
fmt . Println ( "TLSGuard writing back modified handshake data to server" )
fmt . Printf ( "ORIGINAL[%d]: %v\n" , len ( cr . data ) , hex . Dump ( cr . data ) )
fmt . Printf ( "NEW[%d]: %v\n" , len ( rewrite_buf ) , hex . Dump ( rewrite_buf ) )
other . Write ( rewrite_buf )
} else {
other . Write ( cr . data )
}
other . Write ( sendbuf )
continue
}