| 
					
				 | 
			
			
				@@ -13,13 +13,13 @@ import sys 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 EPHEMERAL_INDICATORS = [ "_EDH_", "_DHE_", "_ECDHE_" ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 BAD_STUFF = [ "_DES_40_", "MD5", "_RC4_", "_DES_64_", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              "_SEED_", "_CAMELLIA_", "_NULL" ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "_SEED_", "_CAMELLIA_", "_NULL", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              "_CCM_8", "_DES_", ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # these never get #ifdeffed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 MANDATORY = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     "TLS1_TXT_DHE_RSA_WITH_AES_256_SHA", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     "TLS1_TXT_DHE_RSA_WITH_AES_128_SHA", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    "SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def find_ciphers(filename): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -48,15 +48,23 @@ def usable_cipher(ciph): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # All fields we sort on, in order of priority. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 FIELDS = [ 'cipher', 'fwsec', 'mode',  'digest', 'bitlength' ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Map from sorted fields to recognized value in descending order of goodness 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-FIELD_VALS = { 'cipher' : [ 'AES', 'DES'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+FIELD_VALS = { 'cipher' : [ 'AES', 'CHACHA20' ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                'fwsec' : [ 'ECDHE', 'DHE' ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               'mode' : [ 'GCM', 'CBC' ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               'digest' : [ 'SHA384', 'SHA256', 'SHA' ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               'mode' : [ 'POLY1305', 'GCM', 'CCM', 'CBC', ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               'digest' : [ 'n/a', 'SHA384', 'SHA256', 'SHA', ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                'bitlength' : [ '256', '128', '192' ], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Ciphersuite(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, name, fwsec, cipher, bitlength, mode, digest): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if fwsec == 'EDH': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fwsec = 'DHE' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if mode in [ '_CBC3', '_CBC', '' ]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mode = 'CBC' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif mode == '_GCM': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mode = 'GCM' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.name = name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.fwsec = fwsec 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.cipher = cipher 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -74,42 +82,50 @@ class Ciphersuite(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def parse_cipher(ciph): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)(|_CBC|_CBC3|_GCM)_(SHA|SHA256|SHA384)$', ciph) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if not m: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print "/* Couldn't parse %s ! */"%ciph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if m: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fwsec, cipher, bits, mode, digest = m.groups() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fwsec, cipher, bits, mode, digest = m.groups() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if fwsec == 'EDH': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fwsec = 'DHE' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)_CCM', ciph) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if m: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fwsec, cipher, bits = m.groups() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Ciphersuite(ciph, fwsec, cipher, bits, "CCM", "n/a") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if mode in [ '_CBC3', '_CBC', '' ]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        mode = 'CBC' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    elif mode == '_GCM': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        mode = 'GCM' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_CHACHA20_POLY1305', ciph) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if m: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fwsec, = m.groups() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    print "/* Couldn't parse %s ! */"%ciph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ALL_CIPHERS = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 for fname in sys.argv[1:]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ALL_CIPHERS += (parse_cipher(c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           for c in find_ciphers(fname) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           if usable_cipher(c) ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for c in find_ciphers(fname): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if usable_cipher(c): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            parsed = parse_cipher(c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if parsed != None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ALL_CIPHERS.append(parsed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ALL_CIPHERS.sort(key=Ciphersuite.sort_key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+indent = " "*7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 for c in ALL_CIPHERS: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if c is ALL_CIPHERS[-1]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        colon = ';' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        colon = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         colon = ' ":"' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if c.name in MANDATORY: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print "       /* Required */" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print '       %s%s'%(c.name,colon) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print "%s/* Required */"%indent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print '%s%s%s'%(indent,c.name,colon) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print "#ifdef %s"%c.name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        print '       %s%s'%(c.name,colon) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        print '%s%s%s'%(indent,c.name,colon) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         print "#endif" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+print '%s;'%indent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |