Beispiel #1
0
 def _checkInitiate(self, clientID, data, host_port):
     cookieNonce, encryptedCookie, nonce = _initiateStruct.unpack_from(data)
     try:
         decryptedCookie = self._secretBox.decrypt(encryptedCookie, 'c' * 8 + cookieNonce)
     except CryptoError:
         return
     clientShortPubkey = PublicKey(decryptedCookie[:32])
     serverShortKey = PrivateKey(decryptedCookie[32:])
     serverShortClientShort = Box(serverShortKey, clientShortPubkey)
     try:
         decrypted = serverShortClientShort.decrypt(data[176:], 'CurveCP-client-I' + nonce)
     except CryptoError:
         return
     clientPubkeyString, vouchNonce, encryptedVouch, serverDomain = _initiateInnerStruct.unpack_from(decrypted)
     clientPubkey = PublicKey(clientPubkeyString)
     serverLongClientLong = Box(self.serverKey.key, clientPubkey)
     try:
         vouchKey = serverLongClientLong.decrypt(encryptedVouch, 'CurveCPV' + vouchNonce)
     except CryptoError:
         return
     if vouchKey != str(clientShortPubkey):
         return
     transport = CurveCPServerTransport(
         self.reactor, self.serverKey, self.factory, clientID,
         clientPubkey, host_port, serverShortClientShort, dnsToName(serverDomain))
     return transport, decrypted[352:]
Beispiel #2
0
    def decrypt(self, data, public_key, base64=True):
        box = Box(self._private_key, public_key)
        # decrypted = box.decrypt(data)
        if base64:
            decrypted = box.decrypt(data, encoder=nacl.encoding.Base64Encoder)
        else:
            decrypted = box.decrypt(data)

        return decrypted
Beispiel #3
0
def test_box_failed_decryption(skalice, pkalice, skbob, pkbob, nonce, plaintext, ciphertext):
    pkbob = PublicKey(pkbob, encoder=HexEncoder)
    skbob = PrivateKey(skbob, encoder=HexEncoder)

    # this cannot decrypt the ciphertext!
    # the ciphertext must be decrypted by (pkbob, skalice) or (pkalice, skbob)
    box = Box(pkbob, skbob)

    with pytest.raises(CryptoError):
        box.decrypt(ciphertext, binascii.unhexlify(nonce), encoder=HexEncoder)
Beispiel #4
0
class CryptoBox:

	# Init

	def __init__(self, sk=None, pk=None):

		# Set local Variables

		self._box = None

		self.sk = None
		self.pk = None

		# Generate key pair if nessessary

		if not sk or not pk:

			self.sk = PrivateKey.generate()
			self.pk = self.sk.public_key

		else:

			self.sk = sk
			self.pk = pk

		# Generate shared key / box

		self._box = Box(self.sk, self.pk)

	# Encryption

	def encrypt(self, plaintext, nonce=None):

		if not nonce:
			nonce = nacl.utils.random(Box.NONCE_SIZE)

		ciphertext = self._box.encrypt(plaintext, nonce)
		return ciphertext[24:]

	# Decryption

	def decrypt(self, ciphertext, nonce=None):

		if nonce:
			plaintext = self._box.decrypt(ciphertext, nonce)
		else:
			plaintext = self._box.decrypt(ciphertext)

		return plaintext
Beispiel #5
0
    def authenticate(self, permissions=[]): #TODO check is needs to = None
        keys = PrivateKey.generate()
        nonce = nacl.utils.random(Box.NONCE_SIZE)
        payload = {
            'app': {
                'name': self.name,
                'version': self.version,
                'vendor': self.vendor,
                'id': self.id
            },
            'publicKey': base64.b64encode(keys.public_key.__bytes__()),
            'nonce': base64.b64encode(nonce),
            'permissions': permissions
        }
        headers = {
            'Content-Type': 'application/json'
        }
        r = self._post('auth', headers, payload)
        if r.status_code == 200:
            responseJson = r.json()
            cipherText = base64.b64decode(responseJson['encryptedKey'])
            self.token = responseJson['token']
            self.permissions = responseJson['permissions']
            self.publicKey = base64.b64decode(responseJson['publicKey'])

            box = Box(keys, PublicKey(self.publicKey))
            data = box.decrypt(cipherText, nonce=nonce)

            self.symmetricKey = data[0:PrivateKey.SIZE]
            self.symmetricNonce = data[PrivateKey.SIZE:]
            return True
        else:
            return False
Beispiel #6
0
 def unwrap(self):
   # don't process the bundle if it's not meant for us
   # check the key fingerprint against our own
   # if it doesn't match
   # return false
   #TODO: Write this code
   #if self.destination is not config.get('global', 'nodename'):
     #return False;
 #else:
   # grab my private key
   with open( config.get('global', 'keypath') + '/' + self.destination + '.private', 'r' ) as destinationPrivateKey:
     destinationKey = self.deserialize(destinationPrivateKey)
   # grab the origin's public key
   with open( config.get('global', 'keypath') + '/' + self.origin + '.public', 'r' ) as originPublicKey:
     originKey = self.deserialize(originPublicKey)
   # grab the origin's verification keyhg
   with open( config.get('global', 'keypath') + '/' + self.origin + '.sighex', 'r' ) as originSigHex:
     originSigKey = self.deserialize(originSigHex)
     originVerify = nacl.signing.VerifyKey(originSigKey, encoder=nacl.encoding.HexEncoder)
   # create a box to decrypt this sucker
   container = Box(destinationKey, originKey)
   # verify the signature
   rawResult = originVerify.verify(self.payload)
   # decrypt it
   rawResult = container.decrypt(rawResult)
   # verify the signature again
   result = originVerify.verify(rawResult)
   
   return result
Beispiel #7
0
def validate_workload(r):
    if "powq" in r.args and "powa" in r.args:
        q = base64.b64decode(r.args["powq"][0])
        a = r.args["powa"][0]

        box = Box(SERVER_KEY, SERVER_KEY.public_key)
        q = box.decrypt(q).split(",")
        if q[1] != a:
            print 1
            defer.returnValue(False)
            return

        # Work is expired
        if (float(q[0]) - time.time()) > 80:
            print 2
            defer.returnValue(False)
            return

        ex = yield REDIS.get(":workload:%s" % r.getClientIP())
        ex = ex or 1

        # Work load is smaller than what we require
        if int(q[2]) < int(ex):
            defer.returnValue(False)
            return

        defer.returnValue(True)
        return

    defer.returnValue(False)
Beispiel #8
0
def decrypt_room_message_key(message_key_array, captain_transport_pubkey, my_room_privkey):
    """
    Parse the message key array, do the trial decryption, and try to retrieve
    the room message key.  Return it if found, otherwise raise NoKeyFound.
    """
    # The array length needs to be a multiple of 72 bytes.
    if len(message_key_array) % 72 != 0:
        util.debug("Received message key array of length %d" % len(message_key_array))
        raise NoKeyFound

    # Build our decryption box.
    decryption_box = Box(my_room_privkey, captain_transport_pubkey)

    chunks = array_chunk_generator(message_key_array, 72)

    # Start walking over the message key array and trial decrypt every
    # ciphertext till we get our key. If we finish array and still haven't
    # found anything, bail with NoKeyFound exception.
    while True:
        try:
            chunk = chunks.next()
        except StopIteration: # no more chunks
            util.debug("Walked over the whole KEY_TRANSPORT packet!")
            raise NoKeyFound

        try:
            room_message_key = decryption_box.decrypt(chunk)
            break
        except nacl.exceptions.CryptoError:
            util.debug("Walking KEY_TRANSPORT: Not our key!")
            # if we didn't find key in first chunk, move to next one.
            continue

    return room_message_key
Beispiel #9
0
 def parse_messages(messages):
     if messages is not None:
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext)
                     p = objects.Plaintext_Message()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:])
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.signed_pubkey)
                     pow_hash = h[64:128]
                     if int(pow_hash[:6], 16) >= 50 or hexlify(p.sender_guid) != h[:40]:
                         raise Exception('Invalid guid')
                     listener.notify(p.sender_guid, p.encryption_pubkey, p.subject,
                                     objects.Plaintext_Message.Type.Name(p.type), p.message)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
Beispiel #10
0
 def parse_messages(messages):
     if messages is not None:
         self.log.info("retrieved %s message(s) from the dht" % len(messages))
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext)
                     p = objects.Plaintext_Message()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:])
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.signed_pubkey)
                     pow_hash = h[64:128]
                     if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode("hex") != h[:40]:
                         raise Exception('Invalid guid')
                     if p.type == objects.Plaintext_Message.Type.Value("ORDER_CONFIRMATION"):
                         c = Contract(self.db, hash_value=unhexlify(p.subject))
                         c.accept_order_confirmation(self.protocol.multiplexer.ws,
                                                     confirmation_json=p.message)
                     else:
                         listener.notify(p.sender_guid, p.encryption_pubkey, p.subject,
                                         objects.Plaintext_Message.Type.Name(p.type), p.message)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
Beispiel #11
0
def decrypt_message(encrypted_message, keying_material, private_key):
    encrypted_key = keying_material['encrypted_key']
    message_signature = keying_material['message_signature']
    temp_public_key = PublicKey(
        keying_material['temp_public_key'],
        Base64Encoder)

    box = PublicBox(private_key, temp_public_key)

    message_key = box.decrypt(
        encrypted_key,
        encoder=Base64Encoder)

    # We got the key, so let's get the message.
    message_box = nacl.secret.SecretBox(message_key)
    message = message_box.decrypt(
        encrypted_message,
        encoder=Base64Encoder)

    # Check the signature.
    mac_key = sha256(box._shared_key, RawEncoder)
    signing_key = SigningKey(mac_key)
    if signing_key.sign(message, Base64Encoder) != message_signature:
        raise SignatureError("The signature is not valid")

    return message
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         v = c.verify(sender.pubkey)
         if v is True:
             self.router.addContact(sender)
             self.log.info("received an order from %s, waiting for payment..." % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"]["amount"]
             listing_hash = c.contract["vendor_offer"]["listing"]["contract_id"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64]
             c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s reason %s" % (sender, v))
             return ["False"]
     except Exception, e:
         self.log.error("Exception (%s) occurred processing order from %s" % (e.message, sender))
         return ["False"]
 def rpc_message(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         plaintext = box.decrypt(encrypted)
         p = PlaintextMessage()
         p.ParseFromString(plaintext)
         signature = p.signature
         p.ClearField("signature")
         verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:])
         verify_key.verify(p.SerializeToString(), signature)
         h = nacl.hash.sha512(p.signed_pubkey)
         pow_hash = h[64:128]
         if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode("hex") != h[:40] or p.sender_guid != sender.id:
             raise Exception('Invalid guid')
         self.log.info("received a message from %s" % sender)
         self.router.addContact(sender)
         for listener in self.listeners:
             try:
                 verifyObject(MessageListener, listener)
                 listener.notify(p, signature)
             except DoesNotImplement:
                 pass
         return ["True"]
     except Exception:
         self.log.warning("received invalid message from %s" % sender)
         return ["False"]
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         if c.verify(sender.signed_pubkey[64:]):
             self.router.addContact(sender)
             self.log.info("received an order from %s, waiting for payment..." % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"]["amount"]
             listing_hash = c.contract["buyer_order"]["order"]["ref_hash"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64]
             c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("unable to decrypt order from %s" % sender)
         return ["False"]
Beispiel #15
0
 def _sent(res):
     msgA = res[0][1]
     self.failUnless(msgA.startswith("a0:"))
     pubkey1_s, boxed = parseMsgA(msgA)
     tpriv = self.tport2[0]["privkey"]
     b = Box(tpriv, PublicKey(pubkey1_s))
     msgB = b.decrypt(boxed)
     MSTID, msgC = parseMsgB(msgB)
def test():
    pk = decode_reporter_key("4e9921b2ce590bffdbd31627b60e8e1ebd2603222381a99565488833ded2cf3e")
    nonce = from_hex("ede1604557223f4a50bbc667647d6baeaeae4cf6f86e7079")
    ciphertext = from_hex("6a9b95f98cf70c4ae2f50364375d833dd807448b90aa1db80329a3db08564c147e8325029850f2586079eec7640c01ab96bb85305a47d0ea0c3df585")
    sk = decode_server_secret_key(None);
    box = Box(sk, pk)
    plaintext = box.decrypt(ciphertext, nonce)
    print(plaintext)
def decode_report(report, reporterkey, nonce, keyfile):
    pk = decode_reporter_key(reporterkey)
    sk = decode_server_secret_key(keyfile)
    nonce = from_hex(nonce)
    ciphertext = from_hex(report)
    box = Box(sk, pk)
    plaintext = box.decrypt(ciphertext, nonce)
    return plaintext
Beispiel #18
0
    def on_post(self, req, resp):
        configuration = req.context['configuration']

        if req.content_length:
            data = json.load(req.bounded_stream)
        else:
            raise Exception("No data.")

        if 'challenge' not in data:
            raise Exception("No challenge.")

        if 'uuid' not in data['challenge']:
            raise Exception("No UUID.")

        if 'nonce' not in data['challenge']:
            raise Exception("No nonce.")

        if 'response' not in data['challenge']:
            raise Exception("No response")

        db_session = req.context['db_session']
        challenge = db_session.query(db.Challenge).filter(db.Challenge.uuid == data['challenge']['uuid']).first()
        user = challenge.user

        if challenge is None:
            raise Exception("Challenge unknown.")

        db_session.delete(challenge)
        db_session.commit()

        user_public_key = PublicKey(challenge.user.public_key, encoder = nacl.encoding.RawEncoder)

        box = Box(configuration['server_key_pair'], user_public_key)

        response = base64.b64decode(data['challenge']['response'].encode('utf-8'))

        nonce = base64.b64decode(data['challenge']['nonce'].encode('utf-8'))

        answer = box.decrypt(response, nonce, encoder = nacl.encoding.RawEncoder)
        answer_hash = nacl.hash.sha256(answer, encoder = nacl.encoding.RawEncoder)

        if answer_hash != challenge.answer_hash:
            raise Exception("Response incorrect.")

        user_session = db.UserSession(
            uuid = str(uuid.uuid4()),
            user = user,
            ip_address_hash = nacl.hash.sha256(req.remote_addr.encode('utf-8'), encoder = nacl.encoding.RawEncoder),
            user_agent_hash = nacl.hash.sha256(req.user_agent.encode('utf_8'), encoder = nacl.encoding.RawEncoder)
        )

        db_session.add(user_session)
        db_session.commit()

        resp.status = falcon.HTTP_200
        resp.body = json.dumps({
            'uuid': user_session.uuid
        })
Beispiel #19
0
 def _sent(res):
     msgA = res[0][1]
     self.failUnless(msgA.startswith("a0:"))
     pubkey1_s, boxed = parseMsgA(msgA)
     tpriv_hex = self.tports2["local"]["retrieval"]["privkey"]
     tpriv = PrivateKey(tpriv_hex.decode("hex"))
     b = Box(tpriv, PublicKey(pubkey1_s))
     msgB = b.decrypt(boxed)
     MSTT, msgC = parseMsgB(msgB)
Beispiel #20
0
    def decrypt(self, encrypted, sender_pub, recipient):
        box = Box(secret_key(recipient), public_key(sender_pub))
        if encrypted[:4] != 'msg:':
            raise DecryptionError

        try:
            return box.decrypt(Base64Encoder.decode(encrypted[4:]))
        except CryptoError:
            raise DecryptionError
Beispiel #21
0
def test_box_wrong_length():
    with pytest.raises(ValueError):
        PublicKey(b"")
    with pytest.raises(TypeError):
        PrivateKey(b"")

    pub = PublicKey(
        b"ec2bee2d5be613ca82e377c96a0bf2220d823ce980cdff6279473edc52862798",
        encoder=HexEncoder,
    )
    priv = PrivateKey(
        b"5c2bee2d5be613ca82e377c96a0bf2220d823ce980cdff6279473edc52862798",
        encoder=HexEncoder,
    )
    b = Box(priv, pub)
    with pytest.raises(ValueError):
        b.encrypt(b"", b"")
    with pytest.raises(ValueError):
        b.decrypt(b"", b"")
Beispiel #22
0
def test_box_decryption_combined(skalice, pkalice, skbob, pkbob, nonce, plaintext, ciphertext):
    pkbob = PublicKey(pkbob, encoder=HexEncoder)
    skalice = PrivateKey(skalice, encoder=HexEncoder)

    box = Box(skalice, pkbob)

    combined = binascii.hexlify(
                    binascii.unhexlify(nonce) + binascii.unhexlify(ciphertext))
    decrypted = binascii.hexlify(box.decrypt(combined, encoder=HexEncoder))

    assert decrypted == plaintext
Beispiel #23
0
 def _replyWithCookie(self, data, host_port):
     if len(data) != _helloStruct.size:
         return
     serverExtension, clientExtension, clientShortPubkey, nonce, encrypted = _helloStruct.unpack(data)
     serverLongClientShort = Box(self.serverKey.key, PublicKey(clientShortPubkey))
     try:
         serverLongClientShort.decrypt(encrypted, 'CurveCP-client-H' + nonce)
     except CryptoError:
         return
     serverShortKey = PrivateKey.generate()
     unencryptedCookie = clientShortPubkey + str(serverShortKey)
     cookieNonce = self.serverKey.nonce(longterm=True)
     cookie = cookieNonce + self._secretBox.encrypt(unencryptedCookie, 'c' * 8 + cookieNonce).ciphertext
     boxData = str(serverShortKey.public_key) + cookie
     cookiePacket = (
         'RL3aNMXK'
         + clientExtension
         + serverExtension
         + cookieNonce
         + serverLongClientShort.encrypt(boxData, 'CurveCPK' + cookieNonce).ciphertext)
     self.transport.write(cookiePacket, host_port)
Beispiel #24
0
 def parse_messages(messages):
     if messages is not None:
         self.log.info("retrieved %s message(s) from the dht" % len(messages))
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext).decode("zlib")
                     p = objects.PlaintextMessage()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.pubkey)
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.pubkey)
                     pow_hash = h[40:]
                     if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode("hex") != h[:40]:
                         raise Exception("Invalid guid")
                     if p.type == objects.PlaintextMessage.Type.Value("ORDER_CONFIRMATION"):
                         c = Contract(
                             self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet
                         )
                         c.accept_order_confirmation(
                             self.protocol.get_notification_listener(), confirmation_json=p.message
                         )
                     elif p.type == objects.PlaintextMessage.Type.Value("RECEIPT"):
                         c = Contract(
                             self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet
                         )
                         c.accept_receipt(
                             self.protocol.get_notification_listener(),
                             self.protocol.multiplexer.blockchain,
                             receipt_json=p.message,
                         )
                     elif p.type == objects.PlaintextMessage.Type.Value("DISPUTE_OPEN"):
                         process_dispute(
                             json.loads(p.message, object_pairs_hook=OrderedDict),
                             self.db,
                             self.protocol.get_message_listener(),
                             self.protocol.get_notification_listener(),
                             self.protocol.multiplexer.testnet,
                         )
                     else:
                         listener.notify(p, signature)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
Beispiel #25
0
def test_box_optional_nonce(
        privalice, pubalice, privbob, pubbob, nonce, plaintext, ciphertext):
    pubbob = PublicKey(pubbob, encoder=HexEncoder)
    privalice = PrivateKey(privalice, encoder=HexEncoder)

    box = Box(privalice, pubbob)

    encrypted = box.encrypt(binascii.unhexlify(plaintext), encoder=HexEncoder)

    decrypted = binascii.hexlify(box.decrypt(encrypted, encoder=HexEncoder))

    assert decrypted == plaintext
Beispiel #26
0
    def decrypt(self, mqttpayload):

        image_types = {
            'image/png'         : 'png',
            'image/jpeg'        : 'jpg',
            'image/jpg'         : 'jpg',
            'image/gif'         : 'gif',
        }

	messagehex = b64decode(mqttpayload)
	message = nacl.signing.SignedMessage(messagehex)
	self.verkey.verify(message)
	#print "verified"

        box = Box(me.seckey, self.pubkey)
	
        #
        #CK don't like the literal 64, but I don't know where to get the symbol
        #
        plaintext = box.decrypt(message[64:])
	#print "decrypted"
        message_data = json.loads(plaintext)
	#print "json out"

        if '_type' in message_data:
            tst = message_data['timestamp']
            time_str = time.strftime('%H:%M', time.localtime(float(tst)))
            if message_data.get('_type') == 'ack':
                return time_str, "ACK"
            if message_data.get('_type') == 'see':
                return time_str, "SEE"
            if message_data.get('_type') == 'msg':
                message = b64decode(message_data['content'])

                content_type = message_data.get('content-type', 'unknown')
                if content_type in image_types:
                    extension = image_types[content_type]
                    filename = '%s-%s.%s' % (self.identifier, time.time(), extension)
                    try:
                        fd = open(filename, "wb")
                        fd.write(message)
                        fd.close()
                    except Exception, e:
                        return time_str, "Cannot create file %s: %s" % (filename, str(e))


                    return time_str, "<Incoming file stored as %s>" % filename


                if message_data.get('content-type') != u'text/plain; charset:"utf-8"':
                    message = 'Unsupported content-type: %s' % message_data.get('content-type')
                return time_str, message
 def rpc_dispute_close(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         contract = json.loads(order, object_pairs_hook=OrderedDict)
         close_dispute(contract, self.db, self.get_message_listener(),
                       self.get_notification_listener(), self.multiplexer.testnet)
         self.router.addContact(sender)
         self.log.info("Contract dispute closed by %s" % sender)
         return ["True"]
     except Exception:
         self.log.error("unable to parse disputed close message from %s" % sender)
         return ["False"]
 def rpc_dispute_close(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         res = box.decrypt(encrypted)
         resolution_json = json.loads(res, object_pairs_hook=OrderedDict)
         close_dispute(resolution_json, self.db, self.get_message_listener(),
                       self.get_notification_listener(), self.multiplexer.testnet)
         self.router.addContact(sender)
         self.log.info("Contract dispute closed by %s" % sender)
         return ["True"]
     except Exception:
         self.log.error("unable to parse disputed close message from %s" % sender)
         return ["False"]
Beispiel #29
0
def test_box_decryption(
        privalice, pubalice, privbob, pubbob, nonce, plaintext, ciphertext):
    pubbob = PublicKey(pubbob, encoder=HexEncoder)
    privalice = PrivateKey(privalice, encoder=HexEncoder)

    box = Box(privalice, pubbob)

    nonce = binascii.unhexlify(nonce)
    decrypted = binascii.hexlify(
        box.decrypt(ciphertext, nonce, encoder=HexEncoder),
    )

    assert decrypted == plaintext
Beispiel #30
0
def decrypt_from_perma_payments(ciphertext, encoder=encoding.Base64Encoder):
    """
    Decrypt bytes encrypted by perma-payments.
    """
    box = Box(
        PrivateKey(
            settings.PERMA_PAYMENTS_ENCRYPTION_KEYS['perma_secret_key'], encoder=encoder
        ),
        PublicKey(
            settings.PERMA_PAYMENTS_ENCRYPTION_KEYS['perma_payments_public_key'], encoder=encoder
        )
    )
    return box.decrypt(ciphertext, encoder=encoder)
Beispiel #31
0
    def setUp(self):

        self.session_secret_key = "a7d028388e9d80f2679c236ebb2d0fedc5b7b0a28b393f6a20cc8f6be636aa71"

        # our public / private key box
        box = PrivateKey.generate()

        self.test_email = "*****@*****.**"
        self.test_username = "******" + settings.ALLOWED_DOMAINS[0]
        self.test_authkey = binascii.hexlify(
            os.urandom(settings.AUTH_KEY_LENGTH_BYTES)).decode()
        self.test_public_key = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        self.test_real_private_key = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        self.test_private_key = binascii.hexlify(
            os.urandom(settings.USER_PRIVATE_KEY_LENGTH_BYTES)).decode()
        self.test_private_key_nonce = binascii.hexlify(
            os.urandom(settings.NONCE_LENGTH_BYTES)).decode()
        self.test_secret_key = binascii.hexlify(
            os.urandom(settings.USER_SECRET_KEY_LENGTH_BYTES)).decode()
        self.test_secret_key_nonce = binascii.hexlify(
            os.urandom(settings.NONCE_LENGTH_BYTES)).decode()
        self.test_user_sauce = '0865977160de11fe18806e6843bc14663433982fdeadc45c217d6127f260ff33'
        self.device_fingerprint = '123456'
        self.device_time = timezone.now()

        data = {
            'username': self.test_username,
            'email': self.test_email,
            'authkey': self.test_authkey,
            'public_key': self.test_public_key,
            'private_key': self.test_private_key,
            'private_key_nonce': self.test_private_key_nonce,
            'secret_key': self.test_secret_key,
            'secret_key_nonce': self.test_secret_key_nonce,
            'user_sauce': self.test_user_sauce,
        }

        url = reverse('authentication_register')
        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        self.user_obj = models.User.objects.get(username=self.test_username)
        self.user_obj.is_email_active = True
        self.user_obj.save()

        # encrypt authorization validator with session key
        secret_box = nacl.secret.SecretBox(self.session_secret_key,
                                           encoder=nacl.encoding.HexEncoder)
        authorization_validator_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        authorization_validator_nonce_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator_nonce)
        encrypted = secret_box.encrypt(
            json.dumps({}).encode("utf-8"), authorization_validator_nonce)
        authorization_validator = encrypted[len(authorization_validator_nonce
                                                ):]
        authorization_validator_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator)

        self.authorization_validator = json.dumps({
            'text':
            authorization_validator_hex.decode(),
            'nonce':
            authorization_validator_nonce_hex.decode(),
        })

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
                'device_fingerprint': self.device_fingerprint,
                'device_time': str(self.device_time),
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        url = reverse('authentication_login')
        response = self.client.post(url, data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info').decode()),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce').decode())).decode())

        self.token_key = request_data.get('token', False)

        server_public_key_hex = request_data.get('session_public_key', False)

        # lets encrypt our token
        user_private_key = PrivateKey(self.test_real_private_key,
                                      encoder=nacl.encoding.HexEncoder)
        user_session_private_key = PrivateKey(user_session_private_key_hex,
                                              encoder=nacl.encoding.HexEncoder)
        server_public_key = PublicKey(server_public_key_hex,
                                      encoder=nacl.encoding.HexEncoder)

        # create both our crypto boxes
        user_crypto_box = Box(user_private_key, server_public_key)
        session_crypto_box = Box(user_session_private_key, server_public_key)

        # decrypt session secret
        session_secret_key_nonce_hex = request_data.get(
            'session_secret_key_nonce', False)
        session_secret_key_nonce = nacl.encoding.HexEncoder.decode(
            session_secret_key_nonce_hex)
        session_secret_key_hex = request_data.get('session_secret_key', False)
        session_secret_key = nacl.encoding.HexEncoder.decode(
            session_secret_key_hex)
        decrypted_session_key_hex = session_crypto_box.decrypt(
            session_secret_key, session_secret_key_nonce)

        # decrypt user validator
        user_validator_nonce_hex = request_data.get('user_validator_nonce',
                                                    False)
        user_validator_nonce = nacl.encoding.HexEncoder.decode(
            user_validator_nonce_hex)
        user_validator_hex = request_data.get('user_validator', False)
        user_validator = nacl.encoding.HexEncoder.decode(user_validator_hex)

        decrypted_user_validator = user_crypto_box.decrypt(
            user_validator, user_validator_nonce)

        # encrypt user validator with session key
        verification_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        self.verification_nonce_hex = nacl.encoding.HexEncoder.encode(
            verification_nonce)
        self.decrypted_session_key = nacl.encoding.HexEncoder.decode(
            decrypted_session_key_hex)
        self.secret_box = nacl.secret.SecretBox(self.decrypted_session_key)
        encrypted = self.secret_box.encrypt(decrypted_user_validator,
                                            verification_nonce)
        verification = encrypted[len(verification_nonce):]
        self.verification_hex = nacl.encoding.HexEncoder.encode(verification)
Beispiel #32
0
    def handle(self, *args, **options):  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
        source = options['source']

        supports_json = install_supports_jsonfield()

        # Remove bundles

        if options['skip_bundle']:
            print 'Skipped inspecting and removing DataBundle objects.'
        else:
            deleted = 0
            partial_bundles = 0

            to_delete = []

            index = 0
            total = DataBundle.objects.all().count()

            while index < total:
                print 'Inspecting DataBundle ' + str(index) + ' of ' + str(
                    total)

                for bundle in DataBundle.objects.all().order_by(
                        'recorded')[index:(index + PAGE_SIZE)]:
                    if supports_json is False:
                        bundle.properties = json.loads(bundle.properties)

                    if bundle.encrypted:
                        if 'nonce' in bundle.properties and 'encrypted' in bundle.properties:
                            payload = base64.b64decode(
                                bundle.properties['encrypted'])
                            nonce = base64.b64decode(
                                bundle.properties['nonce'])

                            private_key = PrivateKey(base64.b64decode(settings.PDK_SERVER_KEY).strip())  # pylint: disable=line-too-long
                            public_key = PublicKey(base64.b64decode(settings.PDK_CLIENT_KEY).strip())  # pylint: disable=line-too-long

                            box = Box(private_key, public_key)

                            decrypted_message = box.decrypt(payload, nonce)

                            decrypted = six.text_type(decrypted_message,
                                                      encoding='utf8')

                            bundle.properties = json.loads(decrypted)
                        elif 'encrypted' in bundle.properties:
                            print 'Missing "nonce" in encrypted bundle. Cannot decrypt bundle ' + str(
                                bundle.pk) + '. Skipping...'
                            break
                        elif 'nonce' in bundle.properties:
                            print 'Missing "encrypted" in encrypted bundle. Cannot decrypt bundle ' + str(
                                bundle.pk) + '. Skipping...'
                            break

                    total_points = len(bundle.properties)

                    for data_point in bundle.properties:
                        if source == data_point['passive-data-metadata'][
                                'source']:
                            total_points -= 1

                    if total_points == 0:
                        to_delete.append(bundle.pk)
                    elif total_points != len(bundle.properties):
                        partial_bundles += 1

                index += PAGE_SIZE

            for bundle_pk in to_delete:
                DataBundle.objects.get(pk=bundle_pk).delete()

            print 'Removed ' + str(len(to_delete)) + ' DataBundle objects.'
            print 'Found ' + str(
                partial_bundles) + ' partial DataBundle objects (not removed).'

        source_reference = DataSourceReference.reference_for_source(source)

        if source_reference is not None:
            deleted = DataPoint.objects.filter(
                source_reference=source_reference).delete()

            print 'Removed ' + str(
                deleted[0]) + ' DataPoint objects by source reference.'

        source_reference.delete()

        print 'Removed DataSourceReference object.'

        points_query = DataPoint.objects.filter(source=source)

        index = 0
        total = points_query.count()

        print 'Matching DataPoint objects by source identifier: ' + str(total)

        to_delete = []

        while index < total:
            print 'Queuing DataPoint objects for deletion: ' + str(
                index) + ' of ' + str(total)

            for point in points_query.order_by('pk')[index:(index +
                                                            PAGE_SIZE)]:
                to_delete.append(point.pk)

            index += PAGE_SIZE

        index = 0
        total = len(to_delete)

        while index < total:
            print 'Removing DataPoint objects: ' + str(index) + ' of ' + str(
                total)

            for point_pk in to_delete[index:(index + PAGE_SIZE)]:
                DataPoint.objects.get(pk=point_pk).delete()

            index += PAGE_SIZE

        print 'Removed ' + str(
            len(to_delete)) + ' DataPoint objects by source match.'

        source_obj = DataSource.objects.filter(identifier=source).first()

        if source_obj is not None:
            deleted = DataSourceAlert.objects.filter(
                data_source=source_obj).delete()

            print 'Removed ' + str(
                deleted[0]) + ' DataSourceAlert objects by source match.'

            source_obj.delete()

            print 'Removed DataSource object.'
Beispiel #33
0
class SyncRemoteManager(BaseCASManager):
    def __init__(self, addr=('127.0.0.1', 10811), save_file=None):
        BaseCASManager.__init__(self)
        self.addr = addr
        if not save_file:
            if isinstance(addr, str):
                save_file = addr.replace('/', '_') + '.vac'
            else:
                save_file = '%s_%s.vac' % self.addr
        self.save_file = save_file
        self.sock = None
        self.rfile = self.wfile = None
        self._record = None
        self._changed = False
        self.server_box = None
        self.use_encryption = ENCRYPTION
        self.cache = Cache(maxsize=256)

    def load(self, return_file=False):
        try:
            fp = open(self.save_file, 'rb')
            if return_file:
                return fp
            with fp:
                return CasDir.from_bytes(fp.read())
        except FileNotFoundError:
            if return_file:
                return None
            return CasDir.from_dict({})

    def save(self):
        if self._changed:
            rec = self.record
            parent = self.load(return_file=True)
            if parent:
                rec.parent, level = self.writefile(parent, blocksize=4096)
                parent.close()
            val = rec.to_bytes()
            with open(self.save_file, 'wb') as fp:
                fp.write(rec.to_bytes())
            self._changed = False

    @property
    def record(self):
        if self._record is None:
            self._record = self.load()
        return self._record

    @record.setter
    def record(self, rec):
        self._record = rec

    def save_file_data(self, path, meta, buf, cipher=None, subdir=False):
        hist = BaseCASManager.save_file_data(self, path, meta, buf, cipher=cipher)
        if not subdir:
            self.record.files[hist.path] = hist.to_bytes()
            self._changed = True
        return hist

    def open(self, filename, mode=Perm.read, owner=Owner.ALL, rev=None):
        try:
            hist = self.record.get_file(filename)
        except KeyError:
            if mode == Perm.read:
                raise FileNotFoundError(filename)
            else:
                hist = CasHistoryInfo.from_dict({'path': filename})
        hist.history_key = self.record.parent
        return VersionedFile(self, filename, mode=mode, rev=rev, file_info=hist)

    def _negotiate_encryption(self, server_pub_key, server_auth=None):
        six.print_('server public_key: %s' % server_pub_key.hex())
        self.server_box = None
        if blake2b(server_pub_key + get_cas_secret(), encoder=RawEncoder) != server_auth:
            raise RuntimeError('Bad Server Auth! %s' % server_auth)
        self.private_key = PrivateKey.generate()
        my_pub_key = bytes(self.private_key.public_key)
        six.print_('client public_key: %s' % my_pub_key.hex())
        auth = blake2b(my_pub_key + get_cas_secret(), encoder=RawEncoder)
        self._send(b'N' + my_pub_key + auth)
        resp  = self.rfile.read(2)
        if resp == b'OK':
            self.server_box = Box(self.private_key, PublicKey(server_pub_key))
        else:
            six.print_(resp)
        
    def connect(self):
        if isinstance(self.addr, str) and self.addr.startswith('/'):
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(self.addr)
        else:
            self.sock = socket.create_connection(self.addr)
        self.rfile = self.sock.makefile('rb')
        self.wfile = self.sock.makefile('wb')
        line = self.rfile.read(64)
        six.print_('connected to %s:%s' % (self.addr, line.hex()))
        if self.use_encryption:
            public_key, auth = line[:32], line[32:]
            self._negotiate_encryption(public_key, auth)

    def _decrypt(self, message):
        if self.server_box:
            return self.server_box.decrypt(message)
        else:
            return message

    def readblock(self, key, verify=False):
        # block = self.cache.get(key)
        block = None
        if block is None:
            message = b'R %s\n' % key
            self._send(message)
            resp =  self.rfile.read(4)
            if resp != b'ERRR':
                length = struct.unpack('>I', resp)[0]
                block = self._decrypt(self.rfile.read(length))
                if verify:
                    if self._hash_block(block) != key[1:]:
                        raise Exception('Bad block!')
                self.cache.set(key, block)
            else:
                block = None
        return block

    def writeblock(self, level, block):
        key = struct.pack('>B20s', level, self._hash_block(block))
        if not self.cache.get(key):
            message = b'W %s\n' % struct.pack('>BI', level, len(block))
            message += block
            self._send(message)
            length = struct.unpack('>I', self.rfile.read(4))[0]
            key = self._decrypt(self.rfile.read(length))
            assert len(key) == 21, key
            self.cache.set(key, block)
        return key

    def walkblocks(self, key):
        message = b'T %s\n' % key
        self._send(message)
        while 1:
            resp = self.rfile.read(4)
            if resp == b'\x00\x00\x00\x00':
                break
            if resp != b'ERRR':
                length = struct.unpack('>I', resp)[0]
                block = self._decrypt(self.rfile.read(length))
                yield block
            else:
                yield None
                break

    def missing(self, keys):
        missing = []
        while keys:
            to_check, keys = keys[:10000], keys[10000:]
            message = b'H ' + b''.join(to_check)
            self._send(message)
            while 1:
                resp = self.rfile.read(21)
                if resp != b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00':
                    missing.append(resp)
                else:
                    break
        return missing

    def get_stats(self):
        import json
        message = b'S\n'
        self._send(message)
        return json.loads(self.rfile.readline().decode('utf8'))

    def _send(self, message):
        if not self.sock:
            self.connect()
        if self.server_box:
            message = self.server_box.encrypt(message)
        lm = len(message)
        mess = struct.pack('>I', lm) + message
        self.wfile.write(mess)
        self.wfile.flush()
        
    def close(self):
        if self._record:
            self.save()
        self._send(b'Q\n')
        self.wfile.close()
        self.rfile.close()
        self.sock.close()
        self.sock = None

    def __enter__(self):
        if not self.sock:
            self.connect()
        return self

    def __exit__(self, exc_type, exc, tb):
        self.close()
        if exc:
            six.reraise(exc_type, exc, tb)
Beispiel #34
0
    def handle(self):
        (packet_id, data) = receive_packet(self.request)

        if packet_id == PACKET_ID_REGISTRATION_REQUEST:
            client_pk = data[0:PUBLICKEY_BYTES]
            client_nonce = data[PUBLICKEY_BYTES:PUBLICKEY_BYTES + NONCE_BYTES]
            client_mail_crypt = data[PUBLICKEY_BYTES + NONCE_BYTES:]

            box = Box(server_sk, PublicKey(client_pk))
            client_mail = box.decrypt(client_mail_crypt, client_nonce)

            client_mail = parseaddr(client_mail)[1]

            if '@' not in client_mail:
                raise UserWarning("Invalid mail address")

            client_mail_hash = hashlib.sha512(client_mail).hexdigest()

            return_code = 0

            _global_db_write_lock.acquire(True)
            try:  # make sure the lock will be released again
                if os.path.isfile(STORAGE_PIR_DIR + client_mail_hash):
                    # do not allow reregistrations when the registration
                    # is already done
                    return_code = 1
                elif os.path.isfile(STORAGE_REGISTRATION_DIR +
                                    client_mail_hash):
                    # get the stored token
                    with open(STORAGE_REGISTRATION_DIR + client_mail_hash,
                              'rb') as f:
                        storage_data = f.read()

                    storage_pk = storage_data[0:PUBLICKEY_BYTES]
                    storage_token = storage_data[PUBLICKEY_BYTES:\
                                                 PUBLICKEY_BYTES+TOKEN_BYTES]

                    if not compare_bytes(storage_pk, client_pk):
                        return_code = 2
                    else:
                        client_token = storage_token
                else:
                    # only generate a token if none has been created yet
                    client_token = nacl.utils.random(TOKEN_BYTES)
                    with open(STORAGE_REGISTRATION_DIR + client_mail_hash,
                              'wb') as f:
                        f.write(client_pk + client_token)
            finally:
                _global_db_write_lock.release()

            # TODO: send token via mail
            if return_code == 0:
                print "[TOKEN] for `" + client_mail + "`: " + client_token.encode(
                    'hex')
            else:
                print "Not printing token because return_code is " +\
                      str(return_code)

            # send back the return code
            return_code_encrypted = box.encrypt(
                to_byte(return_code), increase_nonce(client_nonce)).ciphertext

            # we use 11 as our packed id for the response
            data = to_byte(PACKET_ID_REGISTRATION_REQUEST_ACK) +\
                   return_code_encrypted

            self.request.sendall(itonb(len(data)) + data)

        elif packet_id == PACKET_ID_REGISTRATION_TOKEN:
            client_pk = data[0:PUBLICKEY_BYTES]
            client_nonce = data[PUBLICKEY_BYTES:PUBLICKEY_BYTES + NONCE_BYTES]
            client_data_crypt = data[PUBLICKEY_BYTES + NONCE_BYTES:]

            box = Box(server_sk, PublicKey(client_pk))
            client_data = box.decrypt(client_data_crypt, client_nonce)

            client_token = client_data[0:TOKEN_BYTES]
            client_mail = client_data[TOKEN_BYTES:]
            client_mail = parseaddr(client_mail)[1]

            if '@' not in client_mail:
                raise UserWarning("Invalid mail address")

            client_mail_hash = hashlib.sha512(client_mail).hexdigest()

            return_code = 0
            return_msg = ""

            if os.path.isfile(STORAGE_PIR_DIR + client_mail_hash):
                return_code = 1
                return_msg = 'the registration was already completed successfully'

            if return_code == 0:
                _global_db_write_lock.acquire(True)
                try:  # make sure the lock will be released again
                    with open(STORAGE_REGISTRATION_DIR + client_mail_hash,
                              'rb') as f:
                        storage_data = f.read()
                finally:
                    _global_db_write_lock.release()

                storage_pk = storage_data[0:PUBLICKEY_BYTES]
                storage_token = storage_data[PUBLICKEY_BYTES:PUBLICKEY_BYTES+\
                                             TOKEN_BYTES]

                if not compare_bytes(storage_token, client_token):
                    return_code = 2
                    return_msg = 'invalid token'

                if not compare_bytes(storage_pk, client_pk):
                    return_code = 3
                    return_msg = 'wrong public key'

            if return_code == 0:
                # create the file that will be send when contacts query for an
                # email address
                _global_db_write_lock.acquire(True)
                try:  # make sure the lock will be released again
                    with open(STORAGE_PIR_DIR + client_mail_hash, 'wb') as f:
                        f.write(client_pk)
                finally:
                    _global_db_write_lock.release()

                # update PIR manifest
                update_pir_manifest()

                # delete the file from the registration process which is not
                # needed any more
                _global_db_write_lock.acquire(True)
                try:  # make sure the lock will be released again
                    os.remove(STORAGE_REGISTRATION_DIR + client_mail_hash)
                finally:
                    _global_db_write_lock.release()

            print "Return code", return_code, return_msg

            # send back the return code
            return_code_encrypted = box.encrypt(
                to_byte(return_code), increase_nonce(client_nonce)).ciphertext

            # add the packet id
            data = to_byte(PACKET_ID_REGISTRATION_TOKEN_ACK) +\
                   return_code_encrypted

            self.request.sendall(itonb(len(data)) + data)

        elif packet_id == PACKET_ID_UPDATE_PK_REQUEST:
            offset = 0
            client_pk = data[offset:offset + PUBLICKEY_BYTES]
            offset += PUBLICKEY_BYTES
            client_nonce = data[offset:offset + NONCE_BYTES]
            offset += NONCE_BYTES
            client_mail_raw = data[offset:offset + SHA512HASH_BYTES]
            client_mail_hash = binascii.hexlify(client_mail_raw).decode(
                'ascii')
            offset += SHA512HASH_BYTES
            client_data_crypt = data[offset:]

            box = Box(server_sk, PublicKey(client_pk))
            client_tmp_pk_raw = box.decrypt(client_data_crypt, client_nonce)
            box = None
            assert len(client_tmp_pk_raw) == PUBLICKEY_BYTES

            tmp_sk = PrivateKey.generate()
            tmp_pk_raw =\
                tmp_sk.public_key.encode(encoder=nacl.encoding.RawEncoder)

            client_nonce = increase_nonce(client_nonce)
            tmp_box1 = Box(server_sk, PublicKey(client_tmp_pk_raw))
            ciphertext = tmp_box1.encrypt(tmp_pk_raw, client_nonce).ciphertext
            tmp_box1 = None

            data = to_byte(PACKET_ID_UPDATE_PK_RESPONSE) + ciphertext

            self.request.sendall(itonb(len(data)) + data)
            (packet_id, data) = receive_packet(self.request)

            if packet_id != PACKET_ID_UPDATE_PK_SEND_DATA:
                raise UserWarning("Unexpected packet id.")

            client_nonce = increase_nonce(client_nonce)
            tmp_box2 = Box(tmp_sk, PublicKey(client_tmp_pk_raw))
            profile_data = tmp_box2.decrypt(data, client_nonce)

            return_code = 0

            if not os.path.isfile(STORAGE_PIR_DIR + client_mail_hash):
                # the registration is not completed yet
                return_code = 1

            if return_code == 0:
                _global_db_write_lock.acquire(True)
                try:  # make sure the lock will be released again
                    with open(STORAGE_PIR_DIR + client_mail_hash, 'rb') as f:
                        storage_data = f.read()
                finally:
                    _global_db_write_lock.release()

                assert len(storage_data) >= PUBLICKEY_BYTES
                storage_pk = storage_data[0:PUBLICKEY_BYTES]

                # the client needs to verify it's identity against the server
                assert compare_bytes(profile_data[0:PUBLICKEY_BYTES],
                                     storage_pk)

                if len(storage_data) > PUBLICKEY_BYTES and compare_bytes(
                        profile_data[PUBLICKEY_BYTES:PUBLICKEY_BYTES +
                                     NONCE_BYTES],
                        storage_data[PUBLICKEY_BYTES:PUBLICKEY_BYTES +
                                     NONCE_BYTES]):
                    # the nonce has to change to avoid leaking information about
                    # the size of the friend list
                    return_code = 2

                # write the profile data sent by the client
                _global_db_write_lock.acquire(True)
                try:  # make sure the lock will be released again
                    with open(STORAGE_PIR_DIR + client_mail_hash, 'wb') as f:
                        f.write(profile_data)
                except:
                    return_code = 3
                finally:
                    _global_db_write_lock.release()

                update_pir_manifest()

            # send back the return code
            return_code_encrypted = tmp_box2.encrypt(
                to_byte(return_code), increase_nonce(client_nonce)).ciphertext
            tmp_box2 = None

            # add the packet id
            data = to_byte(PACKET_ID_UPDATE_PK_SEND_DATA_ACK) +\
                   return_code_encrypted

            self.request.sendall(itonb(len(data)) + data)

        elif packet_id == PACKET_ID_SEND_MSG:
            client_pk = data[0:PUBLICKEY_BYTES]
            client_nonce = data[PUBLICKEY_BYTES:PUBLICKEY_BYTES + NONCE_BYTES]
            client_data_crypt = data[PUBLICKEY_BYTES + NONCE_BYTES:]

            box = Box(server_sk, PublicKey(client_pk))
            request = from_byte(box.decrypt(client_data_crypt, client_nonce))
            assert request == 0

            tmp_sk = PrivateKey.generate()
            tmp_pk_raw =\
                tmp_sk.public_key.encode(encoder=nacl.encoding.RawEncoder)

            client_nonce = increase_nonce(client_nonce)
            ciphertext = box.encrypt(tmp_pk_raw, client_nonce).ciphertext
            box = None

            data = to_byte(PACKET_ID_SEND_MSG_RESPONSE) + ciphertext

            self.request.sendall(itonb(len(data)) + data)
            (packet_id, data) = receive_packet(self.request)

            if packet_id != PACKET_ID_SEND_MSG_DATA:
                raise UserWarning("Unexpected packet id.")

            client_nonce = increase_nonce(client_nonce)
            tmp_box1 = Box(tmp_sk, PublicKey(client_pk))
            data = tmp_box1.decrypt(data, client_nonce)
            channel = data[:128]
            msg = data[128:]

            return_code = 0

            print "WRITING TO CHANNEL", channel

            # write message sent by the client
            _global_db_write_lock.acquire(True)
            try:  # make sure the lock will be released again
                with open(STORAGE_CHANNELS_DIR + channel, 'ab+') as f:
                    f.write(itonb(len(msg)) + msg)
            except:
                return_code = 1
            finally:
                _global_db_write_lock.release()

            # send back the return code
            return_code_encrypted = tmp_box1.encrypt(
                to_byte(return_code), increase_nonce(client_nonce)).ciphertext
            tmp_box1 = None

            # add the packet id
            data = to_byte(PACKET_ID_SEND_MSG_DATA_ACK) +\
                   return_code_encrypted

            self.request.sendall(itonb(len(data)) + data)

        elif packet_id == PACKET_ID_RECV_MSG:
            client_pk = data[0:PUBLICKEY_BYTES]
            client_nonce = data[PUBLICKEY_BYTES:PUBLICKEY_BYTES + NONCE_BYTES]
            client_data_crypt = data[PUBLICKEY_BYTES + NONCE_BYTES:]

            box = Box(server_sk, PublicKey(client_pk))
            channel = box.decrypt(client_data_crypt, client_nonce)

            data = None

            # read messages for the client
            _global_db_write_lock.acquire(True)
            try:  # make sure the lock will be released again
                with open(STORAGE_CHANNELS_DIR + channel, 'r+') as f:
                    data = f.read()
                    f.seek(0)
                    f.truncate()
            except Exception as e:
                # print "Error reading file:", e
                # the channel does not exist
                data = ''
            finally:
                _global_db_write_lock.release()

            client_nonce = increase_nonce(client_nonce)
            ciphertext = box.encrypt(data, client_nonce).ciphertext
            box = None

            data = to_byte(PACKET_ID_RECV_MSG_RESPONSE) + ciphertext

            self.request.sendall(itonb(len(data)) + data)

        else:
            raise UserWarning("Unknown packet id.")
Beispiel #35
0
class CrCrypto:
    _sk = None
    _pk = None
    _k = None
    _encrypt_nonce = None
    _decrypt_nonce = None

    session_key = None

    @property
    def pk(self):
        return bytes(self._pk)

    @property
    def k(self):
        return bytes(self._k)

    @k.setter
    def k(self, k):
        self._k = Box.decode(k)

    @property
    def encrypt_nonce(self):
        return bytes(self._encrypt_nonce)

    @encrypt_nonce.setter
    def encrypt_nonce(self, encrypt_nonce):
        self._encrypt_nonce = CrNonce(nonce=encrypt_nonce)

    @property
    def decrypt_nonce(self):
        return bytes(self._decrypt_nonce)

    @decrypt_nonce.setter
    def decrypt_nonce(self, decrypt_nonce):
        self._decrypt_nonce = CrNonce(nonce=decrypt_nonce)

    def keypair(self):
        self._sk = PrivateKey.generate()
        self._pk = self._sk.public_key

    def beforenm(self, pk):
        pk = PublicKey(bytes(pk))
        self._k = Box(self._sk, pk)

    def encrypt(self, message, nonce=None):
        if not nonce:
            self._encrypt_nonce.increment()
            nonce = self.encrypt_nonce
        return self._k.encrypt(message, bytes(nonce))[24:]

    def decrypt(self, ciphertext, nonce=None):
        if not nonce:
            self._decrypt_nonce.increment()
            nonce = self.decrypt_nonce
        return self._k.decrypt(ciphertext, bytes(nonce))

    def encryptPacket(self, messageid, unknown, payload):
        raise NotImplementedError

    def decryptPacket(self, packet):
        raise NotImplementedError
class socket:
    def __init__(self):  # fill in your code here
        # create any lists/arrays/hashes you need
        self.sPort = sock352portTx
        self.rPort = sock352portRx
        self.addr = None
        self.seq = 0
        self.ack = 0
        self.socket = syssock.socket(AF_INET, SOCK_DGRAM)
        self.encrypt = False
        self.myPrivateKey = None
        self.theirPublicKey = None
        self.box = None

        self.packetList = []  # for part 1 we dont need a buffer to be stored,
        # so we're only using this list to store the current packet
        self.PLindex = 0
        return

    def bind(self, address):
        # bind is not used in this assignment
        self.socket.bind(("", int(address[1])))
        return

    def connect(self, *args):

        # example code to parse an argument list
        global sock352portTx
        global ENCRYPT
        if (len(args) >= 1):
            (host, port) = args[0]
        if (len(args) >= 2):
            if (args[1] == ENCRYPT):
                self.encrypt = True

        # your code goes here
        #  create a new sequence number
        #  create a new packet header with the SYN bit set in the flags (use the Struct.pack method)
        #  also set the other fields (e.g sequence #)
        #   add the packet to the send buffer
        #   set the timeout
        #      wait for the return SYN
        #        if there was a timeout, retransmit the SYN packet
        #   set the send and recv packets sequence numbers

        self.addr = (syssock.gethostbyname(syssock.getfqdn(host)), (int)(port))

        #search for correct keys
        if (self.encrypt):
            for k, v in publicKeys.items():
                temp = k
                if (k[0] != '*' and k[1] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])),
                            (int)(k[1]))
                elif (k[0] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])), k[1])
                elif (k[1] != '*'):
                    temp = (k[0], (int)(k[1]))
                if ((temp[0] == self.addr[0] or temp[0] == host
                     or temp[0] == '*')
                        and (temp[1] == self.sPort or temp[1] == self.addr[1]
                             or temp[1] == port or temp[1] == '*')):
                    self.theirPublicKey = v
                    break
            for k, v in privateKeys.items():
                temp = k
                if (k[0] != '*' and k[1] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])),
                            (int)(k[1]))
                elif (k[0] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])), k[1])
                elif (k[1] != '*'):
                    temp = (k[0], (int)(k[1]))
                if ((temp[0] == self.addr[0] or temp[0] == host
                     or temp[0] == '*')
                        and (temp[1] == self.rPort or temp[1] == '*')):
                    self.myPrivateKey = v
                    break
            #make a box
            self.box = Box(self.myPrivateKey, self.theirPublicKey)

        self.seq = random.randint(0, 1000)
        self.socket.bind(("", sock352portRx))

        udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
        header = udpPkt_hdr_data.pack(1, 1, 0, 0, 40, 0, 0, 0, self.seq,
                                      self.ack, 0, 0)
        #first part
        self.socket.sendto(header, self.addr)

        waiting = True
        while (waiting):
            try:
                #second part
                self.socket.settimeout(0.2)
                ret, ad = self.socket.recvfrom(40)
                retStruct = struct.unpack('!BBBBHHLLQQLL', ret)
                synCheck = retStruct[1]
                incSeqNum = retStruct[8]
                incAckNum = retStruct[9]
                #invalid
                if (synCheck != 5 or incAckNum != self.seq + 1
                        or (incSeqNum != self.ack and self.ack != 0)):
                    continue
                self.ack = incSeqNum + 1
            except:
                #first part failed
                self.socket.sendto(header, self.addr)
                continue
            waiting = False
        #third part
        self.seq += 1
        udpPkt_hdr_data2 = struct.Struct(sock352HdrStructStr)
        header2 = udpPkt_hdr_data2.pack(1, 5, 0, 0, 40, 0, 0, 0, self.seq,
                                        self.ack, 0, 0)
        self.socket.sendto(header2, self.addr)
        self.seq += 1
        return

    def listen(self, backlog):
        # listen is not used in this assignments
        return

    def accept(self, *args):
        # example code to parse an argument list
        global ENCRYPT
        if (len(args) >= 1):
            if (args[0] == ENCRYPT):
                self.encrypt = True
        # your code goes here

        # call  __sock352_get_packet() until we get a new conection
        # check the the incoming packet - did we see a new SYN packet?
        self.socket.settimeout(None)
        temp = self.socket.recvfrom(40)
        self.packetList.append(temp[0])
        ad = temp[1]
        self.addr = (syssock.gethostbyname(syssock.getfqdn(ad[0])),
                     (int)(ad[1]))

        #search for correct keys
        if (self.encrypt):
            for k, v in publicKeys.items():
                temp = k
                if (k[0] != '*' and k[1] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])),
                            (int)(k[1]))
                elif (k[0] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])), k[1])
                elif (k[1] != '*'):
                    temp = (k[0], (int)(k[1]))
                if ((temp[0] == self.addr[0] or temp[0] == ad[0]
                     or temp[0] == '*')
                        and (temp[1] == self.sPort or temp[1] == self.addr[1]
                             or temp[1] == ad[1] or temp[1] == '*')):
                    self.theirPublicKey = v
                    break
            for k, v in privateKeys.items():
                temp = k
                if (k[0] != '*' and k[1] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])),
                            (int)(k[1]))
                elif (k[0] != '*'):
                    temp = (syssock.gethostbyname(syssock.getfqdn(k[0])), k[1])
                elif (k[1] != '*'):
                    temp = (k[0], (int)(k[1]))
                if ((temp[0] == self.addr[0] or temp[0] == ad[0]
                     or temp[0] == '*')
                        and (temp[1] == self.rPort or temp[1] == '*')):
                    self.myPrivateKey = v
                    break
            #make a box
            self.box = Box(self.myPrivateKey, self.theirPublicKey)

        self.__sock352_get_packet()
        self.packetList[0] = None
        self.socket.settimeout(0.2)
        return (self, self.addr)

    def close(self):  # fill in your code here
        self.socket.close()
        return

    def send(self, buffer):
        bytessent = 0  # fill in your code here
        # make sure the correct fields are set in the flags
        # make sure the sequence and acknowlegement numbers are correct
        # create a new sock352 header using the struct.pack
        # create a new UDP packet with the header and buffer
        # send the UDP packet to the destination and transmit port
        # set the timeout
        # wait or check for the ACK or a timeout

        udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
        header = None
        packet = None
        if (self.encrypt):
            header = udpPkt_hdr_data.pack(1, 16, 1, 0, 40, 0, 0, 0, self.seq,
                                          self.ack, 0,
                                          len(buffer) + 40)
            packet = header + self.box.encrypt(buffer)
        else:
            header = udpPkt_hdr_data.pack(1, 0, 0, 0, 40, 0, 0, 0, self.seq,
                                          self.ack, 0, len(buffer))
            packet = header + buffer

        bytessent = self.socket.sendto(packet, self.addr)

        waiting = True
        while (waiting):
            try:
                #second part
                ret, ad = self.socket.recvfrom(40)
                retStruct = struct.unpack(sock352HdrStructStr, ret)
                ackCheck = retStruct[1]
                incSeqNum = retStruct[8]
                incAckNum = retStruct[9]
                #invalid
                if (ackCheck != 4 or incAckNum != self.seq + 1
                        or incSeqNum != self.ack):
                    continue
                self.ack = incSeqNum + 1
            except:
                #first part failed
                bytessent = self.socket.sendto(packet, self.addr)
                continue
            waiting = False
        self.seq += 1

        return len(buffer)

    def recv(self, nbytes):
        # fill in your code here
        if (self.encrypt):
            nbytes += 40
        self.packetList[0], ad = self.socket.recvfrom(nbytes + 40)
        self.__sock352_get_packet()
        bytesreceived = self.packetList[0][40:]
        self.packetList[0] = None

        # call __sock352_get_packet() to get packets (polling)
        # check the list of received fragements
        # copy up to bytes_to_receive into a buffer
        # return the buffer if there is some data
        return bytesreceived

    # this is an internal function that demultiplexes all incomming packets
    # it update lists and data structures used by other methods
    def __sock352_get_packet(self):
        # There is a differenct action for each packet type, based on the flags:
        #  First check if it's a connection set up (SYN bit set in flags)
        #    Create a new fragment list
        #    Send a SYN packet back with the correct sequence number
        #    Wake up any readers wating for a connection via accept() or return
        #  else
        #      if it is a connection tear down (FIN)
        #        send a FIN packet, remove fragment list
        #      else if it is a data packet
        #           check the sequence numbers, add to the list of received fragments
        #           send an ACK packet back with the correct sequence number
        #          else if it's nothing it's a malformed packet.
        #              send a reset (RST) packet with the sequence number
        header = self.packetList[self.PLindex][:40]
        msg = self.packetList[self.PLindex][40:]
        headerData = struct.unpack(sock352HdrStructStr, header)

        if (headerData[1] == 1):  #syn
            udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
            self.seq = self.seq = random.randint(0, 1000)
            self.ack = headerData[8] + 1
            syn = udpPkt_hdr_data.pack(1, 5, 0, 0, 40, 0, 0, 0, self.seq,
                                       self.ack, 0, 0)
            self.socket.sendto(syn, self.addr)
            self.socket.settimeout(0.2)

            waiting = True
            while (waiting):
                try:
                    #wait for third part
                    ret, ad = self.socket.recvfrom(40)
                    retStruct = struct.unpack(sock352HdrStructStr, ret)
                    ackCheck = retStruct[1]
                    incSeqNum = retStruct[8]
                    incAckNum = retStruct[9]
                    #invalid
                    if (ackCheck != 5 or incAckNum != self.seq + 1
                            or incSeqNum != self.ack):
                        continue
                    self.ack += 1
                except:
                    #our ack failed; resend
                    self.socket.settimeout(0.2)
                    self.socket.sendto(syn, self.addr)
                    continue
                waiting = False
            self.seq += 1

        elif (headerData[1] == 2):  #fin
            udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
            self.ack += 1
            fin = udpPkt_hdr_data.pack(1, 6, 0, 0, 40, 0, 0, 0, self.seq,
                                       self.ack, 0, 0)
            self.socket.sendto(fin, self.addr)

        elif (headerData[1] == 0 or headerData[1] == 16):  #data
            if (self.encrypt):
                msg = self.box.decrypt(msg)
                self.packetList[self.PLindex] = header + msg
            udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
            self.ack += 1
            ack = udpPkt_hdr_data.pack(1, 4, 0, 0, 40, 0, 0, 0, self.seq,
                                       self.ack, 0, 0)
            self.socket.sendto(ack, self.addr)
            self.seq += 1

        else:  #malformed packet
            udpPkt_hdr_data = struct.Struct(sock352HdrStructStr)
            res = udpPkt_hdr_data.pack(1, 8, 0, 0, 40, 0, 0, 0, self.seq,
                                       self.ack, 0, 0)
            self.socket.sendto(res, self.addr)

        return
Beispiel #37
0
    def accept(self,*args):
        # makes sure again that the server is not already connected
        # because part 1 supports a single connection only
        if self.is_connected:
            print(CONNECTION_ALREADY_ESTABLISHED_MESSAGE)
            return

        # Keeps trying to receive the request to connect from a potential client until we get a connection request
        got_connection_request = False
        while not got_connection_request:
            try:
                # tries to receive a potential SYN packet and unpacks it
                (syn_packet, addr) = self.socket.recvfrom(PACKET_HEADER_LENGTH)
                # example code to parse an argument list (use option arguments if you want)
                global ENCRYPT
                if (len(args) >= 1):
                    if (args[0] == ENCRYPT):
                        self.encrypt = True
                        # Take keys and use them to create another box
                        # Note: we had trouble figuring out how to create the box
                        #       we didn't figure out the parameters in time
                        # We would've created a new box with the server's private key and the client's public key
                        # since the server calls this method to decrypt an incoming packet
                        socket_box = Box(args[0, 0], args[0, 1])  # test, possible (host,port)
                        nonce = nacl.utils.random(Box.NONCE_SIZE)
                        header = socket_box.decrypt(syn_packet)
                        syn_packet = header

                syn_packet = struct.unpack(PACKET_HEADER_FORMAT, syn_packet)

                # if the received packet is not a SYN packet, it ignores the packet
                if syn_packet[PACKET_FLAG_INDEX] == SOCK352_SYN:
                    got_connection_request = True
            # if the receive times out while receiving a SYN packet, it tries to listen again
            except syssock.timeout:
                pass

        # Step 2: Send a SYN/ACK packet for the 3-way handshake
        # creates the flags bit to be the bit-wise OR of SYN/ACK
        flags = SOCK352_SYN | SOCK352_ACK
        # creates the SYN/ACK packet to ACK the connection request from client
        # and sends the SYN to establish the connection from this end
        syn_ack_packet = self.createPacket(flags=flags,
                                           sequence_no=self.sequence_no,
                                           ack_no=syn_packet[PACKET_SEQUENCE_NO_INDEX] + 1)
        # increments the sequence number as it just consumed it when creating the SYN/ACK packet
        self.sequence_no += 1
        # sends the created packet to the address from which it received the SYN packet
        if (self.encrypt == True):
            # Need to encrypt the contents of the packet (didn't get to implement properly here)
            # Needed to make another box to send it
            # Had trouble figuring out Box parameters
            # We would've created a new box with the server's public key and the client's private key
            # since the server calls this method to encrypt an outgoing packet
            encrypted = socket_box.encrypt(syn_ack_packet, nonce)
            syn_ack_packet = encrypted
        self.socket.sendto(syn_ack_packet, addr)

        # Receive the final ACK to complete the handshake and establish connection
        got_final_ack = False
        while not got_final_ack:
            try:
                # keeps trying to receive the final ACK packet to finalize the connection
                (ack_packet, addr) = self.socket.recvfrom(PACKET_HEADER_LENGTH)
                if (self.encrypt == True):
                    # We would need to create another box here (maybe we could've used the previous box, we weren't sure)
                    # Had trouble figuring out Box parameters
                    # We would've created a new box with the server's private key and the client's public key
                    # since the server calls this method to decrypt an incoming packet
                    header = socket_box.decrypt(ack_packet)
                    ack_packet = header
                ack_packet = struct.unpack(PACKET_HEADER_FORMAT, ack_packet)
                # if the unpacked packet has the ACK flag set, we are done
                if ack_packet[PACKET_FLAG_INDEX] == SOCK352_ACK:
                    got_final_ack = True
            # if the server times out when trying to receive the final ACK, it retransmits the SYN/ACK packet
            except syssock.timeout:
                # Need to encrypt the packet before sending (might not be correctly implemented here, wasn't sure about the nonce)
                if (self.encrypt == True):
                    # Needed to make another box to send it (maybe we could've used the previous box, we weren't sure)
                    # Had trouble figuring out Box parameters
                    # We would've created a new box with the server's public key and the client's private key
                    # since the server calls this method to encrypt an outgoing packet
                    encrypted = socket_box.encrypt(syn_ack_packet, nonce)
                    syn_ack_packet = encrypted
                self.socket.sendto(syn_ack_packet, addr)

        # updates the server's ack number to be the last packet's sequence number + 1
        self.ack_no = ack_packet[PACKET_SEQUENCE_NO_INDEX] + 1

        # updates the server's send address
        self.send_address = (addr[0], portTx)

        # connect to the client using the send address just set
        # self.socket.connect(self.send_address)

        # updates the connected boolean to reflect that the server is now connected
        self.is_connected = True

        print("Server is now connected to the client at %s:%s" % (self.send_address[0], self.send_address[1]))

        return self, addr
Beispiel #38
0
 def handle_event(self, event):
     for key in event:
         if key in {"type", "from"}:
             continue
         elif key == "messageid":
             event[key] = int(event[key], 16)
         elif type(event[key]) is bool:
             continue
         elif type(event[key]) in {str, unicode}:
             event[key] = event[key].decode("hex")
     if event["type"] == "socket":
         self.tee = Tee(
             os.path.join(self.BASE_DIR,
                          "session-{}.log".format(event["threadid"])))
         self.log("session started")
     elif event["type"] == "keypair":
         self.sk = PrivateKey(event["sk"])
         self.dump({"sk": self.sk}, function="PrivateKey")
     elif event["type"] == "send" or event["type"] == "recv":
         if event["messageid"] == 10100:
             event.update({"message": event["buffer"]})
             self.dump(event)
         elif event["messageid"] == 20100:
             event.update({"message": event["buffer"]})
             self.dump(event)
         else:
             if self.serverkey:
                 if self.sk:
                     if event["messageid"] == 10101:
                         self.pk = PublicKey(event["buffer"][:32])
                         self.dump({"pk": bytes(self.pk)},
                                   function="PublicKey")
                         event["buffer"] = event["buffer"][32:]
                     if self.pk:
                         if event["messageid"] == 10101 or self.snonce:
                             if event["messageid"] in {10101, 20104
                                                       } or self.rnonce:
                                 if event["messageid"] in {10101, 20104
                                                           } or self.k:
                                     if event["messageid"] in {
                                             10101, 20104
                                     }:
                                         k = Box(self.sk, self.serverkey)
                                         self.dump({"s": k}, function="Box")
                                         b2 = blake2b(digest_size=24)
                                         if event["messageid"] == 20104:
                                             b2.update(bytes(self.snonce))
                                         b2.update(bytes(self.pk))
                                         b2.update(bytes(self.serverkey))
                                         nonce = b2.digest()
                                         if event["messageid"] == 10101:
                                             self.dump(
                                                 {
                                                     "pk": self.pk,
                                                     "serverkey":
                                                     self.serverkey,
                                                     "nonce": nonce
                                                 },
                                                 function="blake2b")
                                         elif event["messageid"] == 20104:
                                             self.dump(
                                                 {
                                                     "snonce": self.snonce,
                                                     "pk": self.pk,
                                                     "serverkey":
                                                     self.serverkey,
                                                     "nonce": nonce
                                                 },
                                                 function="blake2b")
                                     else:
                                         k = self.k
                                         if event["type"] == "send":
                                             self.snonce = self.increment_nonce(
                                                 self.snonce)
                                             nonce = self.snonce
                                         elif event["type"] == "recv":
                                             self.rnonce = self.increment_nonce(
                                                 self.rnonce)
                                             nonce = self.rnonce
                                     ciphertext = event["buffer"]
                                     event.update({
                                         "k":
                                         k,
                                         "nonce":
                                         nonce,
                                         "ciphertext":
                                         event["buffer"]
                                     })
                                     try:
                                         message = k.decrypt(
                                             ciphertext, nonce)
                                     except:
                                         self.dump(event, error=True)
                                         self.log(
                                             "Warning: failed to decrypt {}"
                                             .format(event["messageid"]),
                                             error=True)
                                         if event["messageid"] in {
                                                 10101, 20104
                                         }:
                                             raise
                                     else:
                                         if event["messageid"] == 10101:
                                             self.snonce = message[24:48]
                                             self.dump(
                                                 {"snonce": self.snonce},
                                                 function="slice")
                                             message = message[48:]
                                         elif event["messageid"] == 20104:
                                             self.rnonce = message[:24]
                                             self.k = Box.decode(
                                                 message[24:56])
                                             self.dump(
                                                 {
                                                     "rnonce": self.rnonce,
                                                     "k": self.k
                                                 },
                                                 function="slice")
                                             message = message[56:]
                                         event.update({"message": message})
                                         self.dump(event)
                                 else:
                                     raise Exception(
                                         "Missing shared key ({}).".format(
                                             event["messageid"]))
                             else:
                                 raise Exception(
                                     "Missing server nonce ({}).".format(
                                         event["messageid"]))
                         else:
                             raise Exception(
                                 "Missing client nonce ({}).".format(
                                     event["messageid"]))
                     else:
                         raise Exception("Missing public key ({}).".format(
                             event["messageid"]))
                 else:
                     raise Exception("Missing secret key ({}).".format(
                         event["messageid"]))
             else:
                 raise Exception("Missing server key ({}).".format(
                     event["messageid"]))
     elif event["type"] == "closing":
         self.log("session closed")
     elif event["type"] == "close":
         self.tee.flush()
         self.tee.close()
     else:
         raise Exception("Invalid event type ({}).".format(event["type"]))
Beispiel #39
0
    def decrypt(self, event: EVENT, parse=False):
        """
        Using this function a user tries to decrypt an event.

        Parameters
        ----------
        self : USER
            The user decrypting an event
        event : EVENT
            The event to decrypt
        parse : bool
            Describes if event need to be parsed
        """
        # msg = '{"event": "app/action", "content": "xxx"}'
        # log_event = '{"hmac": "'+digest.hex()+'", "cyphertext": "'+encrypted.hex()+'"}'
        # log_event = {"cleartext": {"event": "chat/create", "content": "two"}}
        # log_event = {"cleartext": {"event": "log/sync", "content": "RAW_BACNET_EVENT"}}
        # print(event)

        # determine sender
        sender = get_alias_by_id(self.fid)
        # check if need to sync
        e = check_sync(event.content())
        if (e != None):
            # parse this content
            event = e
            sender = get_alias_by_id(e.fid.hex())
            # return 'sync: ' + e.fid.hex() + ' ' + e.content().__repr__()
        data = loads(event.content())

        try:
            # print cleartext
            return sender + '@all: ' + data['cleartext']['event'] + ' ' + data[
                'cleartext']['content']
        except KeyError:
            # cyphertext --> needs decryption
            cypher = bytes.fromhex(data['cyphertext'])
            if bytes.fromhex(data['hmac']) == hmac.digest(
                    event.fid, cypher, sha256):
                try:
                    # try to decrypt private event
                    box = Box(
                        self.get_curve_private_key(),
                        PublicKey(
                            crypto_sign_ed25519_pk_to_curve25519(event.fid)))
                    cleartext = box.decrypt(cypher, encoder=Base64Encoder)
                    data = loads(cleartext)
                    inv = check_invite(data)
                    if parse and inv != None:
                        self.add_channel(inv)
                    return sender + '@private: ' + data['event'] + ' ' + data[
                        'content']
                except nacl.exceptions.CryptoError:
                    # not allowed to decrypt private boy
                    return sender + '@privatebox'
            # loop through other channels hkey
            for c in self.channels:
                c = CHANNEL(self, c[0])
                channel = get_alias_by_id(c.cid)
                hkey = c.hkey_bytes()
                if bytes.fromhex(data['hmac']) == hmac.digest(
                        hkey, cypher, sha256):
                    # print('matched hkey: '+hkey)
                    # print('hmac: '+data['hmac'])
                    # print('unboxing...')
                    for dk in c.dkeys_bytes():
                        try:
                            # decrypt message in channel
                            box = SecretBox(dk)
                            cleartext = box.decrypt(cypher,
                                                    encoder=Base64Encoder)
                            data = loads(cleartext)
                            rekey = check_rekey(data)
                            if parse and rekey != None:
                                c.add_dkey(self, rekey)
                            return sender + '@[' + channel + ']: ' + data[
                                'event'] + ' ' + data['content']
                        except nacl.exceptions.CryptoError:
                            # not allowed to decrypt channel message
                            continue  # perhaps there is another dkey
                    return sender + '@lock[' + channel + ']'  # no dkey found (not a member anymore)
            return sender + '@secret'  # - not cleartext nor matching a channel
Beispiel #40
0
    def test_activate_token(self):
        """
        Ensure we can activate our token
        """

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        url = reverse('authentication_login')
        response = self.client.post(url, data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info').decode()),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce').decode())).decode())

        token = request_data.get('token', False)

        server_public_key_hex = request_data.get('session_public_key', False)

        # lets encrypt our token
        user_private_key = PrivateKey(self.test_real_private_key,
                                      encoder=nacl.encoding.HexEncoder)
        user_session_private_key = PrivateKey(user_session_private_key_hex,
                                              encoder=nacl.encoding.HexEncoder)
        server_public_key = PublicKey(server_public_key_hex,
                                      encoder=nacl.encoding.HexEncoder)

        # create both our crypto boxes
        user_crypto_box = Box(user_private_key, server_public_key)
        session_crypto_box = Box(user_session_private_key, server_public_key)

        # decrypt session secret
        session_secret_key_nonce_hex = request_data.get(
            'session_secret_key_nonce', False)
        session_secret_key_nonce = nacl.encoding.HexEncoder.decode(
            session_secret_key_nonce_hex)
        session_secret_key_hex = request_data.get('session_secret_key', False)
        session_secret_key = nacl.encoding.HexEncoder.decode(
            session_secret_key_hex)
        decrypted_session_key_hex = session_crypto_box.decrypt(
            session_secret_key, session_secret_key_nonce)

        # decrypt user validator
        user_validator_nonce_hex = request_data.get('user_validator_nonce',
                                                    False)
        user_validator_nonce = nacl.encoding.HexEncoder.decode(
            user_validator_nonce_hex)
        user_validator_hex = request_data.get('user_validator', False)
        user_validator = nacl.encoding.HexEncoder.decode(user_validator_hex)

        decrypted_user_validator = user_crypto_box.decrypt(
            user_validator, user_validator_nonce)

        # encrypt user validator with session key
        verification_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        verification_nonce_hex = nacl.encoding.HexEncoder.encode(
            verification_nonce)
        decrypted_session_key = nacl.encoding.HexEncoder.decode(
            decrypted_session_key_hex)
        secret_box = nacl.secret.SecretBox(decrypted_session_key)
        encrypted = secret_box.encrypt(decrypted_user_validator,
                                       verification_nonce)
        verification = encrypted[len(verification_nonce):]
        verification_hex = nacl.encoding.HexEncoder.encode(verification)

        # encrypt authorization validator with session key
        authorization_validator_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        authorization_validator_nonce_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator_nonce)
        encrypted = secret_box.encrypt(
            json.dumps({}).encode("utf-8"), authorization_validator_nonce)
        authorization_validator = encrypted[len(authorization_validator_nonce
                                                ):]
        authorization_validator_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator)

        url = reverse('authentication_activate_token')

        data = {
            'token': token,
            'verification': verification_hex.decode(),
            'verification_nonce': verification_nonce_hex.decode(),
        }

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token,
                                HTTP_AUTHORIZATION_VALIDATOR=json.dumps({
                                    'text':
                                    authorization_validator_hex.decode(),
                                    'nonce':
                                    authorization_validator_nonce_hex.decode(),
                                }))
        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertTrue(
            response.data.get('user', {}).get('id', False),
            'User ID does not exist in login response')
        self.assertEqual(
            response.data.get('user', {}).get('email', False), self.test_email,
            'Email is wrong in response or does not exist')
        self.assertEqual(
            response.data.get('user', {}).get('secret_key',
                                              False), self.test_secret_key,
            'Secret key is wrong in response or does not exist')
        self.assertEqual(
            response.data.get('user', {}).get('secret_key_nonce', False),
            self.test_secret_key_nonce,
            'Secret key is wrong in response or does not exist')
Beispiel #41
0
    def test_login_with_duo(self):
        """
        Ensure we can login with duo
        """
        url = reverse('authentication_login')

        models.Duo.objects.create(
            user=self.user_obj,
            title='My Sweet Title',
            duo_integration_key='duo_integration_key',
            duo_secret_key=encrypt_with_db_secret('duo_secret_key'),
            duo_host='duo_secret_key',
            enrollment_user_id='enrollment_user_id',
            enrollment_activation_code='enrollment_activation_code',
            enrollment_expiration_date=timezone.now() + timedelta(seconds=600),
            active=True,
        )

        self.user_obj.duo_enabled = True
        self.user_obj.save()

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        models.Token.objects.all().delete()

        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info')),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce'))).decode())

        self.assertTrue(request_data.get('token', False),
                        'Token does not exist in login response')

        self.assertEqual(request_data.get('required_multifactors',
                                          False), ['duo_2fa'],
                         'duo_2fa not part of the required_multifactors')

        self.assertEqual(
            request_data.get('user', {}).get('public_key',
                                             False), self.test_public_key,
            'Public key is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('private_key',
                                             False), self.test_private_key,
            'Private key is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('private_key_nonce', False),
            self.test_private_key_nonce,
            'Private key nonce is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('user_sauce',
                                             False), self.test_user_sauce,
            'Secret key nonce is wrong in response or does not exist')

        self.assertNotEqual(request_data.get('session_public_key', False),
                            False, 'Session public key does not exist')
        self.assertNotEqual(request_data.get('user_validator', False), False,
                            'User validator does not exist')
        self.assertNotEqual(request_data.get('user_validator_nonce', False),
                            False, 'User validator nonce does not exist')
        self.assertNotEqual(request_data.get('session_secret_key', False),
                            False, 'Session secret key does not exist')
        self.assertNotEqual(
            request_data.get('session_secret_key_nonce', False), False,
            'Session secret key nonce does not exist')

        self.assertEqual(models.Token.objects.count(), 1)
Beispiel #42
0
    def test_login(self):
        """
        Ensure we can login
        """

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        url = reverse('authentication_login')

        models.Token.objects.all().delete()

        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info')),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce'))).decode())

        self.assertTrue(request_data.get('token', False),
                        'Token does not exist in login response')

        self.assertEqual(
            request_data.get('required_multifactors', False), [],
            'required_multifactors not part of the return value or not an empty list'
        )

        self.assertEqual(
            request_data.get('user', {}).get('public_key',
                                             False), self.test_public_key,
            'Public key is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('private_key',
                                             False), self.test_private_key,
            'Private key is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('private_key_nonce', False),
            self.test_private_key_nonce,
            'Private key nonce is wrong in response or does not exist')
        self.assertEqual(
            request_data.get('user', {}).get('user_sauce',
                                             False), self.test_user_sauce,
            'Secret key nonce is wrong in response or does not exist')

        self.assertNotEqual(request_data.get('session_public_key', False),
                            False, 'Session public key does not exist')
        self.assertNotEqual(request_data.get('user_validator', False), False,
                            'User validator does not exist')
        self.assertNotEqual(request_data.get('user_validator_nonce', False),
                            False, 'User validator nonce does not exist')
        self.assertNotEqual(request_data.get('session_secret_key', False),
                            False, 'Session secret key does not exist')
        self.assertNotEqual(
            request_data.get('session_secret_key_nonce', False), False,
            'Session secret key nonce does not exist')

        self.assertEqual(models.Token.objects.count(), 1)
Beispiel #43
0
    def test_token_expiration(self):
        """
        Ensure expired tokens are invalid
        """

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        # lets delete all tokens
        models.Token.objects.all().delete()

        # lets create one new token
        url = reverse('authentication_login')

        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info')),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce'))).decode())

        self.assertTrue(request_data.get('token', False),
                        'Token does not exist in login response')

        token = request_data.get('token', False)

        # lets fake activation for our token
        tok = models.Token.objects.filter(
            key=TokenAuthentication.user_token_to_token_hash(token)).get()
        tok.active = True
        tok.user_validator = None
        tok.save()

        # encrypt authorization validator with session key
        secret_box = nacl.secret.SecretBox(tok.secret_key,
                                           encoder=nacl.encoding.HexEncoder)
        authorization_validator_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        authorization_validator_nonce_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator_nonce)
        encrypted = secret_box.encrypt(
            json.dumps({}).encode("utf-8"), authorization_validator_nonce)
        authorization_validator = encrypted[len(authorization_validator_nonce
                                                ):]
        authorization_validator_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator)

        # to test we first query our datastores with the valid token

        url = reverse('datastore')

        data = {}

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token,
                                HTTP_AUTHORIZATION_VALIDATOR=json.dumps({
                                    'text':
                                    authorization_validator_hex.decode(),
                                    'nonce':
                                    authorization_validator_nonce_hex.decode(),
                                }))
        response = self.client.get(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        # seems to work, so lets now put the token back into the past

        token_obj = models.Token.objects.get()

        token_obj.valid_till = timezone.now() - timedelta(seconds=10)

        token_obj.save()

        # ... and try again

        url = reverse('datastore')

        data = {}

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token,
                                HTTP_AUTHORIZATION_VALIDATOR=json.dumps({
                                    'text':
                                    authorization_validator_hex.decode(),
                                    'nonce':
                                    authorization_validator_nonce_hex.decode(),
                                }))
        response = self.client.get(url, data)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
Beispiel #44
0
    k = public.encode(encoder=Base16Encoder)
    msg = (b'CRYPTO 1.0 REQUEST\r\n' + b'Name: Jeff Dwyer\r\n' +
           b'PublicKey: ' + k + b'\r\n' + b'\r\n')

    # Sending Request
    print(msg.decode('utf-8'))
    totalsent = 0
    while totalsent < len(msg):
        sent = s.send(msg[totalsent:])
        if sent == 0:
            raise RuntimeError('socket connection broken')
        totalsent += sent

    chunks = []
    listen = True
    while listen:
        chunk = s.recv(2048)
        chunks.extend(chunk)
        listen = chunk != b''

    c = bytearray(chunks).decode('utf-8')
    server_public = c.split('\r\n')[2].split(': ')[1]
    c = c.split('\r\n')[3].split(': ')[1]
    dumb = PrivateKey.generate()
    dumb.public_key._public_key = base64.b16decode(server_public)
    b = Box(private, dumb.public_key)
    c = c.encode('utf-8')
    c = binascii.unhexlify(c)
    print(b.decrypt(c))
Beispiel #45
0
    def setUp(self):

        # our public / private key box
        box = PrivateKey.generate()

        self.test_email = "*****@*****.**"
        self.test_username = "******" + settings.ALLOWED_DOMAINS[0]
        self.test_authkey = binascii.hexlify(
            os.urandom(settings.AUTH_KEY_LENGTH_BYTES)).decode()
        self.test_public_key = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        self.test_real_private_key = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        self.test_private_key = binascii.hexlify(
            os.urandom(settings.USER_PRIVATE_KEY_LENGTH_BYTES)).decode()
        self.test_private_key_nonce = binascii.hexlify(
            os.urandom(settings.NONCE_LENGTH_BYTES)).decode()
        self.test_secret_key = binascii.hexlify(
            os.urandom(settings.USER_SECRET_KEY_LENGTH_BYTES)).decode()
        self.test_secret_key_nonce = binascii.hexlify(
            os.urandom(settings.NONCE_LENGTH_BYTES)).decode()
        self.test_user_sauce = '24350a638726c0073ec43c8c84ac110bfc2c45e7a430a257f768837f1470c9c7'

        data = {
            'username': self.test_username,
            'email': self.test_email,
            'authkey': self.test_authkey,
            'public_key': self.test_public_key,
            'private_key': self.test_private_key,
            'private_key_nonce': self.test_private_key_nonce,
            'secret_key': self.test_secret_key,
            'secret_key_nonce': self.test_secret_key_nonce,
            'user_sauce': self.test_user_sauce,
        }

        url = reverse('authentication_register')
        response = self.client.post(url, data)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

        self.user_obj = models.User.objects.get(username=self.test_username)
        self.user_obj.is_email_active = True
        self.user_obj.save()

        url = reverse('authentication_login')

        # our public / private key box
        box = PrivateKey.generate()

        # our hex encoded public / private keys
        user_session_private_key_hex = box.encode(
            encoder=nacl.encoding.HexEncoder).decode()
        user_session_public_key_hex = box.public_key.encode(
            encoder=nacl.encoding.HexEncoder).decode()

        server_crypto_box = Box(
            PrivateKey(user_session_private_key_hex,
                       encoder=nacl.encoding.HexEncoder),
            PublicKey(settings.PUBLIC_KEY, encoder=nacl.encoding.HexEncoder))

        login_info_nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
        encrypted = server_crypto_box.encrypt(
            json.dumps({
                'username': self.test_username,
                'authkey': self.test_authkey,
            }).encode("utf-8"), login_info_nonce)
        login_info_encrypted = encrypted[len(login_info_nonce):]

        data = {
            'login_info':
            nacl.encoding.HexEncoder.encode(login_info_encrypted).decode(),
            'login_info_nonce':
            nacl.encoding.HexEncoder.encode(login_info_nonce).decode(),
            'public_key':
            user_session_public_key_hex,
        }

        response = self.client.post(url, data)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info')),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce'))).decode())

        self.test_token = request_data.get('token', False)

        # lets fake activation for our token
        tok = models.Token.objects.filter(
            key=TokenAuthentication.user_token_to_token_hash(
                self.test_token)).get()
        tok.active = True
        tok.user_validator = None
        tok.save()

        response = self.client.post(url, data)

        request_data = json.loads(
            server_crypto_box.decrypt(
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info')),
                nacl.encoding.HexEncoder.decode(
                    response.data.get('login_info_nonce'))).decode())

        self.test_token2 = request_data.get('token', False)

        # lets fake activation for our token
        self.tok2 = models.Token.objects.filter(
            key=TokenAuthentication.user_token_to_token_hash(
                self.test_token2)).get()
        self.tok2.active = True
        self.tok2.user_validator = None
        self.tok2.save()

        # encrypt authorization validator with session key
        secret_box = nacl.secret.SecretBox(tok.secret_key,
                                           encoder=nacl.encoding.HexEncoder)
        authorization_validator_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        authorization_validator_nonce_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator_nonce)
        encrypted = secret_box.encrypt(
            json.dumps({}).encode("utf-8"), authorization_validator_nonce)
        authorization_validator = encrypted[len(authorization_validator_nonce
                                                ):]
        authorization_validator_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator)

        self.authorization_validator1 = json.dumps({
            'text':
            authorization_validator_hex.decode(),
            'nonce':
            authorization_validator_nonce_hex.decode(),
        })

        # encrypt authorization validator with session key
        secret_box = nacl.secret.SecretBox(self.tok2.secret_key,
                                           encoder=nacl.encoding.HexEncoder)
        authorization_validator_nonce = nacl.utils.random(
            nacl.secret.SecretBox.NONCE_SIZE)
        authorization_validator_nonce_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator_nonce)
        encrypted = secret_box.encrypt(
            json.dumps({}).encode("utf-8"), authorization_validator_nonce)
        authorization_validator = encrypted[len(authorization_validator_nonce
                                                ):]
        authorization_validator_hex = nacl.encoding.HexEncoder.encode(
            authorization_validator)

        self.authorization_validator2 = json.dumps({
            'text':
            authorization_validator_hex.decode(),
            'nonce':
            authorization_validator_nonce_hex.decode(),
        })
Beispiel #46
0
    def authenticate(self, request):
        try:
            token_hash = self.get_token_hash(request)
        except exceptions.AuthenticationFailed:
            token_hash = None

        fileserver = None
        if token_hash is not None:
            try:
                fileserver = Fileserver_Cluster_Members.objects.only('pk').get(
                    key=token_hash)
            except Fileserver_Cluster_Members.DoesNotExist:
                pass

        if fileserver is None and token_hash is not None:
            cluster_id, fileserver_info_enc = self.get_fileserver_validator(
                request)
            try:
                cluster = Fileserver_Cluster.objects.get(pk=cluster_id)
            except Fileserver_Cluster.DoesNotExist:
                msg = _('Invalid token header. Cluster ID does not exist.')
                raise exceptions.AuthenticationFailed(msg)

            cluster_public_key = decrypt_with_db_secret(
                cluster.auth_public_key)

            cluster_crypto_box = Box(
                PrivateKey(settings.PRIVATE_KEY,
                           encoder=nacl.encoding.HexEncoder),
                PublicKey(cluster_public_key,
                          encoder=nacl.encoding.HexEncoder))

            try:
                fileserver_info = json.loads(
                    cluster_crypto_box.decrypt(
                        nacl.encoding.HexEncoder.decode(
                            fileserver_info_enc)).decode())
            except nacl.exceptions.CryptoError:
                msg = _('Invalid fileserver info.')
                raise exceptions.AuthenticationFailed(msg)

            if not constant_time_compare(fileserver_info['CLUSTER_ID'],
                                         cluster_id):
                msg = _('Invalid fileserver info.')
                raise exceptions.AuthenticationFailed(msg)

            if not constant_time_compare(
                    FileserverAliveAuthentication.user_token_to_token_hash(
                        fileserver_info['FILESERVER_ID']), token_hash):
                msg = _('Invalid fileserver info.')
                raise exceptions.AuthenticationFailed(msg)

            self.validate_cluster_shard_access(
                cluster_id, fileserver_info['SHARDS_PUBLIC'])

            fileserver = Fileserver_Cluster_Members.objects.create(
                create_ip=get_ip(request),
                fileserver_cluster_id=cluster_id,
                key=token_hash,
                public_key=fileserver_info['FILESERVER_PUBLIC_KEY'],
                secret_key=fileserver_info['FILESERVER_SESSION_KEY'],
                version=fileserver_info['VERSION'],
                hostname=fileserver_info['HOSTNAME'],
                url=fileserver_info['HOST_URL'],
                read=fileserver_info['READ'],
                write=fileserver_info['WRITE'],
                allow_link_shares=fileserver_info.get('ALLOW_LINK_SHARES',
                                                      True),
                delete_capability=fileserver_info['DELETE'],
                valid_till=timezone.now() + datetime.timedelta(seconds=30),
            )

            for shard in fileserver_info['SHARDS_PUBLIC']:
                Fileserver_Cluster_Member_Shard_Link.objects.create(
                    shard_id=shard['shard_id'],
                    member_id=fileserver.id,
                    read=shard['read'],
                    write=shard['write'],
                    allow_link_shares=shard.get('allow_link_shares', True),
                    delete_capability=shard['delete'],
                    ip_read_whitelist=json.dumps(
                        fileserver_info['IP_READ_WHITELIST']),
                    ip_read_blacklist=json.dumps(
                        fileserver_info['IP_READ_BLACKLIST']),
                    ip_write_whitelist=json.dumps(
                        fileserver_info['IP_WRITE_WHITELIST']),
                    ip_write_blacklist=json.dumps(
                        fileserver_info['IP_WRITE_BLACKLIST']),
                )

        if fileserver is None:
            msg = _('Login failed')
            raise exceptions.AuthenticationFailed(msg)

        return fileserver, fileserver
Beispiel #47
0
    def connect(self,*args):                # different from Project 1 code because it's *args instead of address
        # example code to parse an argument list (use option arguments if you want)
        global portTx  # sock352portTx
        global ENCRYPT

        if (len(args)>=1):
            # Example code:
            # (host, port) = args[0]

            # sets the send address to the tuple (address ip, transmit port)
            self.send_address = (args[0], portTx)        # (address[0], portTx)

            # binds the client on the receiving port
            self.socket.bind((args[0], portRx))          # (address[0], portRx)

            # makes sure the client isn't already connected. If it is, prints an error message
            if self.is_connected:
                print(CONNECTION_ALREADY_ESTABLISHED_MESSAGE)
                return
        if (len(args)>=2):
            # check constant, add encryption
            # create nonce, find keys, create Box object
            # FILL IN WITH CODE
            if (args[1] == ENCRYPT):
                self.encrypt = True
                # Note: we had trouble figuring out how to create the box
                #       we didn't figure out the parameters in time
                # We would've created a new box with the server's private key and the client's public key
                # since the client calls this method to encrypt an outgoing packet
                socket_box = Box(args[0,0], args[0,1])   # test, possible (host,port)
                nonce = nacl.utils.random(Box.NONCE_SIZE)
                # Bob wishes to send Alice an encrypted message so Bob must make a Box with
                #   his private key and Alice's public key
                #bob_box = Box(skbob, pkalice)

        else:
            print("ERROR: Provide destination host and port number")


        # Step 1: Request to connect to the server by setting the SYN flag
        # first the packet is created using createPacket and passing in the apprpriate variables
        syn_packet = self.createPacket(flags=SOCK352_SYN, sequence_no=self.sequence_no)
        # we need to encrypt the new packet before sending it
        if (self.encrypt == True):
            # Needed to make another box to send it (maybe we could've used the previous box, we weren't sure)
            # Had trouble figuring out Box parameters
            # We would've created a new box with the server's private key and the client's public key
            # since the client calls this method to encrypt an outgoing packet
            encrypted = socket_box.encrypt(syn_packet, nonce)
            syn_ack_packet = encrypted
        self.socket.sendto(syn_packet, self.send_address)
        # increments the sequence since it was consumed in creation of the SYN packet
        self.sequence_no += 1

        # Receives the SYN_ACK from Step 2 within accept()

        received_handshake_packet = False
        while not received_handshake_packet:
            try:
                # tries to receive a SYN/ACK packet from the server using recvfrom and unpacks it
                (syn_ack_packet, addr) = self.socket.recvfrom(PACKET_HEADER_LENGTH)
                # Create a box and decrypt the message
                if (self.encrypt == True):
                    # Needed to make another box to send it (maybe we could've used the previous box, we weren't sure)
                    # Had trouble figuring out Box parameters
                    # We would've created a new box with the server's public key and the client's private key
                    # since the client calls this method to decrypt an outgoing packet
                    header = socket_box.decrypt(syn_ack_packet)
                    syn_ack_packet = header
                syn_ack_packet = struct.unpack(PACKET_HEADER_FORMAT, syn_ack_packet)
                # if it receives a reset marked flag for any reason, abort the handshake
                if syn_ack_packet[PACKET_FLAG_INDEX] == SOCK352_RESET:
                    print
                    "Connection was reset by the server"
                    return

                # if it receives a packet, and it is SYN/ACK, we are done
                if syn_ack_packet[PACKET_FLAG_INDEX] == SOCK352_SYN | SOCK352_ACK:
                    received_handshake_packet = True

                # if it receives a packet with an incorrect ACK from its sequence number,
                # it tries to receive more packets
                if syn_ack_packet[PACKET_ACK_NO_INDEX] != self.sequence_no:
                    received_handshake_packet = False
            # retransmits the SYN packet in case of timeout when receiving a SYN/ACK from the server
            except syssock.timeout:
                self.socket.sendto(syn_packet, self.send_address)

        # sets the client's acknowledgement number to be SYN/ACK packet's sequence number + 1
        self.ack_no = syn_ack_packet[PACKET_SEQUENCE_NO_INDEX] + 1

        # Step 3: Send a packet with the ACK flag set to acknowledge the SYN/ACK packet
        ack_packet = self.createPacket(flags=SOCK352_ACK,
                                       sequence_no=self.sequence_no,
                                       ack_no=self.ack_no)
        # increments the sequence number as it was consumed by the ACK packet
        self.sequence_no += 1

        # sets the connected boolean to be true
        self.is_connected = True

        # sends the ack packet to the server, as it assumes it's connected now
        # Needed to make another box to send it (maybe we could've used the previous box, we weren't sure)
        # Had trouble figuring out Box parameters
        # We would've created a new box with the server's private key and the client's public key
        # since the client calls this method to encrypt an outgoing packet
        if (self.encrypt == True):
            encrypted = socket_box.encrypt(ack_packet, nonce)
            ack_packet = encrypted
        self.socket.sendto(ack_packet, self.send_address)
        print("Client is now connected to the server at %s:%s" % (self.send_address[0], self.send_address[1]))
def decrypt(cipher, privateKey, publicKey):
    box = Box(privateKey, publicKey)
    cipher_raw = base64url_decode(cipher)

    return box.decrypt(cipher_raw) \
        .decode('utf-8')
Beispiel #49
0
 def decrypt(self, encrypted, public_key):
     from nacl.public import Box
     key = self.private_key
     box = Box(key, public_key)
     return box.decrypt(encrypted)
Beispiel #50
0
def listen():
    global shared_secret
    global listener_stream
    global secretNotKnown
    global nonce
    global nonce2
    global callInProgress
    p = pyaudio.PyAudio()
    listener_stream = p.open(format=p.get_format_from_width(WIDTH),
                             channels=CHANNELS,
                             rate=RATE,
                             output=True,
                             frames_per_buffer=Listen_CHUNK)

    PORT = 50007  #23555#50007 changed to 50007 from 50008             # Arbitrary non-privileged port
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

    s.bind(('', PORT))
    s.listen(1)

    #caller = threading.Thread(target=call)
    #caller.start()

    conn, addr = s.accept()  #here the thread waits for a connection
    global waitingForCall
    if waitingForCall:
        if (conn):
            waitingForCall = False
            talker = threading.Thread(target=talk)
            talker.start()

    print('Connected by', addr)
    time.sleep(2)
    data = conn.recv(Listen_CHUNK)  # #1024
    #might need this ? nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
    i = 1
    print("first data received")
    print(len(data))

    writer.start()
    #https://github.com/pyca/pynacl/blob/51acad0e34e125378d166d6bb9662408056702e0/tests/test_public.py
    #alice_box = Box(skalice, pkbob)
    global skbob
    pkalice = jsonpickle.decode(firebase.get('/fatman/pk', None))
    pkalice = PublicKey(pkalice, encoder=HexEncoder)
    bob_box = Box(skbob, pkalice)

    data = bob_box.decrypt(data)
    shared_secret = bob_box.shared_key()
    talk_secret_box = nacl.secret.SecretBox(shared_secret)
    print("listen", shared_secret)
    secretNotKnown = False
    data = conn.recv(Listen_CHUNK)
    while data != '' and callInProgress:
        try:
            data = talk_secret_box.decrypt(data)
            data = oc.decode(data)
            jitter_buf.put(data)
            data = conn.recv(Listen_CHUNK)  # #1024
            i = i + 1
        except Exception:
            print("Error warning:", sys.exc_info()[0])
            print("length of shit data", len(data))
            data = conn.recv(Listen_CHUNK -
                             len(data))  # throwing away this god awful derter
            #talk_secret_box = nacl.secret.SecretBox(shared_secret)

            time.sleep(.05)
            data = conn.recv(Listen_CHUNK)  # #1024
            if (not callInProgress):
                break
            continue
            #break

    listener_stream.stop_stream()
    listener_stream.close()
    p.terminate()
    conn.close()
    callInProgress = False
    print("listen stopped")
Beispiel #51
0
# Encrypt our message, it will be exactly 40 bytes longer than the
# original message as it stores authentication information and the
# nonce alongside it.

# This is a nonce, it *MUST* only be used once, but it is not considered
#  secret and can be transmitted or stored alongside the ciphertext. A
#  good source of nonces are just sequences of 24 random bytes.

nonceB2A = nacl.utils.random(Box.NONCE_SIZE)
nonceA2B = nacl.utils.random(Box.NONCE_SIZE)
encryptedB2A = bob_box.encrypt(messageB2A, nonceB2A)
encryptedA2B = alice_box.encrypt(messageA2B, nonceA2B)

# Decrypt our message, an exception will be raised if the encryption was
# tampered with or there was otherwise an error.
plaintextB2A = alice_box.decrypt(encryptedB2A)
plaintextA2B = bob_box.decrypt(encryptedA2B)

print("the plaintext Bob sent is: %s" % (plaintextB2A))
print("the plaintext Alice sent is: %s" % (plaintextA2B))

# the following code illustrates that decryption should fail when we modify the message

# make a copy of the message into a byte-array which is mutable
bogusMessage = bytearray(encryptedB2A)

# we have to wrap the message with a bytes() function to make an immutable copy acceptable
# for the nacl library
plaintext_should_work = alice_box.decrypt(bytes(bogusMessage))
print("the plaintext Bob sent is: %s" % (plaintext_should_work))
Beispiel #52
0
def callback():
    """Takes the response from the provider and verify the identity of the logged in user

    Returns:
        Redirect to the wanted page after authentication
    """
    session = request.environ.get("beaker.session")
    data = request.query.get("signedAttempt")

    if not data:
        return abort(400, "signedAttempt parameter is missing")

    data = j.data.serializers.json.loads(data)

    if "signedAttempt" not in data:
        return abort(400, "signedAttempt value is missing")

    username = data["doubleName"]

    if not username:
        return abort(400, "DoubleName is missing")

    res = requests.get(f"https://login.threefold.me/api/users/{username}",
                       {"Content-Type": "application/json"})
    if res.status_code != 200:
        return abort(400, "Error getting user pub key")
    pub_key = res.json()["publicKey"]

    user_pub_key = VerifyKey(j.data.serializers.base64.decode(pub_key))

    # verify data
    signedData = data["signedAttempt"]

    verifiedData = user_pub_key.verify(
        j.data.serializers.base64.decode(signedData)).decode()

    data = j.data.serializers.json.loads(verifiedData)

    if "doubleName" not in data:
        return abort(400, "Decrypted data does not contain (doubleName)")

    if "signedState" not in data:
        return abort(400, "Decrypted data does not contain (state)")

    if data["doubleName"] != username:
        return abort(400, "username mismatch!")

    # verify state
    state = data["signedState"]
    if state != session["state"]:
        return abort(400, "Invalid state. not matching one in user session")

    nonce = j.data.serializers.base64.decode(data["data"]["nonce"])
    ciphertext = j.data.serializers.base64.decode(data["data"]["ciphertext"])

    try:
        priv = j.core.identity.me.nacl.private_key
        box = Box(priv, user_pub_key.to_curve25519_public_key())
        decrypted = box.decrypt(ciphertext, nonce)
    except nacl.exceptions.CryptoError:
        return abort(400, "Error decrypting data")

    try:
        result = j.data.serializers.json.loads(decrypted)
    except JSONDecodeError:
        return abort(400, "3Bot login returned faulty data")

    if "email" not in result:
        return abort(400, "Email is not present in data")

    email = result["email"]["email"]

    sei = result["email"]["sei"]
    res = requests.post(
        "https://openkyc.live/verification/verify-sei",
        headers={"Content-Type": "application/json"},
        json={"signedEmailIdentifier": sei},
    )

    if res.status_code != 200:
        return abort(400, "Email is not verified")

    username = username.lower(
    )  # workaround usernames that are returned by signed attempt with camel cases
    session["username"] = username
    session["email"] = email
    session["authorized"] = True
    session["signedAttempt"] = signedData
    try:
        tid = j.sals.reservation_chatflow.reservation_chatflow.validate_user({
            "username":
            username,
            "email":
            email
        }).id
        session["tid"] = tid
        session["explorer"] = j.core.identity.me.explorer_url
    except Exception as e:
        j.logger.warning(
            f"Error in validating user: {username} with email: {email} in explorer: {j.core.identity.me.explorer_url}\n from {str(e)}"
        )
    return redirect(unquote(session.get("next_url", "/")))
Beispiel #53
0
message2 = {"api_token": "8de531a564e2cb932bf1382b964199ad5967f38fc76c6d366f9e0fa323ffb2e5",
"public_key" : basekey}
r2= requests.post("https://whoomp.cs.uwaterloo.ca/458a3/api/pke/set-key",headers=headers1, json=message2)
print(r2.status_code)

#part 2b
nessiekey = nacl.public.PublicKey(Str1, encoder=nacl.encoding.Base64Encoder)
box = Box(sk, nessiekey)
secret = "take a walk"
cipher = box.encrypt(secret)
cipherbase64 = base64.standard_b64encode(cipher)
message2 = {"api_token": "8de531a564e2cb932bf1382b964199ad5967f38fc76c6d366f9e0fa323ffb2e5",
"to" :"nessie", "message": cipherbase64}
r= requests.post("https://whoomp.cs.uwaterloo.ca/458a3/api/pke/send",headers=headers1, json=message2)
print(r.status_code)


#part 3
message2 = {"api_token": "8de531a564e2cb932bf1382b964199ad5967f38fc76c6d366f9e0fa323ffb2e5"}
r= requests.post("https://whoomp.cs.uwaterloo.ca/458a3/api/pke/inbox",headers=headers1, json=message2)

str = json.loads(r.text)
str2 = str[0]['message']
print str2

ciphmsg = base64.standard_b64decode(str2)
lastmsg = box.decrypt(ciphmsg)

print lastmsg

Beispiel #54
0
from nacl import utils
from nacl.public import PrivateKey, Box
from nacl.encoding import Base64Encoder

aliceKey = PrivateKey.generate()
alicePub = aliceKey.public_key

bobKey = PrivateKey.generate()
bobPub = bobKey.public_key

# with open('pubkey.txt', mode='w') as f:
#      f.write(bytes.decode(pubKey) + '\n')

aliceBox = Box(aliceKey, bobPub)
bobBox = Box(bobKey, alicePub)

message = b'This is a secret message!'

encryptedMessage = aliceBox.encrypt(message, encoder=Base64Encoder)

print("Plaintext: {}".format(message))
print("Encrypted: {}".format(encryptedMessage))

print("Bob decrypted it: {}".format(
    bobBox.decrypt(encryptedMessage, encoder=Base64Encoder)))
Beispiel #55
0
class socket:

    def __init__(self):
        self.receivedACK = []
        self.receivedSeq_no = []
        self.encrypt = False
        return

    def bind(self, address):
        return

    def connect(self, *args):

        # Check for encryption
        global ENCRYPT, privateKeys, publicKeys
        if (len(args) >= 1):
            address = args[0]
        if (len(args) >= 2):
            if (args[1] == ENCRYPT):
                self.encrypt = True
                self.box = Box(privateKeys[('*', '*')], publicKeys[(address[0], str(Tx))])

        # Fill in header values
        global version, opt_ptr, protocol, header_len, checksum, source_port, dest_port, window
        flags = SOCK352_SYN
        sequence_no = random.random()
        ack_no = 0
        payload_len = 0

        # Pack the data
        sock352PktHdrData = '!BBBBHHLLQQLL'
        udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
        header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                      source_port, dest_port, sequence_no, ack_no, window,
                                      payload_len)

        # Connect with the server
        destination = address[0]
        s.connect((destination, Tx))
        print('Trying to connect w/ server..')

        # Encrypt message if encrypt is enabled
        if self.encrypt:
            nonce = nacl.utils.random(Box.NONCE_SIZE)
            header = self.box.encrypt(header, nonce)

        # Send SYN flagged header to server and receive the server's response and check to see if SYN/ACK
        # If the server had another response, resend the packet
        while flags != SOCK352_SYN + SOCK352_ACK:
            s.send(header)
            receivedHeader = ''
            # Check for encrypion before receiving
            if self.encrypt:
                receivedHeader = s.recv(header_len + 40)
                receivedHeader = self.box.decrypt(receivedHeader)
            else:
                receivedHeader = s.recv(header_len)

            (version, flags, opt_ptr, protocol, header_len, checksum,
             source_port, dest_port, sequence_no, ack_no, window,
             payload_len) = udpPkt_hdr_data.unpack(receivedHeader)

        # Record received ACK/seq_no
        self.receivedACK.append(ack_no)
        self.receivedSeq_no.append(sequence_no)

        # After receiving SYN/ACK from server, send ACK
        flags = SOCK352_ACK
        temp = sequence_no
        sequence_no = ack_no
        ack_no = temp + 1
        header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                      source_port, dest_port, sequence_no, ack_no, window,
                                      payload_len)

        # Encrypt message if encrypt is enabled
        if self.encrypt:
            nonce = nacl.utils.random(Box.NONCE_SIZE)
            header = self.box.encrypt(header, nonce)

        s.send(header)
        return

    def listen(self, backlog):
        return

    def accept(self, *args):
        # Wait to receive header data
        print('waiting for connection...')

        # Check for encryption
        if (len(args) >= 1):
            if (args[0] == ENCRYPT):
                self.encrypt = True

        (clientsocket, address) = self.__sock352_get_packet()
        print(address)
        return (clientsocket, address)

    def close(self):  # fill in your code here
        # Fill in header values, make sure flags is FIN
        global version, opt_ptr, protocol, header_len, checksum, source_port, dest_port, window
        flags = SOCK352_FIN
        sequence_no = 0
        ack_no = 0
        payload_len = 0

        # Pack the data
        sock352PktHdrData = '!BBBBHHLLQQLL'
        udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
        header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                      source_port, dest_port, sequence_no, ack_no, window,
                                      payload_len)

        # Encrypt message if encrypt is enabled
        if self.encrypt:
            nonce = nacl.utils.random(Box.NONCE_SIZE)
            header = self.box.encrypt(header, nonce)

            # Send header and close the socket
        s.send(header)
        s.close()
        return

    def send(self, buffer):  # fill in your code here
        # Fill in header values: sequence_no will be the last receivedACK, and ack_no
        # will be the last received sequence_no + 1
        global version, opt_ptr, protocol, header_len, checksum, source_port, dest_port, window
        flags = SOCK352_ACK
        sequence_no = self.receivedACK[-1]
        ack_no = self.receivedSeq_no[-1] + 1

        # Hard-coded fragmentsize because can't handle it dynamically :(
        # This is the max # of bytes that the server can receive
        # as defined in server1
        index = 0;
        FRAGMENTSIZE = 4096
        fragment = ''

        while (index != len(buffer)):
            if (len(buffer) - index > FRAGMENTSIZE):
                payload_len = FRAGMENTSIZE

                # Pack the header data and send it to server
                sock352PktHdrData = '!BBBBHHLLQQLL'
                udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
                header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                              source_port, dest_port, sequence_no, ack_no, window,
                                              payload_len)

                # Encrypt message if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    header = self.box.encrypt(header, nonce)

                s.send(header)

                # Send fragment to server
                fragment = buffer[index:(index + FRAGMENTSIZE)]

                # Encrypt fragment if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    fragment = self.box.encrypt(fragment, nonce)

                    # Set timeout and send fragment
                try:
                    s.settimeout(.2)
                    s.send(fragment)
                except syssock.timeout:
                    s.send(fragment)
                finally:
                    s.settimeout(None)

                print('sent packet: '), len(fragment), ('bytes')

                # TODO: receive ACK?
                # Check for encrypion before receiving
                if self.encrypt:
                    receivedHeader = s.recv(header_len + 40)
                    receivedHeader = self.box.decrypt(receivedHeader)
                else:
                    receivedHeader = s.recv(header_len)

                # Increment index
                index += FRAGMENTSIZE
            else:
                payload_len = len(buffer) - index

                # Pack the header data
                sock352PktHdrData = '!BBBBHHLLQQLL'
                udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
                header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                              source_port, dest_port, sequence_no, ack_no, window,
                                              payload_len)

                # Encrypt message if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    header = self.box.encrypt(header, nonce)

                s.send(header)

                # Send fragment to server
                fragment = buffer[index:len(buffer)]

                # Encrypt fragment if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    fragment = self.box.encrypt(fragment, nonce)

                    # Set timeout and send fragment
                try:
                    s.settimeout(.2)
                    s.send(fragment)
                except syssock.timeout:
                    s.send(fragment)
                finally:
                    s.settimeout(None)

                print('sent packet: '), len(fragment), ('bytes')

                # TODO: receive ACK?
                # Check for encrypion before receiving
                if self.encrypt:
                    receivedHeader = s.recv(header_len + 40)
                    receivedHeader = self.box.decrypt(receivedHeader)
                else:
                    receivedHeader = s.recv(header_len)

                # Increment index
                index = payload_len
                break;

        return len(buffer)

    def recv(self, nbytes):
        # Fill in header values
        global version, opt_ptr, protocol, header_len, checksum, source_port, dest_port, window

        # Receive and unpack header data from client
        receivedHeader = ''
        # Check for encrypion before receiving
        if self.encrypt:
            receivedHeader = s.recv(header_len + 40)
            receivedHeader = self.box.decrypt(receivedHeader)
        else:
            receivedHeader = s.recv(header_len)
        sock352PktHdrData = '!BBBBHHLLQQLL'
        udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
        (version, flags, opt_ptr, protocol, header_len, checksum,
         source_port, dest_port, sequence_no, ack_no, window,
         payload_len) = udpPkt_hdr_data.unpack(receivedHeader)

        # Receive the bytes dictated by the payload_len
        # Check for encrypion before receiving
        if self.encrypt:
            bytesreceived = s.recv(payload_len + 40)
            bytesreceived = self.box.decrypt(bytesreceived)
        else:
            bytesreceived = s.recv(payload_len)

            # Give ack_no the value of the next sequence number the client should send over
        # And give sequence_no the value of what the client is asking for
        temp = ack_no
        ack_no = sequence_no + payload_len + 1
        sequence_no = temp
        flags = SOCK352_ACK

        # Pack and send the ACK to the client
        header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                      source_port, dest_port, sequence_no, ack_no, window,
                                      payload_len)

        # Encrypt message if encrypt is enabled
        if self.encrypt:
            nonce = nacl.utils.random(Box.NONCE_SIZE)
            header = self.box.encrypt(header, nonce)

        s.send(header)
        print('received '), len(bytesreceived), (' bytes')

        return bytesreceived

    def __sock352_get_packet(self):
        global version, opt_ptr, protocol, header_len, checksum, source_port, dest_port, window

        # Receive and unpack the data
        receivedHeader = ''
        addr = (1, 1)

        # If encryption is enabled, receive a longer encrypted message and decrypt it
        if self.encrypt:
            (receivedHeader, addr) = s.recvfrom(header_len + 40)
            if addr[0] == '127.0.0.1':
                self.box = Box(privateKeys[('*', '*')], publicKeys[('localhost', str(Tx))])
            else:
                self.box = Box(privateKeys[('*', '*')], publicKeys[(addr[0], str(Tx))])
            receivedHeader = self.box.decrypt(receivedHeader)
        else:
            (receivedHeader, addr) = s.recvfrom(header_len)

        sock352PktHdrData = '!BBBBHHLLQQLL'
        udpPkt_hdr_data = struct.Struct(sock352PktHdrData)
        (version, flags, opt_ptr, protocol, header_len, checksum,
         source_port, dest_port, sequence_no, ack_no, window,
         payload_len) = udpPkt_hdr_data.unpack(receivedHeader)

        # If the header flag was SYN
        if flags == SOCK352_SYN:
            # Check to see if the address is in the list of connections
            # and if it's not, send back a random sequence_no and a
            # and set the ack_no to the incoming sequence_no + 1
            # Also instantiate a second socket to communicate w/ client
            if addr not in connections:
                connections.append(addr)
                ack_no = sequence_no + 1
                sequence_no = random.random()
                flags = SOCK352_SYN + SOCK352_ACK
                header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                              source_port, dest_port, sequence_no, ack_no, window,
                                              payload_len)
                s.connect(addr)

                # Check for encryption before sending
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    header = self.box.encrypt(header, nonce)

                    # Send out the SYN/ACK flagged header, and wait for
                # ACK response from client
                while flags != SOCK352_ACK:
                    s.send(header)

                    # Check for encrypion before receiving
                    if self.encrypt:
                        receivedHeader = s.recv(header_len + 40)
                        receivedHeader = self.box.decrypt(receivedHeader)
                    else:
                        receivedHeader = s.recv(header_len)

                    (version, flags, opt_ptr, protocol, header_len, checksum,
                     source_port, dest_port, sequence_no, ack_no, window,
                     payload_len) = udpPkt_hdr_data.unpack(receivedHeader)

                print('Connected to:')
                return (self, addr)
            # If it is in the list, the connection is reset
            else:
                sequence_no = sequence_no + 1
                flags = SOCK352_RESET
                header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                              source_port, dest_port, sequence_no, ack_no, window,
                                              payload_len)
                s.connect(addr)
                # Encrypt message if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    header = self.box.encrypt(header, nonce)
                s.send(header)
                return

        else:
            # If the header flag is FIN, send back a FIN and remove the addr
            # from connections and clear the fragments
            if flags == SOCK352_FIN:
                flags = SOCK352_FIN
                header = udpPkt_hdr_data.pack(version, flags, opt_ptr, protocol, header_len, checksum,
                                              source_port, dest_port, sequence_no, ack_no, window,
                                              payload_len)
                connections.remove(addr)
                self.fragments.clear()
                s.connect(addr)
                # Encrypt message if encrypt is enabled
                if self.encrypt:
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    header = self.box.encrypt(header, nonce)
                s.send(header)
                print('closing connection')
Beispiel #56
0
r = request.urlopen(req)
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
print(data)
print(data["public_key"])
jessie_signed_prekey = base64.b64decode(data["public_key"])

jessie_pk = nacl.bindings.crypto_sign_open(jessie_signed_prekey, jessie_id_vk)

