Beispiel #1
0
 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__())
Beispiel #2
0
    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
Beispiel #3
0
    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])
Beispiel #4
0
    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)