def findsharedKEY(self, peer_public):
     shared_key = self.private_key.exchange(ec.ECDH(), peer_public)
     return shared_key
Beispiel #2
0
def on_message(client, userdata, msg):
    global name
    global mode
    global asymmetric_mode
    global symmetric_mode
    global b_public_key
    global b_public_key_ecdh
    global a_shared_key
    global f_key
    global a_key
    global h
    global hmac_key
    print(msg.topic + " -> " + str(msg.payload.decode()))

    # Connection message
    if (msg.topic == "connection"):
        print("Connection message.")

        # Initialize some variables
        name = str(msg.payload.decode()).split(":")[0]
        mode = str(msg.payload.decode()).split(":")[1]
        asymmetric_mode = int(str(msg.payload.decode()).split(":")[2])
        symmetric_mode = int(str(msg.payload.decode()).split(":")[3])

        # Save the variables for each device
        names.append(name)
        modes.append(mode)
        asymmetric_modes.append(asymmetric_mode)
        symmetric_modes.append(symmetric_mode)

        # Key exchange
        if (asymmetric_mode == 0):
            client.publish(name + "/to", "param:" + str(params_pem, 'ascii'))
            client.publish(name + "/to",
                           "public:" + str(a_public_key.public_numbers().y))
        else:
            client.publish(
                name + "/to", "public:" + a_public_key_ecdh.public_bytes(
                    encoding=Encoding.PEM,
                    format=PublicFormat.SubjectPublicKeyInfo).decode())
        client.subscribe(name + "/from")
        print("Public key sent to device.")

        # Show the information on web page
        data = {
            "type": "conexion_dispositivo",
            "payload": msg.payload.decode()
        }
        server.send_message_to_all(json.dumps(data))

    # Message from a device that has already connected
    else:

        # Topic = <Device name>/from
        name = str(msg.topic).split("/")[0]
        if (msg.topic == (name + "/from")):

            # Receive device public key
            if (str(msg.payload.decode()).split(":")[0] == "public"):

                # If we know its old public key, we upload it
                try:
                    public_keys.pop(names.index(name))
                    shared_keys.pop(names.index(name))
                    fernet_keys.pop(names.index(name))
                    aead_keys.pop(names.index(name))
                    print("Public key uploaded from device.")

                # If we don't know its public key, we save it
                except IndexError:
                    # If the device has 'output' or nothing
                    if (int(mode) > 0):
                        # HMAC key will be introduced on web page
                        data = {"type": "hmac", "name": name, "mode": mode}

                    # If the device has just 'input'
                    else:
                        # HMAC key will be introduced on device
                        hmac_key = str(os.urandom(2).hex())
                        data = {
                            "type": "hmac",
                            "name": name,
                            "mode": mode,
                            "hmac_key": hmac_key
                        }

                    # Show the correspondent information on web page
                    server.send_message_to_all(json.dumps(data))

                    print("New public key from device.")

                # DH key exchange
                if (asymmetric_modes[names.index(name)] == 0):
                    b_public_key_number = int(
                        str(msg.payload.decode()).split(":")[1])
                    peer_public_numbers = dh.DHPublicNumbers(
                        b_public_key_number, parameters.parameter_numbers())
                    b_public_key = peer_public_numbers.public_key(
                        default_backend())
                    public_keys.insert(names.index(name), b_public_key)
                    a_shared_key = a_private_key.exchange(b_public_key)

                # ECDH key exchange
                else:
                    b_public_key_number = str(
                        msg.payload.decode()).split(":")[1]
                    b_public_key_ecdh = load_pem_public_key(
                        b_public_key_number.encode())
                    a_shared_key = a_private_key_ecdh.exchange(
                        ec.ECDH(), b_public_key_ecdh)

                print("Shared key calculated.")
                # Save the shared key
                shared_keys.insert(names.index(name), a_shared_key)

                # We fix the shared key for Fernet using HASH and save it
                derived_key_fernet = HKDF(
                    algorithm=hashes.SHA256(),
                    length=32,
                    salt=None,
                    info=b'handshake data').derive(a_shared_key)
                key_fernet = base64.urlsafe_b64encode(derived_key_fernet)
                f_key = Fernet(key_fernet)
                fernet_keys.insert(names.index(name), f_key)

                # We fix the shared key for AEAD using HASH and save it
                derived_key_aead = HKDF(
                    algorithm=hashes.SHA256(),
                    length=24,
                    salt=None,
                    info=b'handshake data').derive(a_shared_key)
                key_aead = base64.urlsafe_b64encode(derived_key_aead)
                a_key = aead.AESGCM(key_aead)
                aead_keys.insert(names.index(name), a_key)

            # Receive HMAC from device
            elif (str(msg.payload.decode()).split(":")[0] == "hmac"):

                # Save received HMAC
                print("HMAC recibida del dispositivo.")
                h = str(msg.payload.decode()).split(":")[1]

                # If the device has just 'input'
                if (int(mode) == 0):
                    # DH or ECDH
                    if (asymmetric_mode == 0):
                        h2 = hmac.new(
                            bytes(hmac_key, 'ascii'),
                            bytes(str(b_public_key.public_numbers().y),
                                  'ascii'), hashlib.sha256)
                    else:
                        h2 = hmac.new(
                            bytes(hmac_key, 'ascii'),
                            b_public_key_ecdh.public_bytes(
                                encoding=Encoding.PEM,
                                format=PublicFormat.SubjectPublicKeyInfo),
                            hashlib.sha256)

                    # Compare HMAC
                    if (hmac.compare_digest(h, h2.hexdigest())):
                        hmacs.append(True)
                        data = {
                            "type": "datos_dispositivos",
                            "name": name,
                            "mode": mode
                        }
                        # Device will be added on web page if HMAC is correct
                        server.send_message_to_all(json.dumps(data))
                        print("HMAC de " + name +
                              " coincide. Añadiendo dispositivo...")
                    else:
                        hmacs.append(False)
                        # Unsubscribe
                        client.unsubscribe(name + "/from")
                        print("HMAC de " + name +
                              " no coincide. Dispositivo expulsado.")

            # Receive message from device
            elif (str(msg.payload.decode()).split(": ")[0] == "message"):
                message = str(msg.payload.decode()).split(": ")[1]

                # Fernet or AEAD
                if (symmetric_modes[names.index(name)] == 0):
                    message = fernet_keys[names.index(name)].decrypt(
                        message.encode())
                else:
                    message = aead_keys[names.index(name)].decrypt(
                        b"12345678", message.encode('latin-1'), None)
                print("Message from " + name + ": " + message.decode())

                # Show the correspondent information on web page
                data = {
                    "type": "message",
                    "name": name,
                    "payload": message.decode()
                }  # model data
                server.send_message_to_all(json.dumps(data))
Beispiel #3
0
 def generatesharedkey(self, pem: bytes):
     self.sharedkey = self.__privkey.exchange(ec.ECDH(), self.pem2key(pem))
     self.derivedkey = HKDF(algorithm=hashes.SHA256(),
                            length=16,
                            salt=None,
                            info=b'key exchange').derive(self.sharedkey)
Beispiel #4
0
    def process(self, packet):
        print("Process")
        if not self.shared_secret:
            print("shared secret not computed")
            received_public_key = deserializeKey(packet.pk)
            received_cert = x509.load_pem_x509_certificate(
                packet.cert, default_backend())
            received_cert_key = received_cert.public_key()
            self.received_key = received_cert_key

        if packet.nonceSignature is not FIELD_NOT_SET:
            # Verify nonce signature
            try:
                print("Verifying nonce")
                self.received_key.verify(
                    packet.nonceSignature,
                    str(self.nonce).encode(),
                    padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                salt_length=padding.PSS.MAX_LENGTH),
                    hashes.SHA256())
            except Exception as e:
                return createPacket(HandshakePacket,
                                    status=HandshakePacket.ERROR)

        # Generate nonce signature
        if self.shared_secret:
            self.complete = True
            return None

        if packet.signature is not FIELD_NOT_SET:
            try:
                print("verifying signature")
                self.received_key.verify(
                    packet.signature, packet.pk,
                    padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                salt_length=padding.PSS.MAX_LENGTH),
                    hashes.SHA256())

            except Exception as e:
                print("Not Verified?")
                print('There has been an error. Sending error.')
                return createPacket(HandshakePacket,
                                    status=HandshakePacket.ERROR)

        # print("Verified?")

        print("nonce Verified. Signing nonce ")
        nonceSignature = (self.signing_key).sign(
            str(packet.nonce).encode(),
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())
        self.shared_key = self.private_key.exchange(ec.ECDH(),
                                                    received_public_key)
        self.shared_secret = True
        if self.received_init:
            self.complete = True
            print("client handshake completed")
            return self.send_success(nonceSignature)
        else:
            print("crap Server got first packet")
            serialized_cert_bytes = self.cert.public_bytes(
                serialization.Encoding.PEM)
            serialized_server_public_key = serializeKey(self.public_key)
            return self.send_key(serialized_server_public_key,
                                 serialized_cert_bytes, nonceSignature)
Beispiel #5
0
def generate_master_secret(public_key, private_key):
    shared_key = private_key.exchange(ec.ECDH(), public_key)
    return shared_key
Beispiel #6
0
 def exchange_shared_key(self, pubkey):
     # # used in ECDHAlgorithm
     if isinstance(self.raw_key, EllipticCurvePrivateKeyWithSerialization):
         return self.raw_key.exchange(ec.ECDH(), pubkey)
     raise ValueError('Invalid key for exchanging shared key')
    #Seek to the beginning of the session len
    f.seek(0x1A5 + pdh_len)
    session_len = int.from_bytes(f.read(4), 'big')

    # Read session data
    f.seek(0x1A5 + 4 + pdh_len)
    session_data = f.read(session_len)

    begin_chunk = 0x1A5 + 4 + pdh_len + session_len
    print(hex(begin_chunk))


# DH Static Unified Model - Section 2.2.2 AMD SEV API
print("Deriving shared secret")
shared_secret = pdh_priv.exchange(ec.ECDH(), remote_pdh)

# Get session data
nonce = session_data[:0x10]
wrapped_tk = session_data[0x10:0x30]
iv = session_data[0x30:0x40]
hmac_tk = session_data[0x40:0x60]
hmac_policy = session_data[0x60:0x80]

print("Deriving master secret, key-encryption-key (KEK) and key-integrity-key (KIK)")
master_secret = derive_secret(shared_secret,b'sev-master-secret',nonce)
kek = derive_secret(master_secret,b'sev-kek',None)
kik = derive_secret(master_secret,b'sev-kik',None)

calc_hmac = hmac.HMAC(kik, hashes.SHA256(), backend=default_backend())
    encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo).decode()

count = 1

# ECDHE

ecdh_data = {'pub_key': deepvault_public_key_pem_spki, 'counter': count}
count += 1

auth_post = requests.post(deepapi_host + '/auth',
                          headers=headers,
                          data=json.dumps(ecdh_data))
deepapi_public_key = load_pem_public_key(auth_post.json()['pub_key'].encode(),
                                         default_backend())

shared_secret = deepvault_private_key.exchange(ec.ECDH(), deepapi_public_key)

# challenge-response

iv = secrets.token_bytes(16)

salt = secrets.token_bytes(32)
iterations = 150000

kdf = PBKDF2HMAC(
    algorithm=SHA512(),
    length=32,  # 32 * 8 = 256 bits
    salt=salt,
    iterations=iterations,
    backend=default_backend())
 def test_elliptic_curve_exchange_algorithm_supported(self, monkeypatch):
     monkeypatch.setattr(backend, "_lib", DummyLibrary())
     assert not backend.elliptic_curve_exchange_algorithm_supported(
         ec.ECDH(), ec.SECP256R1())
Beispiel #10
0
def generate_dh_key(private_key, public_key):
    shared_key = private_key.exchange(ec.ECDH(), public_key)
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(shared_key)
    return digest.finalize()
Beispiel #11
0
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from pwn import *

p = process("challenge.py")

client_sk = ec.generate_private_key(ec.SECP384R1(), default_backend())
client_pk = client_sk.public_key()
client_der = client_pk.public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo)

res = p.recvuntil("Send your public key (hex):")
server_der = res.split("\n")[1].decode("hex")

server_pk = serialization.load_der_public_key(server_der, default_backend())
shared_key = client_sk.exchange(ec.ECDH(), server_pk)
derived_key = HKDF(algorithm=hashes.SHA256(),
                   length=16,
                   salt=None,
                   info=b"handshake data",
                   backend=default_backend()).derive(shared_key)

p.sendline(client_der.encode('hex'))
res = p.recvuntil("Please, prove you know stuffs: ")
msg = process(["collide.py",
               derived_key.encode("hex")]).recvall().split("\n")[1]
p.sendline(msg)
flag = p.recvall()
print(flag)
Beispiel #12
0
    def post(self, request, eid, tok, format=None):
        # Verify that the employee ID exists
        tokR = settings.REDIS_CONN.get(eid)
        if tokR is None:
            return Response(False)
        #  TokR is not None
        if not isinstance(tokR, bytes):
            return Response(False)

        # TokR is a bytes buffer
        if tokR.decode('utf-8') == tok:
            request = loads(request.body)
            salt = b64decode(tok)
            EncData = b64decode(request['data'])

            loaded_public_key = serialization.load_pem_public_key(
                b64decode(request['pub']), backend=default_backend())

            loaded_private_key = serialization.load_pem_private_key(
                b64decode(settings.REDIS_CONN.get(eid + "pvt")),
                # or password=None, if in plain text
                password=None,
                backend=default_backend())

            shared_key = loaded_private_key.exchange(ec.ECDH(),
                                                     loaded_public_key)

            kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                             length=32,
                             salt=salt,
                             iterations=100000,
                             backend=default_backend())

            AESkey = kdf.derive(shared_key)

            DecData = self.DecAES(AESkey, EncData)
            DecDataJSON = loads(DecData)
            OTP = DecDataJSON['OTP']
            if HCenterEmployee.objects.filter(EmployeeID=eid).exists():
                EmpObj = HCenterEmployee.objects.get(EmployeeID=eid)
                # Generate a Session Token for Employee and return it
                # Hash a random number
                config.InputTemplate['uid'] = EmpObj.Data['UID']
                config.InputTemplate["bio_dict"]["FMR"] = {
                    "LEFT_THUMB": DecDataJSON["BIO"]
                }
                res = AuthInit(config.InputTemplate, OTP)
                if res.get('actn') == "RETRY":
                    res = AuthInit(config.InputTemplate, OTP)
                if res.get('ret') == "Y":
                    # Employee Verification complete
                    # In redis save EID + "auth" = Txn ID of AuthInit response
                    settings.REDIS_CONN.set(eid + "auth", res.get('txn'),
                                            10 * 3600)  # Valid for 10 hours.
                    # Create a new token Encrypt it with the AESkey and return in response a newcreated Token
                    # From this point on after recieving this token HealthCenter will request Sessions from Auth Channel
                    # from Session Server
                    tok = sha256(urandom(128)).hexdigest()
                    settings.REDIS_CONN.set(
                        eid + "authed", tok,
                        3600)  # One Token is valid for One Hour.
                    return Response(tok)
                else:
                    return Response(False)
        return Response(False)
Beispiel #13
0
    def process(self, msg):
        if (self.msg_cnt == 0):

            self.server_private_key = ec.generate_private_key(
                ec.SECP256K1(), default_backend())

            self.server_public_key = self.server_private_key.public_key()

            new_msg = {
                "pubKey":
                self.server_public_key.public_bytes(
                    Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
            }

            msg = new_msg

            self.msg_cnt += 1

        elif (self.msg_cnt == 1):

            msg = msg.decode()

            msg_dict = ast.literal_eval(msg)

            nounce = msg_dict['nounce']
            key = msg_dict['key']
            ciphertext = msg_dict['ct']
            signature = msg_dict['sign']
            pub_key = msg_dict['pub_key']

            self.client_public_key = load_der_public_key(
                pub_key, backend=default_backend())

            self.shared_key = self.server_private_key.exchange(
                ec.ECDH(), self.client_public_key)

            cip = ChaCha20Poly1305(key)

            try:
                self.client_public_key.verify(signature, ciphertext,
                                              ec.ECDSA(hashes.SHA256()))
                message = cip.decrypt(nounce, ciphertext, None)
                print('%d : %r' % (self.id, message.decode('utf-8')))

            except:
                print("Error while decrypt")

            self.msg_cnt += 1
        else:

            msg = msg.decode()

            msg_dict = ast.literal_eval(msg)

            nounce = msg_dict['nounce']
            key = msg_dict['key']
            ciphertext = msg_dict['ct']
            signature = msg_dict['sign']

            cip = ChaCha20Poly1305(key)

            try:
                self.client_public_key.verify(signature, ciphertext,
                                              ec.ECDSA(hashes.SHA256()))
                message = cip.decrypt(nounce, ciphertext, None)
                print('%d : %r' % (self.id, message.decode('utf-8')))

            except:
                print("Error while decrypt")

            self.msg_cnt += 1

        print('NEXT!')
        return msg if len(msg) > 0 else None
Beispiel #14
0
    def compute_sharedKey(self, pubk, privk):
        #deserialize pubkA
        publicKey = load_pem_public_key(pubk, default_backend())

        shared_key = privk.exchange(ec.ECDH(), publicKey)
        return shared_key
Beispiel #15
0
 def create_e_share_key(self, pub_key, private_key):
     return private_key.exchange(ec.ECDH(), pub_key)
Beispiel #16
0
    def process(self, packet):
        print("Handshake Process")
        if not self.shared_secret:

            received_public_key = deserializeKey(packet.pk)
            received_cert = deserializeCert(packet.cert)
            received_cert_key = getKeyFromCert(received_cert)
            self.received_key = received_cert_key

        if packet.nonceSignature is not FIELD_NOT_SET:
            # Verify nonce signature
            try:
                # print("Verifying nonce")
                self.received_key.verify(
                    packet.nonceSignature,
                    str(self.nonce).encode(),
                    padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                salt_length=padding.PSS.MAX_LENGTH),
                    hashes.SHA256())
            except Exception as e:
                # print("Nonce not Verified?")
                # print('There has been an error. Sending error.')
                return createPacket(HandshakePacket,
                                    status=HandshakePacket.ERROR)

        # Generate nonce signature
        if self.shared_secret:
            # print("crap Server got second packet")
            print("server handshake completed")
            self.complete = True
            return None

        # print(packet.pk)
        if packet.signature is not FIELD_NOT_SET:
            try:
                # print("verifying signature")
                self.received_key.verify(
                    packet.signature, packet.pk,
                    padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                salt_length=padding.PSS.MAX_LENGTH),
                    hashes.SHA256())
            except Exception as e:
                # print("Not Verified?")
                # print('There has been an error. Sending error.')
                return createPacket(HandshakePacket,
                                    status=HandshakePacket.ERROR)

        for certBytes in packet.certChain:
            cert = deserializeCert(certBytes)
            print(received_cert)
            received_cert_address = received_cert.subject.get_attributes_for_oid(
                NameOID.COMMON_NAME)[0]._value
            cert_address = cert.subject.get_attributes_for_oid(
                NameOID.COMMON_NAME)[0]._value
            # print("received cert", received_cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0]._value)
            # print("chain cert", cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0]._value)
            if not cert_address.startswith(
                    "20194") and not received_cert_address.startswith(
                        cert_address):
                # print("CA verification failed")
                return createPacket(HandshakePacket,
                                    status=HandshakePacket.ERROR)

        nonceSignature = (self.signing_key).sign(
            str(packet.nonce).encode(),
            padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                        salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())
        self.shared_key = self.private_key.exchange(ec.ECDH(),
                                                    received_public_key)
        self.shared_secret = True
        if self.received_init:
            self.complete = True
            print("client handshake completed")
            return self.send_success(nonceSignature)
        else:
            # print("crap Server got first packet")
            serialized_cert_bytes = self.cert.public_bytes(
                serialization.Encoding.PEM)
            serialized_server_public_key = serializeKey(self.public_key)
            return self.send_key(serialized_server_public_key,
                                 serialized_cert_bytes, nonceSignature)
def decryptSalsa(message, key):

    message = str(message.data) #Converts the message's ciphertext to a string
    message = message.split("SPACE") #Splits the message by the word 'SPACE' to seperate the peer public key and ciphertext message


    peer_public_key = message[0] #Assigns the portion before SPACE to variable peer_public_key

    loaded_public_key = serialization.load_pem_public_key(peer_public_key, backend=default_backend()) #Unserialized the peer public key so that is usable for decryption

    ciphertext = message[1] #Assigns the portion after SPACE to variable ciphertext
 


ros services
    shared_key = key.exchange(ec.ECDH(), loaded_public_key) #Generates a shared key using the local private key and the senders public key

    derived_key = HKDF( #Derives key to be used for decryption from shared key
        algorithm=hashes.SHA256(),
        length=32,
        salt=None,
        info=None,
        backend=default_backend()
    ).derive(shared_key) 
     



    msg_nonce = ciphertext[:8] #Seperates the nonce from the ciphertext
    cipher_text = ciphertext[8:] #Seperates the cipher text from the nonce
Beispiel #18
0
def derive():
    for i in range(2):
        digest = hashlib.sha256(private.exchange(ec.ECDH(), peer[i])).digest()
        shared_key.append(
            Cipher(algorithms.AES(digest), modes.CBC(b'0' * 16),
                   default_backend()))
Beispiel #19
0
def encrypt_payload(message, client_pub_key, auth):
    """
    This is quite a bit but for more information I wrote
    a blog post https://blog.vihan.org/the-push-protocol/

    Brief overview is we take our private and client public key
    which are ECC keys on the P-256 NIST curve and we perform a
    diffie-hellman (ECDH) key exchange to obtain a shared
    secret to generate a HKDF key which is derived with various
    content types to obtain the encryption parameters for an
    AES-128-GCM cipher.

    :param bytes message: Binary message
    :param bytes client_pub_key:
    :param bytes auth:
    """

    # const salt = crypto.randomBytes(16);
    salt = urandom(16)

    # const localKeysCurve = crypto.createECDH('prime256v1');
    # localKeysCurve.generateKeys();
    # const localPrivateKey = localKeysCurve.getPrivateKey();
    local_private_key = ec.generate_private_key(ec.SECP256R1,
                                                default_backend())

    # const localPublicKey = localKeysCurve.getPublicKey();
    local_public_key = local_private_key.public_key()
    local_public_key_bytes = local_public_key.public_numbers().encode_point()

    # const sharedSecret = localKeysCurve.computeSecret(subscription.keys.p256dh, 'base64')
    shared_secret = local_private_key.exchange(
        ec.ECDH(),
        ec.EllipticCurvePublicNumbers.from_encoded_point(
            ec.SECP256R1(), client_pub_key).public_key(default_backend()))

    # const authEncBuff = new Buffer('Content-Encoding: auth\0', 'utf8');
    # const prk = hkdf(subscription.keys.auth, sharedSecret, authEncBuff, 32);
    #                  salt                    ikm           info         length
    prk = HKDF(algorithm=hashes.SHA256(),
               length=32,
               salt=auth,
               info=b'Content-Encoding: auth\0',
               backend=default_backend()).derive(shared_secret)

    server_pub_key = get_public_key()

    # This is context which happens to be appended to end
    # of all the things
    context = b'P-256\0' + pack('!H', len(client_pub_key)) + client_pub_key +\
        pack('!H', len(local_public_key_bytes)) + local_public_key_bytes

    # This is something that cipher needs idk im not
    # crypto genius
    nonce = HKDF(algorithm=hashes.SHA256(),
                 length=12,
                 salt=salt,
                 info=b'Content-Encoding: nonce\0' + context,
                 backend=default_backend()).derive(prk)

    # CEK = Content Encryption Key
    # this goes into AES
    cek = HKDF(algorithm=hashes.SHA256(),
               length=16,
               salt=salt,
               info=b'Content-Encoding: aesgcm\0' + context,
               backend=default_backend()).derive(prk)

    cipher = Cipher(algorithms.AES(cek), modes.GCM(nonce), default_backend())
    encryptor = cipher.encryptor()
    payload = pack('!H', 0) + message
    encrypted_payload = encryptor.update(
        payload) + encryptor.finalize() + encryptor.tag

    return encrypted_payload, local_public_key_bytes, salt
    def test_elliptic_curve(self):
        backend = MultiBackend([
            DummyEllipticCurveBackend([
                ec.SECT283K1
            ])
        ])

        assert backend.elliptic_curve_supported(ec.SECT283K1()) is True

        assert backend.elliptic_curve_signature_algorithm_supported(
            ec.ECDSA(hashes.SHA256()),
            ec.SECT283K1()
        ) is True

        backend.generate_elliptic_curve_private_key(ec.SECT283K1())

        backend.load_elliptic_curve_private_numbers(
            ec.EllipticCurvePrivateNumbers(
                1,
                ec.EllipticCurvePublicNumbers(
                    2,
                    3,
                    ec.SECT283K1()
                )
            )
        )

        backend.load_elliptic_curve_public_numbers(
            ec.EllipticCurvePublicNumbers(
                2,
                3,
                ec.SECT283K1()
            )
        )

        assert backend.elliptic_curve_supported(ec.SECT163K1()) is False

        assert backend.elliptic_curve_signature_algorithm_supported(
            ec.ECDSA(hashes.SHA256()),
            ec.SECT163K1()
        ) is False

        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
            backend.generate_elliptic_curve_private_key(ec.SECT163K1())

        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
            backend.load_elliptic_curve_private_numbers(
                ec.EllipticCurvePrivateNumbers(
                    1,
                    ec.EllipticCurvePublicNumbers(
                        2,
                        3,
                        ec.SECT163K1()
                    )
                )
            )

        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE):
            backend.load_elliptic_curve_public_numbers(
                ec.EllipticCurvePublicNumbers(
                    2,
                    3,
                    ec.SECT163K1()
                )
            )

        assert backend.elliptic_curve_exchange_algorithm_supported(
            ec.ECDH(), ec.SECT283K1()
        )
        backend2 = MultiBackend([DummyEllipticCurveBackend([])])
        assert not backend2.elliptic_curve_exchange_algorithm_supported(
            ec.ECDH(), ec.SECT163K1()
        )

        with pytest.raises(UnsupportedAlgorithm):
            backend.derive_elliptic_curve_private_key(123, DummyCurve())

        assert backend.derive_elliptic_curve_private_key(
            123, ec.SECT283K1()) is None