message = b"lmao"
nonce = nacl.utils.random(Box.NONCE_SIZE)
encrypted = nacl.bindings.crypto_box(message, nonce, jessie_pk, bytes(secretkey))
data = parse.urlencode({
        "api_token": "f0cd8f18e9d280fd23f9eae0d1df65bc0a93d1dbfc3e9f730d31c425249ce05e",
        "to": "jessie",
        "message": base64.b64encode(nonce + encrypted)
}).encode()
req = request.Request('https://whoomp.cs.uwaterloo.ca/458a3/api/prekey/send', data)
r = request.urlopen(req)

# Part 3
data = parse.urlencode({
        "api_token": "f0cd8f18e9d280fd23f9eae0d1df65bc0a93d1dbfc3e9f730d31c425249ce05e"
}).encode()
req = request.Request('https://whoomp.cs.uwaterloo.ca/458a3/api/prekey/inbox', data)
r = request.urlopen(req)
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
encrypted = base64.b64decode(data[0]["message"])
box = Box(secretkey, PublicKey(jessie_pk))
plaintext = box.decrypt(encrypted)
print(plaintext.decode('utf-8'))
Beispiel #57
0
    def validate(self, attrs: dict) -> dict:

        username = attrs.get('username')
        emergency_authkey = attrs.get('emergency_authkey')

        update_data = nacl.encoding.HexEncoder.decode(attrs.get('update_data'))
        update_data_nonce = nacl.encoding.HexEncoder.decode(
            attrs.get('update_data_nonce'))

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # TODO REPLACE WITH USERNAME_OR_RECOVERY_CODE_INCORRECT
            msg = _("Username or recovery code incorrect.")
            raise exceptions.ValidationError(msg)

        emergency_codes = Emergency_Code.objects.filter(user_id=user.id)

        valid_emergency_code = None

        for emergency_code in emergency_codes:
            if not check_password(emergency_authkey,
                                  emergency_code.emergency_authkey):
                continue
            valid_emergency_code = emergency_code
            break

        if not valid_emergency_code:
            msg = _("Username or emergency code incorrect.")
            raise exceptions.ValidationError(msg)

        if valid_emergency_code.verifier_issue_date + datetime.timedelta(
                0, settings.RECOVERY_VERIFIER_TIME_VALID) < timezone.now():
            msg = _("Validator expired.")
            raise exceptions.ValidationError(msg)

        try:
            crypto_box = Box(
                PrivateKey(valid_emergency_code.verifier,
                           encoder=nacl.encoding.HexEncoder),
                PublicKey(user.public_key, encoder=nacl.encoding.HexEncoder))

            login_info = json.loads(
                crypto_box.decrypt(update_data, update_data_nonce).decode())

        except:
            msg = _("Validator failed.")
            raise exceptions.ValidationError(msg)

        if not valid_emergency_code.user.is_active:
            msg = _('User account is disabled.')
            raise exceptions.ValidationError(msg)

        if not valid_emergency_code.user.is_email_active:
            msg = _('E-mail is not yet verified.')
            raise exceptions.ValidationError(msg)

        attrs['emergency_code'] = valid_emergency_code
        attrs['user'] = user
        attrs['session_duration'] = settings.DEFAULT_TOKEN_TIME_VALID

        attrs['device_fingerprint'] = login_info.get('device_fingerprint', '')
        attrs['device_description'] = login_info.get('device_description', '')
        attrs['user_session_public_key'] = login_info.get(
            'session_public_key', '')

        device_time = login_info.get('device_time', None)
        if device_time is None:
            attrs['device_time'] = None
        else:
            attrs['device_time'] = dateutil.parser.parse(device_time)

        return attrs
Beispiel #58
0
class socket:
    def __init__(self):
        # Initalizes the socket, setting all values to default
        print("Initializing Lib")
        self.connectionFlag = False
        self.prev_ack = 0
        self.next_sequence_no = 0
        self.next_acknolodgement_no = 0
        self.start_sequence_no = 0
        self.encrypt = False
        self.window = 32000

        return

    def bind(self, address):
        # bind is not used in this assignment
        print "Bind"
        return

    def connect(self, *args):
        global ENCRYPT
        global publicKeysHex
        global privateKeysHex
        global publicKeys
        global privateKeys
        global sock
        print("In connect:")

        if (len(args) >= 1):
            print("args[0], ", args[0])
            (host, port) = args[0]

        if (len(args) >= 2):
            if (args[1] == ENCRYPT):
                self.encrypt = True

        # If the encrypt flag is on we will create a box for the client
        # to send encrypted messages
        if (self.encrypt is True):
            print "Connection is using encrpytion"
            print("Public key =" + str(publicKeysHex[(host, recv_port)]))
            print("Private key =" + str(privateKeysHex[('*', '*')]))
            self.box = Box(privateKeys[('*', '*')],
                           publicKeys[(host, recv_port)])
            # Create nonce for client sending messages
            self.nonce = nacl.utils.random(Box.NONCE_SIZE)

        # Generates a random initial sequence number and creates and packs a SYN pkt
        self.start_sequence_no = randint(0, 5000)
        self.ack_number = 0
        print "Creating SYN Packet......."
        SYN_pkt = pkt()
        SYN_pkt.create_syn(self.start_sequence_no)
        print "Packing SYN Packet......."
        packed_SYN_pkt = SYN_pkt.packPacket()
        len_hdr = len(packed_SYN_pkt)
        print "Sending SYN Packet....."

        # If the connection is encrypted, you must encrypt the packed synpacket and get the length of the
        # newly encrypted pkt
        if (self.encrypt):
            packed_SYN_pkt = self.box.encrypt(packed_SYN_pkt, self.nonce)
            self.length_encrypted_header = len(packed_SYN_pkt)
            len_hdr = self.length_encrypted_header

        # Until succesfull connecction we will continue to try
        while True:
            # Try to send the packet
            sock.sendto(packed_SYN_pkt, (host, int(send_port)))
            try:
                # unless we get a response then it wasn't received
                sock.settimeout(def_timeout_value)
                raw_packet, sender = sock.recvfrom(len_hdr)

                break
            except syssock.timeout:
                # We didnt get a respone, run the while loop again
                print "Socket Timed Out.... Resending Packet"
                time.sleep(2)

        # If there is encryption then the ack must be decrypted as well
        if (self.encrypt):
            recieved_packet_header = packetHeader(self.box.decrypt(raw_packet))
        else:
            recieved_packet_header = packetHeader(raw_packet)
        print "Packet received... Packed Header is: ", recieved_packet_header
        print "Flags for recieved_packet_header.flags:", recieved_packet_header.flags
        print "received ACK_NO: ", recieved_packet_header.ack_no

        # Check to make sure the received response is an SYN ACK
        if (recieved_packet_header.flags != 5
                or recieved_packet_header.ack_no !=
            (SYN_pkt.header.sequence_no + 1)):
            print("Ack inforrectly formatted")
        else:
            print "Client: Connection created..."
            self.connectionFlag = True
            connections[sender] = sender
            self.destination = sender
            self.next_sequence_no = recieved_packet_header.ack_no
            self.prev_ack = recieved_packet_header.ack_no - 1
        return

    def listen(self, backlog):
        return

    def accept(self, *args):
        global connections
        global ENCRYPT

        # Checks to see if args length is > 1, if so it checks to if the server is encrypted
        if (len(args) >= 1):
            if (args[0] == ENCRYPT):
                self.encrypt = True
                print "This is Encrypted server"

        print "Server: Waiting...."
        # We will loop until a connection is accepted
        while True:
            try:
                sock.settimeout(def_timeout_value)
                raw_packet, sender = sock.recvfrom(def_pkt_size)
                if (self.encrypt):
                    self.length_encrypted_header = len(raw_packet)
                    self.box = Box(privateKeys[('*', '*')],
                                   publicKeys[('localhost', send_port)])
                    raw_packet = self.box.decrypt(raw_packet)
                    print "PrivateKey = " (
                        (privateKeysHex[('*', '*')] + " PublicKey = " +
                         str(publicKeysHex[('localhost', recv_port)])))
                    print "Encrypted Server Creating Box"
                print "Packet Read During Accept"
                print "Packet received... Packed Header is: ", binascii.hexlify(
                    raw_packet)
                recieved_packet_header = packetHeader(raw_packet)
                # If statement to make sure the pkt received is a SYN pkt
                if (recieved_packet_header.flags != SOCK352_SYN):
                    print "Not Connection Request"
                else:
                    break
            except syssock.timeout:
                print "Socket timed out recieving"
                time.sleep(5)
                continue
            finally:
                sock.settimeout(None)

        # Once we reach this point we have a connection. We then send back an ACK
        print "Accepted Connection"
        self.start_sequence_no = randint(0, (math.pow(2, 64) - 1))
        self.prev_ack = recieved_packet_header.sequence_no + recieved_packet_header.payload_len - 1
        ack_packet = pkt()
        if (connections.has_key(sender)):
            print "Server already connectionFlag to this client"
            ack_packet.header.flags = SOCK352_RESET
        else:
            ack_packet.header.flags = (SOCK352_ACK + SOCK352_SYN)
        print "Ack_Packet_Header: ", ack_packet.header.flags
        print "received seqnum: ", recieved_packet_header.sequence_no
        ack_packet.header.sequence_no = self.start_sequence_no
        ack_packet.header.ack_no = recieved_packet_header.sequence_no + 1
        print "Ack_No", ack_packet.header.ack_no
        packed_ack_packet = ack_packet.packPacket()
        # Checks to see if encrypted connection, if so must create nonce and encrpyt the ACK pkt
        if (self.encrypt):
            self.nonce = nacl.utils.random(Box.NONCE_SIZE)
            packed_ack_packet = self.box.encrypt(packed_ack_packet, self.nonce)

        # Records the total number of bytes sent.
        bytesSent = sock.sendto(packed_ack_packet, sender)
        self.destination = sender
        print bytesSent
        print "Sender: ", sender

        return (self, sender)

    def close(self):
        global connections

        # Creates the FIN pkt for when close() is called
        FIN_packet = pkt()
        FIN_packet.header.flags = SOCK352_FIN

        # Packs the FIN pkt, if encryption we encrypt the FIN pkt
        packed_FIN = FIN_packet.packPacket()
        if (self.encrypt):
            packed_FIN = self.box.encrypt(packed_FIN, self.nonce)

        # Send the FIN pkt to the destination and reset the variables
        sock.sendto(packed_FIN, self.destination)
        self.connectionFlag = False
        connections.pop(self.destination, None)
        self.destination = {}
        self.prev_ack = 0
        self.next_sequence_no = 0
        self.next_acknolodgement_no = 0
        self.start_sequence_no = 0
        return

    def send(self, buffer):
        print "*******************************************"
        print "Inside Send Method..........."
        global sPort  # example using a variable global to the Python module

        # The next six lines create the pkt based on desired data
        print("BUFFER LEN " + str(len(buffer)))
        payload = buffer[:4096]
        # payload = buffer
        data_packet = pkt()
        data_packet.header.payload_len = len(payload)
        data_packet.header.sequence_no = self.next_sequence_no
        data_packet.header.ack_no = self.next_acknolodgement_no
        data_packet.payload = payload
        print "Length Payload: ", len(payload)

        packed_data_packet = data_packet.packPacket()
        print "Length of Data_Packet: ", len(packed_data_packet)
        # print "Packed Value   :", binascii.hexlify(packed_data_packet)

        # Encrypt pkt if connection is encrypted
        print "Sending pkt"
        if (self.encrypt):
            self.nonce = nacl.utils.random(Box.NONCE_SIZE)
            packed_data_packet = self.box.encrypt(packed_data_packet,
                                                  self.nonce)

        # Attempts to send the pkt. If timeout, it will resend. Like accept, if the timeout is hit
        # the exception will be thrown. There are also checks for the ACK number and flags to make sure it is a
        # proper ACK pkt
        while True:
            # We resend the pkt if we have a timeout
            bytesSent = sock.sendto(packed_data_packet, self.destination)
            print "Bytes Sent: ", bytesSent

            try:
                sock.settimeout(def_timeout_value)
                if (self.encrypt):
                    raw_packet_header, sender = sock.recvfrom(
                        self.length_encrypted_header)
                    raw_packet_header = self.box.decrypt(raw_packet_header)
                else:
                    raw_packet_header, sender = sock.recvfrom(header_len)

                recieved_packet_header = packetHeader(raw_packet_header)
                print "SeqNum Sent: ", data_packet.header.sequence_no
                print "Ack received: ", recieved_packet_header.ack_no
                print "Window size: ", recieved_packet_header.window

                if (recieved_packet_header.flags != SOCK352_ACK
                        or recieved_packet_header.ack_no !=
                    (data_packet.header.sequence_no +
                     data_packet.header.payload_len)):
                    print "Not proper ACK"

                break

            except syssock.timeout:
                print "Socket Timed Out.... Resending Packet"
                continue

            finally:
                sock.settimeout(None)

        # Stores the last ACK # and the next ACK #
        self.next_sequence_no = recieved_packet_header.ack_no  # SIGNALED THAT THIS LINE IS UNREACHABLE
        self.prev_ack = recieved_packet_header.ack_no - 1
        self.next_acknolodgement_no = recieved_packet_header.ack_no + 1

        print "Returning ", bytesSent

        # Check to see if encrypted connection, if so must set length to encrypted header size
        if (self.encrypt):
            len_hdr = self.length_encrypted_header
        else:
            len_hdr = header_len

        bytesSent = len(buffer)

        if (len(buffer) > 4096):
            bytesSent = 4096

        return recieved_packet_header.window

    def recv(self, nbytes):
        print "In Recieve"
        print("nbytes == " + str(nbytes))

        # Loop used to receive pkt. Exception thrown if timeout. Also checks to see if it is a valid data pkt
        # or if it is a FIIN pkt

        while True:
            try:
                # This means we got a pkt.
                sock.settimeout(def_timeout_value)
                raw_packet, sender = sock.recvfrom(5000)
                if (self.encrypt):
                    raw_packet = self.box.decrypt(raw_packet)

                recieved_packet_header = packetHeader(raw_packet[:header_len])
                print "Packet received... Packed Header is: ", binascii.hexlify(
                    raw_packet[:header_len])
                print "Unpacked Header is: ", udpPkt_hdr_data.unpack(
                    raw_packet[:header_len])

                if (recieved_packet_header.flags > 0):
                    print "Not data pkt"
                    if (recieved_packet_header.flags == SOCK352_FIN):
                        sock.close()

                else:
                    break

            except syssock.timeout:
                print "Socket timed out recieving"

            finally:
                sock.settimeout(None)

        # ack_window = pkt()
        # ack_window.create_ack_window(nbytes)
        # packed_ack_window = ack_window.packPacket()
        # sock.sendto(packed_ack_window, sender)

        self.next_sequence_no = recieved_packet_header.ack_no  # SIGNALED THAT THIS LINE IS UNREACHABLE
        # Stores the last ACK # and the next ACK num
        self.prev_ack = recieved_packet_header.ack_no - 1
        self.next_acknolodgement_no = recieved_packet_header.ack_no + 1
        recieved_packet_header.window = nbytes

        payload = raw_packet[(40):(40 + nbytes)]

        print "payload length: ", len(payload)
        # as a 4 byte integer in network byte order (big endian)

        # Creates an ACK pkt and checks to see if it needs to be encrypted. Packet is then sent to sender
        ack_packet = pkt()
        ack_packet.create_ack(recieved_packet_header)
        print "Ack Packet Ack_NO: ", ack_packet.header.ack_no
        print "Ack Packet WINDOW: ", ack_packet.header.window
        packed_ack_packet = ack_packet.packPacket()
        if (self.encrypt):
            packed_ack_packet = self.box.encrypt(packed_ack_packet, self.nonce)
        sock.sendto(packed_ack_packet, sender)

        return payload
# This is our message to send, it must be a bytestring as Box will treat it
#   as just a binary blob of data.

# Note the "b" in the front of the string means to keep the string in
# binary/ascii format, as opposed to UTF-8 or Unicode
message = b"This is a binary message"

# Encrypt our message, it will be exactly 40 bytes longer than the
#   original message as it stores authentication information and the
#   nonce alongside it.

# the encrypt function must take a nonce now
# encrypted = bob_box.encrypt(message)

# This is a nonce, it *MUST* only be used once, but it is not considered
#   secret and can be transmitted or stored alongside the ciphertext. A
#   good source of nonces are just sequences of 24 random bytes.
nonce = nacl.utils.random(Box.NONCE_SIZE)
encrypted = bob_box.encrypt(message, nonce)

print("The length of the plaintext is %d and the cyphertext is %d" %
      (len(message), len(encrypted)))
# Alice creates a second box with her private key to decrypt the message
alice_box = Box(skalice, pkbob)

# Decrypt our message, an exception will be raised if the encryption was
#   tampered with or there was otherwise an error.
plaintext = alice_box.decrypt(encrypted)

print("the plaintext is: %s" % (plaintext))
Beispiel #60
0
def public_decrypt(message, origin_pub, target_priv):
    priv = PrivateKey(binascii.unhexlify(target_priv))
    pub = PublicKey(binascii.unhexlify(origin_pub))
    box = Box(priv, pub)
    return box.decrypt(message)