def connection_made(self, transport): super().connection_made(transport) self.importKeys() self.state = self.STATE_CLIENT_HELLO self.clientNonce = self.generateNonce() self.dbgPrint( "Client: Sending Hello message, current state: {!r}, nonce number: {!r}".format(self.STATE_DESC[self.state], self.clientNonce)) # Serialize certs to pack into PlsHello certBytes = [CipherUtil.serializeCert(c) for c in self.certs] helloPkt = PlsHello.makeHelloPacket(self.clientNonce, certBytes) self.messages["M1"] = helloPkt.__serialize__() self.transport.write(helloPkt.__serialize__())
def connection_made(self, transport): self.log("Connection made at SITH layer on " + type(self.higherProtocol()).__name__) self.transport = transport self.peerAddress = transport.get_extra_info('peername') super().connection_made(transport) self.importClientCerts() self.state = self.STATE_CLIENT_HELLO self.log( "Client: Sending Hello message, current state: {!r}, random: {!r}". format(self.STATE_DESC[self.state], self.random)) self.certBytes = [CipherUtil.serializeCert(c) for c in self.certs] helloPkt = SITHPacket.makeHelloPacket(self.random, self.certBytes, self.public_key) self.messages["M1"] = helloPkt.__serialize__() self.transport.write(helloPkt.__serialize__()) #send client hello pkt
def data_received(self, data): self.deserializer.update(data) for pkt in self.deserializer.nextPackets(): if isinstance(pkt, PlsHello) and self.state == self.STATE_SERVER_HELLO: # Deserialize certs in packet, attach root cert peerCerts = [CipherUtil.getCertFromBytes(c) for c in pkt.Certs] if self.verifyCerts(peerCerts): self.dbgPrint("Server: PlsHello received!") self.messages["M1"] = pkt.__serialize__() self.peerPublicKey = peerCerts[0].public_key() self.clientNonce = pkt.Nonce # Make PlsHello and send back self.serverNonce = self.generateNonce() # Serialize certs to pack into PlsHello certBytes = [CipherUtil.serializeCert(c) for c in self.certs] self.dbgPrint("Server: sending PlsHello back to client... Current state: {!r}, nonce Number: {!r}" .format(self.STATE_DESC[self.state], self.serverNonce)) helloPkt = PlsHello.makeHelloPacket(self.serverNonce, certBytes) self.messages["M2"] = helloPkt.__serialize__() self.transport.write(helloPkt.__serialize__()) self.state = self.STATE_SERVER_KEY_EXCHANGE else: self.handleError("Error: certificate verification failure.") elif isinstance(pkt, PlsKeyExchange) and self.state == self.STATE_SERVER_KEY_EXCHANGE: if self.serverNonce + 1 == pkt.NoncePlusOne: self.dbgPrint("Server: received PlsKeyExchange packet from client") self.messages["M3"] = pkt.__serialize__() self.clientPreKey = self.privateKey.decrypt( pkt.PreKey, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None ) ) if len(self.clientPreKey) != self.PRE_KEY_LENGTH_BYTES: self.handleError("Error: Bad client pre-key with length = " + str(len(self.clientPreKey) * 8) + " bits, wrong RSA decryption?") else: self.dbgPrint("Server: client prekey received: " + self.clientPreKey.hex()) # Make PlsKeyExchange and send back self.serverPreKey = self.generatePreKey() self.dbgPrint( "Server: sending plsKeyExchange packet, prekey: {!r}".format(self.serverPreKey.hex())) encryptedPreKey = self.peerPublicKey.encrypt( self.serverPreKey, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA1()), algorithm=hashes.SHA1(), label=None ) ) plsKeyExchangePkt = PlsKeyExchange.makePlsKeyExchange(encryptedPreKey, self.clientNonce + 1) self.messages["M4"] = plsKeyExchangePkt.__serialize__() self.transport.write(plsKeyExchangePkt.__serialize__()) self.state = self.STATE_SERVER_PLS_HANDSHAKE_DONE # Enough info to generate keys and initialize ciphers self.setKeys(self.generateDerivationHash()) self.setEngines() else: self.handleError("Error: bad nonce in key exchange.") elif isinstance(pkt, PlsHandshakeDone) and self.state == self.STATE_SERVER_PLS_HANDSHAKE_DONE: if self.verifyValidationHash(pkt.ValidationHash): self.dbgPrint("Server: plsHandshakeDone packet received from client.") self.dbgPrint( "Server: sending plsHandshakeDone to client and notifying upper layer connection_made") hashText = self.generateValidationHash() handshakeDonePkt = PlsHandshakeDone.makePlsHandshakeDone(hashText) self.transport.write(handshakeDonePkt.__serialize__()) # Enter transmission self.state = self.STATE_SERVER_TRANSFER higherTransport = PLSTransport(self.transport, self) self.higherProtocol().connection_made(higherTransport) else: self.handleError("Error: validation hash verification failure.") elif isinstance(pkt, PlsData) and self.state == self.STATE_SERVER_TRANSFER: self.dbgPrint("Server: received application data from client, decrypt and notify upper layer") if self.verifyPlsData(pkt.Ciphertext, pkt.Mac): self.dbgPrint("Verification succeeded, sending data to upper layer...") self.higherProtocol().data_received(self.decrypt(pkt.Ciphertext)) else: # self.handleError("Error: data verification failure.") self.dbgPrint("Data MAC verification error, discarded.") elif isinstance(pkt, PlsClose): self.dbgPrint("PlsClose received, closing...") self.transport.close() else: self.handleError("Error: wrong packet type " + pkt.DEFINITION_IDENTIFIER + ", current state " + self.STATE_DESC[self.state])
def data_received(self, data): self.deserializer.update(data) for pkt in self.deserializer.nextPackets(): if isinstance( pkt, SITHPacket ): # judge if this packet is an instance of RIPPPacket if (pkt.Type == "HELLO") and ( self.state == self.STATE_SERVER_HELLO): #receive client hello pkt # Deserialize certs in packet, attach root cert self.peerCerts = [ CipherUtil.getCertFromBytes(c) for c in pkt.Certificate ] if self.verifyCerts(self.peerCerts): self.log("Server: SithHello received!") self.messages["M1"] = pkt.__serialize__( ) #turn the client's hello pkt into bytes self.peerPublicKey = self.peerCerts[0].public_key() # Serialize certs to pack into SithHello self.certBytes = [ CipherUtil.serializeCert(c) for c in self.certs ] self.log( "Server: sending SithHello back to client... Current state: {!r}, random: {!r}" .format(self.STATE_DESC[self.state], self.random)) helloPkt = SITHPacket.makeHelloPacket( self.random, self.certBytes, self.public_key) self.messages["M2"] = helloPkt.__serialize__( ) #turn the server's hello pkt into bytes self.transport.write( helloPkt.__serialize__() ) #send the server hello pkt and enter 'server_key_exchange' stage self.state = self.STATE_SERVER_KEY_EXCHANGE #key derivation self.client_public_key = x25519.X25519PublicKey.from_public_bytes( pkt.PublicValue ) #load client's public key from bytes shared_secret = self.private_key.exchange( self.client_public_key) hasher = hashes.Hash(hashes.SHA256(), backend=default_backend()) hasher.update(self.messages["M1"] + self.messages["M2"]) self.hash_msg = hasher.finalize() #get the hash result derived_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=self.hash_msg, backend=default_backend()).derive( shared_secret) #get the derived key self.iv_dec = derived_key[:12] self.iv_enc = derived_key[12:24] self.server_write = derived_key[:16] self.server_read = derived_key[16:] self.setEngines() self.state = self.STATE_SERVER_SITH_HANDSHAKE_DONE else: self.log("Error: certificate verification failure.") self.sendSithClose(1) elif (pkt.Type == "FINISH") and ( self.state == self.STATE_SERVER_SITH_HANDSHAKE_DONE): self.log( "Server: received handshake_finish packet from client") #verify client's signature client_public_key = self.peerCerts[0].public_key() client_signature = pkt.Signature verify_result = self.verify_signature( client_public_key, client_signature, self.hash_msg) if not verify_result: self.log("Server: wrong signature of client!") self.log("Server is closing...") self.sendSithClose(1) else: # generate handshake finish pkt self.cert_private_key = getServerPrivateKey( ) # read private of server's certificate finishPkt = SITHPacket.makeFinishPacket( self.messages["M1"], self.messages["M2"], self.cert_private_key) self.transport.write( finishPkt.__serialize__() ) # send the server hello pkt and enter 'server_key_exchange' stage #enter the data transmission state self.state = self.STATE_SERVER_TRANSFER higherTransport = SITHTransport(self.transport, self) self.higherProtocol().connection_made(higherTransport) # Enter transmission higherTransport = SITHTransport(self.transport, self) self.higherProtocol().connection_made(higherTransport) elif (pkt.Type == "DATA") and self.state == self.STATE_SERVER_TRANSFER: self.log( "Server: received application data from client, decrypt and notify upper layer" ) self.log( "Verification succeeded, sending data to upper layer..." ) self.higherProtocol().data_received( self.decrypt(self.iv_dec, pkt.Ciphertext, None)) elif (pkt.Type == "CLOSE"): self.transport.close() else: self.log("Error: wrong packet type " + pkt.DEFINITION_IDENTIFIER + ", current state " + self.STATE_DESC[self.state]) self.sendSithClose(1) else: self.log("Wrong packet class type: {!r}".format(str( type(pkt)))) self.sendSithClose(1)