Beispiel #21
0
sock.send(struct.pack("!i", blksz))

privkey = peer_public_key = ec.generate_private_key(ec.SECP384R1(),
                                                    default_backend())

sock.send(privkey.public_key().public_bytes(
    serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo))

servpubkeybytes = sock.recv(120)

servpubkey = serialization.load_der_public_key(servpubkeybytes,
                                               default_backend())

sharedkey = privkey.exchange(ec.ECDH(), servpubkey)

derived = HKDF(algorithm=hashes.SHA256(),
               length=32,
               salt=None,
               info=b'handshake data',
               backend=default_backend()).derive(sharedkey)

IV = Random.new().read(AES.block_size)

aes = AES.new(derived, AES.MODE_CBC, IV)

fmt = "!3s0si"

buf = bytearray(blksz * AES.block_size)
Beispiel #22
0
 def generate_derived_keys(self, source, peer_public_key, salt):
     shared_key = self.key_cache[source]["private_key"].exchange(ec.ECDH(), peer_public_key)
     self.key_cache[source]["shared_encryption_key"] = self.derive_key(b"encryption key", salt, shared_key)
Beispiel #23
0
def test_skip_exchange_algorithm_unsupported(backend):
    with pytest.raises(pytest.skip.Exception):
        _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), DummyCurve())
def main():
    '''
    uses a select loop to process user and server messages. Forwards user input to the server.
    '''

    args = get_args()
    server_addr = args.ip
    port = args.port

    server = socket.socket()
    server.connect((server_addr, port))

    msg_buffer = {}
    recv_len = {}
    msg_len = {}
    msg_ids = {}
    symmetric_keys = {}
    client_private_key = ec.generate_private_key(ec.SECP384R1(),
                                                 backend=default_backend())
    end_to_end_keys = {}
    sender = ""
    receiver = ""
    realMessage = ""
    inputs = [server, sys.stdin]
    outputs = [server]
    message_queue = queue.Queue()

    waiting_accept = True
    username = ''
    username_next = False

    while server in inputs:

        readable, writable, exceptional = select.select(
            inputs, outputs, inputs)

        for s in readable:

            ###
            ### Process server messages
            ###
            if s == server:

                # This point may iterate multiple times until the message is completely
                # read since LNP.recv, receives a few bytes at a time.
                code = LNP.recv(s, msg_buffer, recv_len, msg_len, msg_ids)

                # This will not happen until the message is switched to
                # MSG_COMPLETE when then it is read from the buffer.
                if code != "LOADING_MSG":
                    code_id, msg = LNP.get_msg_from_queue(
                        s, msg_buffer, recv_len, msg_len, msg_ids,
                        symmetric_keys)

                    if code_id is not None:
                        code = code_id
                        # print("Message ID: " + id)

                if code == "MSG_CMPLT":

                    # print("As soon as we get msg complt, message is: ", msg)
                    if username_next:
                        print("complete")
                        username_msg = msg
                        username = username_msg.split(' ')[1]
                        sys.stdout.write(username_msg + '\n')
                        sys.stdout.write("> " + username + ": ")
                        sys.stdout.flush()
                        username_next = False

                    elif msg:
                        # If username exists, add message prompt to end of message
                        if username != '':
                            name = msg.split()[2]
                            if name[0] == "b":
                                name = name[2:(len(name) - 1)]
                            if is_private(name):
                                wasSent = msg.split()[1]
                                algorithm = algorithms.ARC4(
                                    end_to_end_keys[receiver])
                                cipher = Cipher(algorithm,
                                                mode=None,
                                                backend=default_backend())
                                decryptor = cipher.decryptor()
                                part_decrypt = msg.split()[3]

                                if part_decrypt[0] == "b":
                                    part_decrypt = part_decrypt[2:(
                                        len(part_decrypt) - 1)]

                                part_decrypt = part_decrypt.encode()
                                part_decrypt = part_decrypt.decode(
                                    'unicode-escape').encode('ISO-8859-1')

                                decrypted_now = decryptor.update(part_decrypt)
                                decrypted_now = str(decrypted_now)
                                decrypted_now = decrypted_now[2:(
                                    len(decrypted_now) - 1)]

                                msg = "> " + wasSent + " " + decrypted_now

                            sys.stdout.write('\r' + msg + '\n')
                            sys.stdout.write("> " + username + ": ")

                        # If username doesnt exist, just write message
                        else:
                            sys.stdout.write(msg)

                        sys.stdout.flush()

                # This and any other codes can be edited in protocol.py, this way
                # you can add new codes for new states, e.g., is this a public
                # key, CODE is PUBKEY and msg contains the key.
                elif code == "ACCEPT":
                    waiting_accept = False
                    sys.stdout.write(msg)
                    sys.stdout.flush()

                elif code == "DH-HELLO":
                    pub_key = client_private_key.public_key()

                    serial_public = pub_key.public_bytes(
                        encoding=serialization.Encoding.PEM,
                        format=serialization.PublicFormat.SubjectPublicKeyInfo)

                    LNP.send(s, serial_public, "DH-KEY-EXCHANGE")

                elif code == "DH-REPLY":
                    new_pub_key = serialization.load_pem_public_key(
                        msg.encode(), backend=default_backend())

                    shared_key = client_private_key.exchange(
                        ec.ECDH(), new_pub_key)
                    symm_key = HKDF(
                        algorithm=hashes.SHA256(),
                        length=32,
                        salt=None,
                        info=b'handshake data',
                        backend=default_backend()).derive(shared_key)

                    symmetric_keys[s] = symm_key

                elif code == "P2P-KEY-EXCHANGE":
                    if msg[0] == "b":
                        msg = msg[2:(len(msg) - 1)]
                        msg = msg.replace('\\n', '\n')

                    new_pub_key = serialization.load_pem_public_key(
                        msg.encode(), backend=default_backend())
                    shared_key = client_private_key.exchange(
                        ec.ECDH(), new_pub_key)
                    symm_key = HKDF(
                        algorithm=hashes.SHA256(),
                        length=32,
                        salt=None,
                        info=b'handshake data',
                        backend=default_backend()).derive(shared_key)

                    end_to_end_keys[sender] = symm_key

                    algorithm = algorithms.ARC4(end_to_end_keys[sender])
                    cipher = Cipher(algorithm,
                                    mode=None,
                                    backend=default_backend())
                    encryptor = cipher.encryptor()
                    part_encrypt = realMessage.split(" ", 1)[1]
                    part_encrypt = bytes(part_encrypt, encoding='utf8')
                    encrypted_now = encryptor.update(part_encrypt)
                    toSend = recip
                    sendy = bytes(toSend, encoding='utf8')
                    LNP.send(s, f"{sendy} {encrypted_now}", None,
                             symmetric_keys[s])

                elif code == "P2P-HELLO":
                    sender = msg
                    receiver = username

                    pub_key = client_private_key.public_key()

                    serial_public = pub_key.public_bytes(
                        encoding=serialization.Encoding.PEM,
                        format=serialization.PublicFormat.SubjectPublicKeyInfo)
                    toSend = "@" + sender
                    sendy = bytes(toSend, encoding='utf8')

                    LNP.send(s, f"{sendy} {serial_public}", "P2P-KEY-EXCHANGE",
                             symmetric_keys[s])

                elif code == "P2P-REPLY":
                    if msg[0] == "b":
                        msg = msg[2:(len(msg) - 1)]
                        msg = msg.replace('\\n', '\n')

                    new_pub_key = serialization.load_pem_public_key(
                        msg.encode(), backend=default_backend())

                    shared_key = client_private_key.exchange(
                        ec.ECDH(), new_pub_key)
                    symm_key = HKDF(
                        algorithm=hashes.SHA256(),
                        length=32,
                        salt=None,
                        info=b'handshake data',
                        backend=default_backend()).derive(shared_key)

                    end_to_end_keys[receiver] = symm_key

                elif code == "USERNAME-INVALID" or code == "USERNAME-TAKEN":
                    sys.stdout.write(msg)
                    sys.stdout.flush()

                elif code == "USERNAME-ACCEPT":
                    username_next = True

                elif code == "NO_MSG" or code == "EXIT":
                    sys.stdout.write(msg + '\n')
                    sys.stdout.flush()
                    inputs.remove(s)
                    if s in writable:
                        writable.remove(s)

                elif code == "CERTIFICATE-EXCHANGE":
                    try:
                        with open(f"{msg}.cert", "rb") as f:
                            LNP.send(s, f.read(), "CERTIFICATE-EXCHANGE",
                                     symmetric_keys[s])
                    except FileNotFoundError:
                        LNP.send(s, '', "NO-CERTIFICATE", symmetric_keys[s])
                        sys.stdout.write(
                            "No certificate found for that username.\n")
                        sys.stdout.flush()

            ###
            ### Process user input
            ###
            else:

                msg = sys.stdin.readline()

                if not waiting_accept:
                    msg = msg.rstrip()
                    if msg:
                        message_queue.put(msg)
                    if not ((username == '') or (msg == "exit()")):
                        sys.stdout.write("> " + username + ": ")
                        sys.stdout.flush()

        ###
        ### Send messages to server
        ###
        for s in writable:

            try:
                msg = message_queue.get_nowait()
            except queue.Empty:
                msg = None

            # if there is a message to send
            if msg:

                # if exit message, send the exit code
                if msg == "exit()":
                    outputs.remove(s)
                    LNP.send(s, '', "EXIT", symmetric_keys[s])

                # otherwise just send the messsage
                else:
                    if is_private(msg):
                        #check if already have security
                        recip = msg.split()[0]

                        if recip not in end_to_end_keys:
                            #if don't have, create
                            LNP.send(s, f"{recip} {username}", "P2P-HELLO",
                                     symmetric_keys[s])

                            receiver = recip[1:]
                            sender = username

                            pub_key = client_private_key.public_key()

                            serial_public = pub_key.public_bytes(
                                encoding=serialization.Encoding.PEM,
                                format=serialization.PublicFormat.
                                SubjectPublicKeyInfo)

                            recievv = bytes(recip, encoding='utf8')

                            LNP.send(s, f"{recievv} {serial_public}",
                                     "P2P-REPLY", symmetric_keys[s])

                            realMessage = msg
                            continue

                        algorithm = algorithms.ARC4(end_to_end_keys[sender])
                        cipher = Cipher(algorithm,
                                        mode=None,
                                        backend=default_backend())
                        encryptor = cipher.encryptor()
                        part_encrypt = msg.split()[0][1:]
                        encrypted_now = encryptor.update(part_encrypt)
                        message = recip + encrypted_now
                        LNP.send(s, message, None, symmetric_keys[s])

                    else:
                        LNP.send(s, msg, None, symmetric_keys[s])

        for s in exceptional:
            print("Disconnected: Server exception")
            inputs.remove(s)

    server.close()
