diff --git a/AATC_Config.py b/AATC_Config.py index 3bd1ed0..0b7764c 100644 --- a/AATC_Config.py +++ b/AATC_Config.py @@ -1,6 +1,7 @@ SERVER_NAME = "AATC" -SERVER_PRIVATE_KEY = b'0\x82\t)\x02\x01\x00\x02\x82\x02\x01\x00\x9a`\xfa\xdf\x0e%\x8bv\x82\x94v\xe1gt\xafK\'\xa1\x87l\xef\xaeV\xc5\x9e\xfb\x8e\x00\xbal1u\xab\xbe\x92"\xd6\t\xad\x12\xdbx4\x0c\x9d\xdb\xf9\xcf\x08\x8au+\xa8[n\x1b\x86i\xb76N~\x82\xcf\xdd\xd0\xa1c\xb7\xbf\xbcT\x93\x9fT\x1c\xbb\x85\xf2\xd5\xa6\xfbx,\xf1i\xecv{\x85\x92\xd6\xc5a\x168\x93.\xa4t`\x06D\xbd\x969\xba\xec\xda<&\xaf\x8d\xb0\xc6\x99\xb6k\x86\x96\x0c\x19\x0b\x1a\x82T\x1c\xcbI\xe4P\x00\xd0\x0f\x9eP\x1cw\x06\xc1\x18\x1b\xc46g\xe2\xd8iSy\xc2?\tP\xef\xd1jlf\x97C?\xfa*\x92\x1c\xd8\xf0l\x02\xd3\xc2W7\xc4\xd8\xb2\xd2\xa5\x00?\xe9K\xce\x0e\xc0\xa3\x8c\xc7\xee\xd8\x9aq\xe0\xe2n6~\xd9-_OE]Ui9w#\x7f\xf9\x11QE\xb9^/\xdc0=\x9d\x12+nU\xd4\xc6H\xebAK\x010)OV\xab3\x1b\x0f\xe8\xa99\xbe\x18\xab\xadE\x9cs\xd7\x1co\xa3FD\xcf\x96\x88\xb6\xcay\x02\xcb!\x97x{\x13\x80\'\xdd\\\x1awL\xd63\xb4\x85\xa3\x10\xf9\xe8s\xa6\xb6\xd5\xd8P\xba\xe1\x81\x07Az4\x8f\x94\x9aR\x89\xae\xb4\x18\x9b9Q\xfeVe\xb4\xf7\xfe\xb1\xa0\xd3j5\x89 r\x92\xc0\x06\xbd\xa4sf\xdc\xd0y:=M0\xe2Y\xeez\xe2^\xd0?\xd8\xf6\xe1\xa62\x840\x91d\x99\xf7{\x909\xf4\xe4\xcd\x8c\x02\x03{\x1e\xe7]\xe4\xc4 \x94 \xe5\xcbw4\xbf\xc7\xe7J\xba\x1a\xf9\x13\xedN\xff\x85UA\xcf%V\xa8\xfa0I\xb5\x05%\x9bo@\xae]\x82\xb1-\xe1\x87\x82z\xfb\x9bA\xd8\x991\xceNx\x91\xba\x87`\x1c\x9f\xc5Y+\x8b\x87[\xd1\xb8)\x92\xb0\xfc\xee\xb7\xd1\xcf\xa1OF\xc0;\xf3\xf2\xe9\xbez"\xaf\xd3\xd4\xa4\xddG\xb0]ro\xf7\x82\xfc\x1a\xf1\xed\xb92$\xcbd%j\x98\xcbd\x7f\x1b!\xc6l\xd2<\x9d8\x97\xe5\xa0\xac\xc7G\xb9\xda\x90\xce~\xb1\xc1\xab\xe2\xcd\xef\x8d\xf8g\xd1I\x02\x03\x01\x00\x01\x02\x82\x02\x00\x0e!7\xf8\xfc8\x1c\xbf\x8a4Y<\xa8}\xce1\x06e\xb3\t\xda\x16\xa6\x7f\xc4=A:)\x15\xef\xc1u\xc8\x95\xa2\xcd]\x19\x9b\x97\x1d\x95\x82\xfd\x9cU\x8d\x18\xda\xa6^\x8atb\xdb\xafU\xe3\xf4[#\x1ai8\xe3\xc8o\xc2p\xd0\xc5\x9bt\xda\xeb\x9d\xd0\xc4\xe0\xff\xfdvz\x83\x96\x96\xb3a\xfb\x1f\xed[\'\xb7\x93RJS\xb8H\x95.K\xbdq\x17~\'\xfb\xd7-\x1c~|p\xf3x\xbc:\xe5\xcc\xd1~\xb9\xc4\xc5\xd5g\xf4\x17\x0b\xf9\xff!\xf5\xf2c\x05\t\xdd\xa1e\xf86R5\x8dO[\xfe\xb6\xcb\r\x1e\xc4\x17\xb5\xe7\xfej\x83\xf3\xab[\x8f\xfb\x1d\xa7?+\x7fWA\x06\x19\xf0\xe5\x15\x7f\xd49\xaf\xcb\xe2\x7f\x08\x81!H\x07\xc8|\t\x91\xa3\xf5\x86.\xed\xc7\x92Ov\x9bS\x8c\x14N\xda\x1e\xd3rQ;\xc6\x06\x82\xa4b1K\tQZ\x17\x05V\x85|\xc6\x87\x0bo\xce\x80\x8f\xdf\x17\xb8!+\x02\xfbV\x91\xf9\x04\x1c\xed\x9f\xd7\xcd\x12\x80B\xf5\xe1\xff\xb7 \xb9\xe19\xa8>\xe0,\xd9U\x92\xd9r\x9aU\xc5\xa5\xe7U\x0b\x87\xd7\xa3-\xdb\xd0\xeeH`\xdbrJ\xc1\xfc^\xe6\\\xea\t\x14\x8e\x15\x01\xb1\xe4\xa9he\xac\xa7;\xf6\xc5\xc6\xa7X,\xcb"\xe3\x98\x94eOs\xab\x91\x0c&/\xa8\xfd}\xc1O\xa8MA\xef\xb2B\x95\xffP\xfff\xed\x1b\xdd+"\xac\xbd\x98\x0b{\x02\xab\x0eh\x9d"}\xa8\xe3\xc46E\x0ex\xc2\xe9\xea:\xaa\xe4\x89\x0f\x01\xfd\xb3^\xfb\x85\xb3\xa1?IZ]\x15\x14lv>7\x96\xeb\xc4\xc6\x0b.\r\xac@-.\xb2\xb3\xc7\n\x0f6\x97.\xe2\xce\xff\x90\x86\xd8s\xb3\x18\xebVA\x82\xc8\x1d;\xdf"\xfc#\x7f\x98`\x1e\xc2\xeb%\x97W\xae\x99H\x90\x9a\xe2\xf3\x0c\xca\xc9\xa5\x9c\xdb?V\xe5\xa5\xaf\xe4\xe0\x0f\xfcZj\xab\x0e\xf1\x02\x82\x01\x01\x00\x88\xd8\xda:\x97\x1c\x1e\x1b3o\xbe\x01\x00\xdc\x84\xa48\xd12\xed\x0e\x972\x96\xc9\x02<\xc3\xf1\xd5\x98\xcf\x8e\xf8\xe0\xb4\xf0C\x92\x14\xedq\xf8\r#\xe5$[\x1a\x14\x17\xdd\xdd\x9d!\xb1\x82\xc1\xa1\\\xa0\xa9\xad\x9d(\xe4\xb7\xfd\xb5\xbd\x98\xb0n\xf4g\xb4$\x11\xc0\xd8;\x122\xfa\t\r^B\x1c\x94\xd1\x97Y\xd0\x96\xd1\xa9@\x14Q\x8f\x15\xa9\xb2\xf5:~o\xf2/Qo\xd2%\xa8\xeb\x95\xec6\xb2\x00m_o\xdeF{k\x17Y\xca)\x1f\xc6\xddz\xb2\xefY;\x92\rxRI\xff\xd2\xc9\x05q\x1aHh\xaeI\xdf\xab\xc3\xc5)\xd5P\xe4\x82N\x0b\xfb\x81\x02\x82\x01\x00\x07\x9f\x0b\x02\xc5\xb4\xd2\xbdRy\xf4aq\xa3\xf5\xce\x17\r\xb6\x13\xf9\xed}\xbc\xf9\xfe\\\xb2\x8f\xee\x1f\xf4\xbb\xbe\x8d\xee:\xb4\xeb%\xbf2ya\x9f\x87\x88\xe0]\xa1\x9a{\xdd\xb5\x04,4V\xe8\xd1\xfd\'I\xc18\xedG\x88\xe1<\xd7\xda\x1b\x19\xef\xad\xc2{\x9e\x13\xdb\xc3%b\xe5\x12CJ\xc0F\xd1\xbd\xd4\xcd|\xff2I;mp\xaa\x05X\xf8\xedNI\x93\xca\x91\xd9\x83\x8e\x04\xe2|\xf5\xa1O\xfbq~;\xb0o\xb0-\x03\xca\x1a\xc25is\xb0F\xc0L\xe5U\xb20!g&c\xb9\x19\xc6[o8{\x87a\xfe<\xfb\x8c\xc4U\x18Bz\xe8D\xdfd9\x88\xe9\xfa\x9f|\x8f\x1f#U\xad\xbf\xe2\x17\x12\xd4\xff\x05\x83FV=\xab\x06x\xc6\xe4>?\x9aMFg\x85]K\xc2\xd4\x02\x88J\x87\x89`\x1a\xac\xcb\xa9\x03\x05\xcb^\xf5i\x00\xce%\x00H, \xa9~\xdd\x8e\x9b{,\x82\x04Z\x94\xd7\xd2\xbe\xd7\x94b\x1bJ*yP\x8c\xe76\xd4' +SERVER_PRIVATE_KEY = b'0\x82\x04\xa3\x02\x01\x00\x02\x82\x01\x01\x00\xc0\xfeF\x8d\x98\xdd9V\'\xab\xbd\xca\x99\x134\xb6S\xfb<\xe3\xf5\xf6\x11]\x10\xe6\xb9\xc3\x83[H:\xaf\x91s\x88=\xbc\x90L\xab+#$\xe8\xe4\xf3\xe0Du\xb1\x1a\xb9\x03 \xd3\xa4\xe2\xf8\xcd\x88\xcb\x9a\x98\xfe\xd8\xdb\xa5\na\x02\x81\x81\x00\xc2\xe7\x9e\xed\xc8?\x1a\xcd|}\xc8\xc8\rFZ\x96\x1a\x94\xaa\x86\xa0\xf8#\xec\x9b\xc6\x7fp\x9bQ\x1c\x01\xd1\x8b\xf5t\xdcp"Ug\x1fx\xc3\xfb\xb2Y\xd5Uh\xbd\xb1\xebE\xe8\x0f&\x08\x0bT\xe1\xa0b\x89\xa6rt@\xda\xc9f\x81\x85\xc7+\xca\xb5\x16\xdd\xc0D\x172XY/\xba\xa2\xb0H`\xe6M\\\xb5\x14\xea*@\xeeo\n\x03U\xe5\xdd\x8e&\xeb\x0e\xd7j\x1a\xe5{\xd2f"\xf9P\xa5M\xec \x82\x17-\xe5\x02\x81\x81\x00\xfd}C\x7f\xe7\xa44\x8e\x19AAA\xfa\x9a\xc6C\x8cy$g\xaam\xec\xdcz\xba\xba.\x1dVUz\xd1\x0c\xf4F\xd5D\x01\xb5v\x8d1\xbf\xeb\xea7\xbe}\xb3\x12A\xc5W\xac\x04\xf9\xffLu\xa8\x7fD$1+K\xcf\xab\x9b\x07=#\xf4\x91/\x8d`\xd4+\xec\xe1G\x0c\x08\xdc."\n|\xf2\xdf\x12Tf\x9fU\xd0\x9e\xea\xd5\xd8b\x85\x01=\x88\xb2\x04\x84\xc2z\xfb7\xacf\xc8[&\xabM\x11U\xbdBv\xda\xff\x02\x81\x80Z)e\xb6\xdf\xd4yd\xa7{T\x9f^\xac\xb6\t\x0c \xcb\xc5\xdd\xbf\x0cwO\x14\x83-\xa7[\xdd\x15\xe6F\xd5t\x8a\xe9\x00\xa8\xfb\x9a\x1c\x80zc\xaf\xd6\x0b:\xc8\xbc\x94\x95%\xa7\xd4\xd8\r\t7\xbb\xde1\xed\\\xf7\x12*\xe1\xbd\xff!\xee\x18L\xee\x13^', 'PublicKey': b'0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\x8d\x84\xd70\xdd\xec\xf5\x11"E\x84p\xfeD\xa4C\xad\x92u\xcb\xaa\t,\x99\x82\x02\xc2j\x8e\xae\x16\xbcx\x9f}\xab\xf9Zh\xb5\x85\x1cb8\x91\xab\xda>\x89\x1a\xa1\xef\xa8c\x0b\xf3\xde\xf6\xee#\xd2Z\xbc\xf2\xba)8\xd8\xc6\xba\xd6\x07\x13\xb8&\xa4|\xa1\x0c\xe0\xff\x19&\x8e\x9f,\x19x\xb5AS\xca\xd1Rj\x0c\x19,\xa3*DG\xa9?\x86H\xd8,^K\xd3\xf8w\xa5\x89&?\xba\xb6\x97\xa6>\xd7R\x00\x1f\xcc\xb9\xad\\\xfe\xcb.aUO-\x81\x14\x0f\xb78\xf6\x85j\x13\xc9\xe2\x12\xb0g\x88U>|\xe357\xf3\xe0O\xdb\x0cL\x89\xd8\xe5\x1dTw\xb9Vd~\xde\x0bg\xf8Q$_x\x0f\xcb\x04\xf4\x0cRF\xd1Er\xbe\xd8\x14\xf7@:\x9d\xdb!\x93\xa2\xecs`\xd4jU\xd2\xde\xa3\x9bd\x0f\xd8xY\x86q\x95;9\xdf\x87\xc7U\t\xde,\x1b\xc6\xf1\xb9uO\xc6\xf4\xe3&N\xccs\xb8I\xca\\h\xa2v\x8f\xa2\x13\x87@\x83\x02\x03\x01\x00\x01', 'Name': '0', 'NotAfter': 10000000000, 'Issuer': 'IssuerA', 'NotBefore': 1}, {'Signature': b"|\xc1U\xfe\x81\x92\xf9\x1c\xf2g\x86\xf3\xbb\x12\xb3\x1e\x9drt\xd6\xf3f*d\x86\x0f\x86\x00rQ\xec:\x13\xb4\x17\x9d\xa4\xef\xd1&\x7f\xee\xbc\x87\xdd\xc4\xe0\x87R\x7f\xcb\xa9\xabj\r!\x9d\x06pO?\xa2i\x14*\xae\xee\x9e\x1c\x13\xddV\xc0*\xe5\x06\xd4 \xa7)\xd2\r,\x93\xb0x\xcb\\\xe8+\xd6\xa7T\xe6\xe8\xefP\x0ee\xab\xca\x0b\xbbh\xf3\xdf\xb1\xc2\x02\x06z\xbf\x83#\xa2\xd5)>&\xdf\xf1\xbcm5$\x15wB\x84/L&\x1aA\xa2=\xae\xe2\x92\xab\xed\x1bP\x02c)5IT\xc1\xcft\xf1gb\x11\xd0\xa1p\xd3\xcei\xbe\xb8\xb3t\x06\xbf/\xd6$i\xc2\xfbO\xb2\x94]\x02\xa1\xf9\xfe\xec9\xd12!\x91\xea\xcb\x13\x0b\x7f\xd7\xfc\xac\xb8F\xe5\xd3\x7f\xee$\xc7?#\x07\x01\x8f\xf9\xb1\xaex\x87\x07Z#\x9e', 'NotBefore': 1, 'Name': 'IssuerA', 'PublicKey': b'0\x81\x9f0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x81\x8d\x000\x81\x89\x02\x81\x81\x00\xcddI\xe9\xcbV\xc2\x931\n+\xc5\xef\xcc\xeft\xf8\x01\xe8s\x12\xe2\r)\xf8\x81\xb9\x1e\xcc\x06!n\xff\xd0=\xf1\x92\xa6\xd0\xff\x91~s\xf9pY\xde\xc2\xe4\x8e`\xd2\x02\xe8\xf2r\xa7=\xdbFK\x9a\x02b\x1a\xcdP\x07\x92>GU\x1a?\x89\x96\x89\x99\xf3b\xe5<\xfdJY\xd2\xc4]W\xe9j\x87\xb4\x82\xe0\xa8c\xa7\x87\xe2(\xb0\xa6\xc2M>\xab\xb5r\xd8\xdf\x10\x1a\x07\xd6\xc0\t\xb0\xa3Ng\x1aD%\xab\xb52\xad\x02\x03\x01\x00\x01', 'NotAfter': 10000000000000, 'Issuer': 'IssuerA'}, ] diff --git a/AATC_Crypto.py b/AATC_Crypto.py index 481cbd0..5933aa4 100644 --- a/AATC_Crypto.py +++ b/AATC_Crypto.py @@ -1,5 +1,5 @@ #AATC crypto module -import codecs,recvall,ast,binascii,os,AATC_Config,time +import codecs,recvall,ast,binascii,os,AATC_Config,time,AATC_CryptoBeta from Crypto.Cipher import AES,PKCS1_OAEP from Crypto.PublicKey import RSA @@ -42,24 +42,17 @@ def GenerateKey(self,key_size = AATC_Config.DEFAULT_RSA_KEYSIZE): def ClientGenerateKey(self,RSA_KeySize,AES_KeySize= AATC_Config.DEFAULT_AES_KEYSIZE): - self.Send(("GetServerName",())) - Sucess,Message,Data = self.SplitData(self.Recv()) - if not Sucess: - raise ValueError("Server did not recognise command"+Message) - ServerName = Data[0] if AATC_Config.SET_ENCRYPTION_KEYS_ENABLE: #Allows preshared encryption keys to be used self.SetEncryptionKeys(AATC_Config.SET_AES_KEY, AATC_Config.SET_IV_KEY) elif AATC_Config.ENCRYPTION_USE_PRESHARED_KEYS: - self.ClientPreSharedKeys(ServerName,RSA_KeySize,AES_KeySize) + self.ClientPreSharedKeys(RSA_KeySize,AES_KeySize) else: self.ClientExchangeKeys(RSA_KeySize,AES_KeySize) - - self.Send(("Exit",())) Sucess,Message,Data = self.SplitData(self.Recv()) if not Sucess: @@ -67,13 +60,20 @@ def ClientGenerateKey(self,RSA_KeySize,AES_KeySize= AATC_Config.DEFAULT_AES_KEYS - def ClientPreSharedKeys(self,ServerName,RSA_KeySize,AES_KeySize): + def ClientPreSharedKeys(self,RSA_KeySize,AES_KeySize): + self.Send(("GetServerCertificateChain",())) + Sucess,Message,CertificateChain = self.SplitData(self.Recv()) + if not Sucess: + raise Exception("Server did not respond to command") + + + AESKey,IV = GenerateKeys(AES_KeySize) - Certificate = GetCertificates(ServerName) + PublicKey = AATC_CryptoBeta.VerifyCertificates(CertificateChain,AATC_Config.ROOT_CERTIFICATES) - if Certificate: - publicKey = Certificate["PublicKey"] - PKO = PKCS1_OAEP.new(RSA.import_key(publicKey)) + if PublicKey: + + PKO = PKCS1_OAEP.new(RSA.import_key(PublicKey)) EncryptedAESKey = PKO.encrypt(AESKey) EncryptedIV = PKO.encrypt(IV) self.SetEncryptionKeys(AESKey,IV) @@ -82,11 +82,11 @@ def ClientPreSharedKeys(self,ServerName,RSA_KeySize,AES_KeySize): else: - print("No Valid Certificates found") + print("Certificate Chain is not valid") if AATC_Config.AUTO_GENERATE_FALLBACK: self.ClientExchangeKeys(RSA_KeySize,AES_KeySize) else: - raise Exception("No valid certificate found. Exception raised") + raise Exception("Certificate Chain is not valid. Exception raised") @@ -123,8 +123,8 @@ def ServerGenerateKey(self): if Command == "GenerateKey": Sucess,Message,Data = self.ServerGenerateKeys(Arguments) - elif Command == "GetServerName": - Sucess,Message,Data = self.GetServerName(Arguments) + elif Command == "GetServerCertificateChain": + Sucess,Message,Data = self.GetServerCertificateChain(Arguments) elif Command == "SetKey": Sucess,Message,Data = self.ServerSetKey(Arguments) @@ -158,8 +158,8 @@ def ServerGenerateKeys(self,Arguments): self.SetEncryptionKeys(AESKey,IV) return True,"Instated encryption keys",[EncryptedAESKey,EncryptedIV] - def GetServerName(self,Arguments = None): - return True,"Server Name",[AATC_Config.SERVER_NAME] + def GetServerCertificateChain(self,Arguments = None): + return True,"Server Certificate Chain",AATC_Config.SERVER_CERTIFICATE_CHAIN def ServerSetKey(self,Arguments): PKO = PKCS1_OAEP.new(RSA.import_key(AATC_Config.SERVER_PRIVATE_KEY)) @@ -233,25 +233,4 @@ def GenerateKeys(AES_KeySize): IV = binascii.b2a_hex(os.urandom(AES_KeySize//2)) return AESKey,IV -def GetCertificates(ServerName): - Certificates = AATC_Config.CERTIFICATES.get(ServerName) - if Certificates == None: - return False - - found = False - for Certificate in Certificates: - if Validate(Certificate): - found = True - break - - if not found: - return False - - return Certificate - -def Validate(Certificate): - if Certificate["NotBefore"] <= time.time() and Certificate["NotAfter"] >= time.time(): - return True - else: - return False diff --git a/AATC_CryptoBeta.py b/AATC_CryptoBeta.py index 1e4771f..8b0ff93 100644 --- a/AATC_CryptoBeta.py +++ b/AATC_CryptoBeta.py @@ -1,5 +1,4 @@ -import codecs,recvall,ast,binascii,os,AATC_Config,time -from Crypto.Cipher import AES,PKCS1_OAEP +import time,codecs from Crypto.PublicKey import RSA from Crypto.Hash import SHA256 from Crypto.Signature import PKCS1_PSS @@ -21,12 +20,6 @@ def GenerateCertificate(Name,Issuer,NotBefore,NotAfter,PublicKey,IssuerPrivateKe Certificate["Signature"] = Signature return Certificate -def GetSignatureSource(Certificate): - SignatureSource = codecs.encode(str(Certificate["Name"]) + str(Certificate["Issuer"]) + str(Certificate["NotBefore"]) + str(Certificate["NotAfter"]) + str(hashlib.sha256(Certificate["PublicKey"]).hexdigest())) - return SignatureSource - - - def VerifyCertificates(CertificateChain,RootCertificates, Reverse = False): if Reverse: CertificateChain = CertificateChain[::-1] @@ -35,8 +28,9 @@ def VerifyCertificates(CertificateChain,RootCertificates, Reverse = False): Valid = False for RootCert in RootCertificates: if BaseCertificate["Issuer"] == RootCert["Name"]: - Valid = True - break + if ValidateCertificate(RootCert,RootCert["PublicKey"]): #Checks that root certificate is in time bounds and that is ok. + Valid = True + break if Valid and ValidateCertificate(BaseCertificate,RootCert["PublicKey"]): CurrentPublicKey = BaseCertificate["PublicKey"] @@ -47,7 +41,7 @@ def VerifyCertificates(CertificateChain,RootCertificates, Reverse = False): else: return False - + print("Valid Certificate Chain ") return CurrentPublicKey @@ -63,7 +57,9 @@ def ValidateCertificate(Certificate,IssuerPublicKey): return Valid_Signature - +def GetSignatureSource(Certificate): + SignatureSource = codecs.encode(str(Certificate["Name"]) + str(Certificate["Issuer"]) + str(Certificate["NotBefore"]) + str(Certificate["NotAfter"]) + str(hashlib.sha256(Certificate["PublicKey"]).hexdigest())) + return SignatureSource @@ -94,7 +90,8 @@ def CreateTestChain(length,RSA_KeySize,PRIVATE_KEY): cert = GenerateCertificate(x,Issuer,1,10000000000,puk,PRIVATE_KEY) Issuer = x PRIVATE_KEY = pk + print(cert,"\n\n Private Key :",pk,"\n"*2) chain.append(cert) - return chain + return chain,pk