Beispiel #25
0
 def gen_shared_secret(self, publickey):
     return self.key.exchange(ec.ECDH(), publickey)
Beispiel #26
0
def ECDH(slot, iface='hid', **kwargs):
    ATCA_SUCCESS = 0x00

    # Loading cryptoauthlib(python specific)
    load_cryptoauthlib()

    # Get the target default config
    cfg = eval('cfg_ateccx08a_{}_default()'.format(atca_names_map.get(iface)))

    # Set interface parameters
    if kwargs is not None:
        for k, v in kwargs.items():
            icfg = getattr(cfg.cfg, 'atca{}'.format(iface))
            setattr(icfg, k, int(v, 16))


    # Basic Raspberry Pi I2C check
    if 'i2c' == iface and (check_if_rpi() or check_if_bbb()):
        cfg.cfg.atcai2c.bus = 1

    # Initialize the stack
    assert atcab_init(cfg) == ATCA_SUCCESS

    # Get the device type from the info command
    info = bytearray(4)
    assert atcab_info(info) == ATCA_SUCCESS
    dev_type = get_device_type_id(get_device_name(info))

    # Check device type
    if dev_type in [0, 0x20]:
        raise ValueError('Device does not support ECDH operations')
    elif dev_type != cfg.devtype:
        cfg.dev_type = dev_type
        assert atcab_release() == ATCA_SUCCESS
        time.sleep(1)
        assert atcab_init(cfg) == ATCA_SUCCESS

    # Create a host private key
    host_key = ec.generate_private_key(ec.SECP256R1(), default_backend())

    # Convert host's public key into ATECCx08 format
    host_pub = host_key.public_key().public_numbers().encode_point()[1:]

    # Display the host's public key
    print("\nHost Public Key:")
    print(pretty_print_hex(host_pub, indent='    '))

    # Buffers for device public key and shared secret
    device_pub = bytearray(64)
    device_shared = bytearray(32)

    # Generate a device private key and perform the ECDH operation
    # This step is using the unencrypted form of the ECDH calls due to configuration details that will be specific
    # for the use case. See atcab_ecdh_enc and atcab_ecdh_tempkey_ioenc functions.
    if dev_type == get_device_type_id('ATECC508A'):
        assert atcab_genkey(slot, device_pub) == ATCA_SUCCESS
        assert atcab_ecdh(slot, host_pub, device_shared) == ATCA_SUCCESS
    else:
        assert atcab_genkey(0xFFFF, device_pub) == ATCA_SUCCESS
        assert atcab_ecdh_tempkey(host_pub, device_shared) == ATCA_SUCCESS

    # Display the device's public key
    print("\nDevice public key:")
    print(pretty_print_hex(device_pub, indent='    '))

    # Convert device public key to a cryptography public key object
    device_pub = ec.EllipticCurvePublicNumbers.from_encoded_point(ec.SECP256R1(), b'\04' + device_pub).public_key(default_backend())

    # Perform the host side ECDH computation
    host_shared = host_key.exchange(ec.ECDH(), device_pub)

    # Display the host side computed symmetric key
    print('\nHost Calculated Shared Secret:')
    print(pretty_print_hex(host_shared, indent='    '))

    # Display the device side computed symmetric key
    print('\nDevice Calculated Shared Secret:')
    print(pretty_print_hex(device_shared, indent='    '))

    # Compare both independently calculated
    print('\nComparing host and device generated secrets:')
    if host_shared == device_shared:
        print("    Success - Generated secrets match!")
    else:
        print("    Error in calculation")

    assert atcab_release() == ATCA_SUCCESS
Beispiel #27
0
 def gensharedKey(self, public_key):
     self.shared_key.append(
         self.diffieHellman.exchange(ec.ECDH(), public_key))
        elif isNewData:
            print("Received new data from", dev.addr)


if __name__ == '__main__':
    #    scanner = Scanner().withDelegate(ScanDelegate())
    #    devices = scanner.scan(10.0)
    #
    #    for dev in devices:
    #        print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
    #        for (adtype, desc, value) in dev.getScanData():
    #            print("  %s = %s" % (desc, value))

    private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())
    public_key = private_key.public_key()
    shared_key = private_key.exchange(ec.ECDH(), public_key)
    print(" shared key :", shared_key.hex())
    derived_key = HKDF(algorithm=hashes.SHA256(),
                       length=64,
                       salt=None,
                       info=b'mible-setup-info',
                       backend=default_backend()).derive(shared_key)
    print("derived key :", derived_key.hex())
    token = derived_key[0:12]
    bind_key = derived_key[12:28]
    A = derived_key[28:44]
    print("      token :", token.hex())
    print("   bind_key :", bind_key.hex())
    print("          A :", A.hex())

    aesccm = AESCCM(A)
Beispiel #29
0
    def data_received(self, data):
        logger.debug("CRAP: {} side received a data of size {} from {}".format(self.mode, len(data), self.transport.get_extra_info("peername")))
        self.deserializer.update(data)
        if self.handshakeComplete:
            for packet in self.deserializer.nextPackets():
                if isinstance(packet, DataPacket):
                    logger.debug('CRAP: {} side received data packet. Info:\n'
                                 'data: {}\n'.format(self.mode, packet.data))

                    logger.debug('CRAP: {} side decrypting data.\n'.format(self.mode))
                    aes_gcm = AESGCM(self.higher_transport.dec_key)
                    decrypted_data = aes_gcm.decrypt(self.higher_transport.other_side_IV, packet.data, None)
                    logger.debug('CRAP: {} side decrypted data is: {}\n'.format(self.mode, decrypted_data))

                    logger.debug(
                        'CRAP: {} side incrementing other_side_IV by one from {} to {}'.format(self.mode, self.higher_transport.other_side_IV,
                                                                                         increment_large_binary(
                                                                                             self.higher_transport.other_side_IV)))
                    self.higher_transport.other_side_IV = increment_large_binary(self.higher_transport.other_side_IV)

                    logger.debug('CRAP: {} sending decrypted data to higher protocol, data: {}\n'.format(self.mode, decrypted_data))
                    self.higherProtocol().data_received(decrypted_data)

                elif isinstance(packet, ErrorPacket):
                    logger.debug('CRAP: {} side received error packet. Info:\n'
                                 'data: {}\n'.format(self.mode, packet.message))

                else:
                    logger.debug('CRAP: {} side expected data/error got something else: ignore'.format(self.mode))


        else:
            # handshake
            for packet in self.deserializer.nextPackets():
                if isinstance(packet, HandshakePacket):
                    logger.debug('CRAP: {} side received handshake packet. Info:\n'
                                 'status: {}\n'
                                 'pk: {}\n'
                                 'signature: {}\n'
                                 'cert: {}\n'
                                 'nonce: {}\n'
                                 'nonce_signature: {}\n'
                                 'cert chain: {}\n'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain))
                    if packet.status == HandshakePacket.NOT_STARTED:
                        try:
                            cert = deserialize_cert(packet.cert)
                            logger.debug('CRAP: {} side verifying certificate common_name!\n'.format(self.mode))
                            self.verify_common_name(cert)
                            logger.debug('CRAP: {} side certificate common name verified!\n'.format(self.mode))

                            logger.debug('CRAP: {} side verifying certificate chain of trust!\n'.format(self.mode))
                            self.verify_chain_of_trust(cert, packet.certChain)
                            logger.debug('CRAP: {} side chain of trust verified!\n'.format(self.mode))

                            logger.debug('CRAP: {} side verifying signature received from other side!\n'.format(self.mode))
                            verification_key = cert.public_key()
                            self.verification_key = verification_key
                            verification_key.verify(packet.signature, packet.pk, padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                              salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())
                            logger.debug('CRAP: {} side signature verified!\n'.format(self.mode))

                            logger.debug('CRAP: {} side creating shared key\n'.format(self.mode))
                            self.shared_key = self.private_key.exchange(ec.ECDH(), deserialize_public(packet.pk))

                            logger.debug('CRAP: {} side signing the sent nonce with signature key\n'.format(self.mode))
                            nonce_bytes = str(packet.nonce).encode()
                            nonce_signature = self.signing_key.sign(nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                              salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

                            logger.debug('CRAP: {} side creating signature\n'.format(self.mode))
                            signature = self.signing_key.sign(self.public_key_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                              salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

                            with open('team1csr_signed.cert', 'rb') as f:
                                signer_cert_bytes = f.read()

                            cert_chain = [signer_cert_bytes]

                            packet = HandshakePacket(status=HandshakePacket.SUCCESS, pk=self.public_key_bytes, signature=signature, cert=self.cert_bytes, nonce=self.nonce, nonceSignature=nonce_signature, certChain=cert_chain)
                            packet_bytes = packet.__serialize__()
                            logger.debug('CRAP: {} side sending handshake packet. Info:\n'
                                         'status: {}\n'
                                         'pk: {}\n'
                                         'signature: {}\n'
                                         'cert: {}\n'
                                         'nonce: {}\n'
                                         'nonce_signature: {}\n'
                                         'cert chain: {}'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain))
                            self.transport.write(packet_bytes)
                        except:
                            error = 'Verification failed!'
                            logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error))
                            self.handle_handshake_error()
                            packet = HandshakePacket(status=HandshakePacket.ERROR)
                            packet_bytes = packet.__serialize__()
                            logger.debug('CRAP: {} side sending handshake packet. Info:\n'
                                         'status: {}\n'
                                         'pk: {}\n'
                                         'signature: {}\n'
                                         'cert: {}\n'
                                         'nonce: {}\n'
                                         'nonce_signature: {}\n'
                                         'cert chain: {}\n'.format(self.mode, packet.status, packet.pk, packet.signature,
                                                             packet.cert, packet.nonce, packet.nonceSignature, packet.certChain))
                            self.transport.write(packet_bytes)

                            self.connection_lost()

                    elif packet.status == HandshakePacket.SUCCESS:
                        if not_set(packet.pk, packet.nonce, packet.signature) and is_set(packet.nonceSignature):
                            try:

                                if is_set(packet.cert):
                                    cert = deserialize_cert(packet.cert)
                                    verification_key = cert.public_key()
                                else:
                                    verification_key = self.verification_key
                                logger.debug('CRAP: {} side verifying nonce signature received from other side!\n'.format(self.mode))
                                verification_key.verify(packet.nonceSignature, self.nonce_bytes,
                                                        padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                                    salt_length=padding.PSS.MAX_LENGTH),
                                                        hashes.SHA256())
                                logger.debug('CRAP: {} side nonce signature verified!\n'.format(self.mode))
                                self.handshakeComplete = True
                                logger.debug(
                                    'CRAP: {} set handshakeComplete to True'.format(self.mode))
                                higher_transport = CrapTransport(self.transport, mode=self.mode, protocol=self)
                                higher_transport.assign_gcm_values()
                                self.higher_transport = higher_transport
                                logger.debug('Crap: {} side calling self.higherProtocol().connection_made()'.format(self.mode))
                                self.higherProtocol().connection_made(higher_transport)
                            except:
                                logger.debug(
                                    'CRAP: {} verifying nonce failed'.format(self.mode))
                                self.connection_lost()
                        elif is_set(packet.pk, packet.cert, packet.signature, packet.nonce, packet.nonceSignature):
                            try:
                                cert = deserialize_cert(packet.cert)
                                logger.debug('CRAP: {} side verifying certificate common_name!\n'.format(self.mode))
                                self.verify_common_name(cert)
                                logger.debug('CRAP: {} side certificate common name verified!\n'.format(self.mode))

                                logger.debug('CRAP: {} side verifying certificate chain of trust!\n'.format(self.mode))
                                self.verify_chain_of_trust(cert, packet.certChain)
                                logger.debug('CRAP: {} side chain of trust verified!\n'.format(self.mode))

                                logger.debug('CRAP: {} side verifying signature received from other side!\n'.format(self.mode))
                                verification_key = cert.public_key()
                                verification_key.verify(packet.signature, packet.pk,
                                                        padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                                    salt_length=padding.PSS.MAX_LENGTH),
                                                        hashes.SHA256())
                                logger.debug('CRAP: {} side signature verified!\n'.format(self.mode))

                                logger.debug('CRAP: {} side verifying nonce signature received from other side!\n'.format(self.mode))
                                verification_key.verify(packet.nonceSignature, self.nonce_bytes,
                                                        padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                                    salt_length=padding.PSS.MAX_LENGTH),
                                                        hashes.SHA256())
                                logger.debug('CRAP: {} side nonce signature verified!\n'.format(self.mode))

                                logger.debug('CRAP: {} side creating shared key\n'.format(self.mode))
                                self.shared_key = self.private_key.exchange(ec.ECDH(), deserialize_public(packet.pk))

                                logger.debug(
                                    'CRAP: {} side signing the sent nonce with signature key\n'.format(self.mode))
                                nonce_bytes = str(packet.nonce).encode()
                                nonce_signature = self.signing_key.sign(nonce_bytes, padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                                              salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())

                                self.handshakeComplete = True
                                logger.debug(
                                    'CRAP: {} set handshakeComplete to True'.format(self.mode))

                                packet = HandshakePacket(status=HandshakePacket.SUCCESS, nonceSignature=nonce_signature,
                                                         cert=self.cert_bytes)
                                packet_bytes = packet.__serialize__()
                                logger.debug('CRAP: {} side sending handshake packet. Info:\n'
                                             'status: {}\n'
                                             'pk: {}\n'
                                             'signature: {}\n'
                                             'cert: {}\n'
                                             'nonce: {}\n'
                                             'nonce_signature: {}\n'
                                             'cert chain: {}'.format(self.mode, packet.status, packet.pk,
                                                                     packet.signature, packet.cert, packet.nonce,
                                                                     packet.nonceSignature, packet.certChain))

                                self.transport.write(packet_bytes)

                                higher_transport = CrapTransport(self.transport, mode=self.mode, protocol=self)
                                higher_transport.assign_gcm_values()
                                self.higher_transport = higher_transport
                                logger.debug(
                                    'Crap: {} side calling self.higherProtocol().connection_made()'.format(self.mode))
                                self.higherProtocol().connection_made(higher_transport)



                            except:
                                error = 'Verification failed!'
                                logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error))
                                self.handle_handshake_error()
                                packet = HandshakePacket(status=HandshakePacket.ERROR)
                                packet_bytes = packet.__serialize__()
                                logger.debug('CRAP: {} side sending handshake packet. Info:\n'
                                             'status: {}\n'
                                             'pk: {}\n'
                                             'signature: {}\n'
                                             'cert: {}\n'
                                             'nonce: {}\n'
                                             'nonce_signature: {}\n'
                                             'cert chain: {}'.format(self.mode, packet.status, packet.pk, packet.signature, packet.cert, packet.nonce, packet.nonceSignature, packet.certChain))
                                self.transport.write(packet_bytes)

                                self.connection_lost()
                        else:
                            error = 'handshake fields does not match!'
                            logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error))
                            self.handle_handshake_error()

                            self.connection_lost()
                    elif packet.status == HandshakePacket.ERROR:
                        # Error detected on the other side
                        error = 'an error reported from the other side'
                        logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error))
                        self.handle_handshake_error()

                        self.connection_lost()
                    else:
                        self.handle_handshake_error()

                        self.connection_lost()

                elif isinstance(packet, ErrorPacket):
                    logger.debug('CRAP: {} side received error packet. Info:\n'
                                 'data: {}\n'.format(self.mode, packet.message))

                else:
                    error = 'Expected handshake/error packet and got s.th else!'
                    logger.debug('CRAP: {} side encountered error: {}\n'.format(self.mode, error))
                    self.handle_handshake_error()
Beispiel #30
0
 def exchange_shared_key(self, pubkey):
     # # used in ECDHESAlgorithm
     private_key = self.get_private_key()
     if private_key:
         return private_key.exchange(ec.ECDH(), pubkey)
     raise ValueError('Invalid key for exchanging shared key')