def test_boxnm(self):
     msg = b'Are you suggesting coconuts migrate?'
     # run 1
     nonce1 = libnacl.utils.rand_nonce()
     pk1, sk1 = libnacl.crypto_box_keypair()
     pk2, sk2 = libnacl.crypto_box_keypair()
     k1 = libnacl.crypto_box_beforenm(pk2, sk1)
     k2 = libnacl.crypto_box_beforenm(pk1, sk2)
     enc_msg = libnacl.crypto_box_afternm(msg, nonce1, k1)
     self.assertNotEqual(msg, enc_msg)
     clear_msg = libnacl.crypto_box_open_afternm(enc_msg, nonce1, k2)
     self.assertEqual(clear_msg, msg)
Ejemplo n.º 2
0
 def test_boxnm(self):
     msg = b'Are you suggesting coconuts migrate?'
     # run 1
     nonce1 = libnacl.utils.rand_nonce()
     pk1, sk1 = libnacl.crypto_box_keypair()
     pk2, sk2 = libnacl.crypto_box_keypair()
     k1 = libnacl.crypto_box_beforenm(pk2, sk1)
     k2 = libnacl.crypto_box_beforenm(pk1, sk2)
     enc_msg = libnacl.crypto_box_afternm(msg, nonce1, k1)
     self.assertNotEqual(msg, enc_msg)
     clear_msg = libnacl.crypto_box_open_afternm(enc_msg, nonce1, k2)
     self.assertEqual(clear_msg, msg)
Ejemplo n.º 3
0
def confirm(request, addr, publicKey, password):
    her_public = b64decode(request['pk'][0])
    response = {
        'credentials': {
            ('%s:%s' % addr): {
                'publicKey': publicKey,
                'password': password
            }
        }
    }
    response = json.dumps(response)

    my_public, my_private = libnacl.crypto_box_keypair()
    nonce = libnacl.utils.rand_nonce()
    encrypted = b64encode(
        libnacl.crypto_box(response, nonce, her_public, my_private))

    offer = {
        'type': 'credentials',
        'interface': 'udp',
        'message': encrypted,
        'n': b64encode(nonce),
        'pk': b64encode(my_public),
        'wrbtVersion': WRBT_VERSION
    }

    return PREFIX + '#' + urlencode(offer)
Ejemplo n.º 4
0
    def crypto_hello(self) -> bytes:
        """Create a client tunnel packet consisting of:
        * 8 bytes: the ASCII bytes "oqQN2kaH"
        * 32 bytes: client's short-term public key C'
        * 64 bytes: all zero
        * 8 bytes: a client-selected compressed nonce in little-endian
                   form. This compressed nonce is implicitly prefixed by
                   "splonebox-client" to form a 24-byte nonce
        * 80 bytes: a cryptographic box encrypted and authenticated to the
                    server's long-term public key S from the client's short-term
                    public key C' using this 24-byte nonce. The 64-byte
                    plaintext inside the box has the following contents:
            * 64 bytes: all zero

        :return: client hello packet
        """
        self.crypto_nonce_update()

        identifier = struct.pack("<8s", b"oqQN2kaH")
        nonce = struct.pack("<16sQ", b"splonebox-client-H", self.nonce)
        zeros = bytearray(64)

        self.clientshorttermpk, \
            self.clientshorttermsk = libnacl.crypto_box_keypair()
        box = libnacl.crypto_box(zeros, nonce, self.serverlongtermpk,
                                 self.clientshorttermsk)

        nonce = struct.pack("<Q", self.nonce)

        return b"".join(
            [identifier, self.clientshorttermpk, zeros, nonce, box])
Ejemplo n.º 5
0
 def test_box_seal(self):
     msg = b'Are you suggesting coconuts migrate?'
     # run 1
     pk, sk = libnacl.crypto_box_keypair()
     enc_msg = libnacl.crypto_box_seal(msg, pk)
     self.assertNotEqual(msg, enc_msg)
     clear_msg = libnacl.crypto_box_seal_open(enc_msg, pk, sk)
     self.assertEqual(clear_msg, msg)
     # run 2
     pk2, sk2 = libnacl.crypto_box_keypair()
     enc_msg2 = libnacl.crypto_box_seal(msg, pk2)
     self.assertNotEqual(msg, enc_msg2)
     clear_msg2 = libnacl.crypto_box_seal_open(enc_msg2, pk2, sk2)
     self.assertEqual(clear_msg2, msg)
     # Check bits
     self.assertNotEqual(enc_msg, enc_msg2)
Ejemplo n.º 6
0
        def test_guest_rpc(self):
            s_pub, s_pk = libnacl.crypto_box_keypair()

            cid2 = b'cid2' * 4

            #Servers identify clients by client id and key pairs.
            #In this case, the server is allowing a guest login from a server it's never heard of.

            #The special value 'guest' tells the client to generate a new keypair.
            s = Server(allow_guest=True, ecc_keypair=(s_pub, s_pk))
            c = Client(keypair='guest',
                       serverkey=s_pub,
                       clientID=cid2,
                       cipher=2)

            time.sleep(0.55)
            r = Register("test", "foooo")

            s.registers[400] = r

            #Using the "Direct function" method which doesn't have as much introspection capability
            s.registers[401] = lambda c, a: a

            x = c.call(400, b'A test string')

            self.assertEqual(x, b'A test string')

            x = c.call(401, b'A test string')

            self.assertEqual(x, b'A test string')
Ejemplo n.º 7
0
 def test_gen(self):
     pk1, sk1 = libnacl.crypto_box_keypair()
     pk2, sk2 = libnacl.crypto_box_keypair()
     pk3, sk3 = libnacl.crypto_box_keypair()
     self.assertEqual(len(pk1), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertEqual(len(sk1), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertEqual(len(pk2), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertEqual(len(sk2), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertEqual(len(pk3), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertEqual(len(sk3), libnacl.crypto_box_PUBLICKEYBYTES)
     self.assertNotEqual(pk1, sk1)
     self.assertNotEqual(pk2, sk2)
     self.assertNotEqual(pk3, sk3)
     self.assertNotEqual(pk1, pk2)
     self.assertNotEqual(pk1, pk3)
     self.assertNotEqual(sk1, sk2)
     self.assertNotEqual(sk2, sk3)
Ejemplo n.º 8
0
def request():
    my_public, my_private = libnacl.crypto_box_keypair()
    query = {
        'type': 'peer',
        'interface': 'udp',
        'pk': b64encode(my_public),
        'wrbtVersion': WRBT_VERSION
    }
    url = PREFIX + '#' + urlencode(query)
    return url, b64encode(my_private)
Ejemplo n.º 9
0
 def __init__(self, sk=None):
     '''
     If a secret key is not passed in then it will be generated
     '''
     if sk is None:
         self.pk, self.sk = libnacl.crypto_box_keypair()
     elif len(sk) == libnacl.crypto_box_SECRETKEYBYTES:
         self.sk = sk
         self.pk = libnacl.crypto_scalarmult_base(sk)
     else:
         raise ValueError('Passed in invalid secret key')
Ejemplo n.º 10
0
    def __init__(self, providerName, providerFingerprint, resolverAddress, resolverPort=443):
        self._providerName = providerName
        self._providerFingerprint = providerFingerprint.lower().replace(':', '').decode('hex')
        self._resolverAddress = resolverAddress
        self._resolverPort = resolverPort
        self._resolverCertificates = []
        self._publicKey, self._privateKey = libnacl.crypto_box_keypair()

        addrType = self._addrToSocketType(self._resolverAddress)
        self._sock = socket.socket(addrType, socket.SOCK_DGRAM)
        self._sock.connect((self._resolverAddress, self._resolverPort))
        self._sock.settimeout(2)
Ejemplo n.º 11
0
    def __init__(self, providerName, providerFingerprint, resolverAddress, resolverPort=443, timeout=2):
        self._providerName = providerName
        self._providerFingerprint = providerFingerprint.lower().replace(':', '').decode('hex')
        self._resolverAddress = resolverAddress
        self._resolverPort = resolverPort
        self._resolverCertificates = []
        self._publicKey, self._privateKey = libnacl.crypto_box_keypair()

        addrType = self._addrToSocketType(self._resolverAddress)
        self._sock = socket.socket(addrType, socket.SOCK_DGRAM)
        self._sock.settimeout(timeout)
        self._sock.connect((self._resolverAddress, self._resolverPort))
Ejemplo n.º 12
0
 def test_box(self):
     msg = b'Are you suggesting coconuts migrate?'
     # run 1
     nonce1 = libnacl.utils.rand_nonce()
     pk1, sk1 = libnacl.crypto_box_keypair()
     pk2, sk2 = libnacl.crypto_box_keypair()
     enc_msg = libnacl.crypto_box(msg, nonce1, pk2, sk1)
     self.assertNotEqual(msg, enc_msg)
     clear_msg = libnacl.crypto_box_open(enc_msg, nonce1, pk1, sk2)
     self.assertEqual(clear_msg, msg)
     # run 2
     nonce2 = libnacl.utils.rand_nonce()
     pk3, sk3 = libnacl.crypto_box_keypair()
     pk4, sk4 = libnacl.crypto_box_keypair()
     enc_msg2 = libnacl.crypto_box(msg, nonce2, pk4, sk3)
     self.assertNotEqual(msg, enc_msg2)
     clear_msg2 = libnacl.crypto_box_open(enc_msg2, nonce2, pk3, sk4)
     self.assertEqual(clear_msg2, msg)
     # Check bits
     self.assertNotEqual(nonce1, nonce2)
     self.assertNotEqual(enc_msg, enc_msg2)
Ejemplo n.º 13
0
            def test_rpc(self):
                c_pub, c_pk = libnacl.crypto_box_keypair()

                s_pub, s_pk = libnacl.crypto_box_keypair()

                cid2 = b'cid2' * 4

                #Servers identify clients by client id and key pairs.
                s = Server(pubkeys={cid2: c_pub},
                           ecc_keypair=(s_pub, s_pk),
                           openWANPort=6070)

                #Get one of our WAN addressess, and from there
                import pavillion.upnpwrapper
                wan_addr = pavillion.upnpwrapper.getWANAddresses()[0]

                c = Client(address=(wan_addr, 6070),
                           keypair=(c_pub, c_pk),
                           serverkey=s_pub,
                           clientID=cid2,
                           cipher=2)

                time.sleep(5)
                r = Register("test", "foooo")

                s.registers[400] = r

                #Using the "Direct function" method which doesn't have as much introspection capability
                s.registers[401] = lambda c, a: a

                x = c.call(400, b'A test string')

                self.assertEqual(x, b'A test string')

                x = c.call(401, b'A test string')

                self.assertEqual(x, b'A test string')
Ejemplo n.º 14
0
    def refreshKeys(self):
        """
        Refreshes keys as needed so valid set of keys
        """
        if not self.seed:  # no signing key seed so create new one
            self.seed = libnacl.randombytes(libnacl.crypto_sign_SEEDBYTES)

        if not self.sigkey or not self.verkey:  # ensure also sigkey and verkey
            self.verkey, self.sigkey = libnacl.crypto_sign_seed_keypair(
                self.seed)

        if not self.prikey:  # no private encryption key so create new pair
            self.pubkey, self.prikey = libnacl.crypto_box_keypair()

        if not self.pubkey:  # no public decryption key so create one from prikey
            self.pubkey = libnacl.crypto_scalarmult_base(self.prikey)
Ejemplo n.º 15
0
    def generateKeypair(self):
        keypair = libnacl.crypto_box_keypair()

        self.publicKey = keypair[0]
        self.secretKey = keypair[1]
Ejemplo n.º 16
0
 def generate_keypair(cls):
     return KeyPair(*libnacl.crypto_box_keypair())
Ejemplo n.º 17
0
    def __init__(self, address:Tuple[str,int]=('255.255.255.255',DEFAULT_PORT),clientID=None,psk=None,cipher=1,server=None,keypair=None, serverkey=None, handle=None,daemon=None):
        "Represents a Pavillion client that can both initiate and respond to requests"
        
        if daemon is None:
            daemon=pavillion.daemon

   
        #Last time we were known to be connected
        #We're trying to pretend to be connectionless, so
        #this is really just a guess of if there's at least one
        #server connected
        self.connectedAt =0

        #The address of our associated server
        self.server_address = address

        #The default timeout.
        self.timeout = 2

        #Used for optimizing the response timing
        self.fastestOverallCallResponse = 0.05

        #Average response time for each type of call we know about
        #Listed by the RPC number
        self.averageResponseTimes = {}
        self.stdDevResponseTimes = {}

        #Used to keeo track of the optimization where some broadcasts are converted to unicasts.
        #We occasionally send real broadcasts for new server discovery.
        self.lastActualBroadcast = 0

        #Our message counter
        self.counter = random.randint(1024,1000000000)
        self.server_counter = 0

        self.cipher= ciphers[cipher]

        self.keypair = keypair
        self.server_pubkey = serverkey

        #Clients can be associated with a server
        self.server = server

        psk = preprocessKey(psk)
        self.psk = psk
        self.clientID = clientID

        self.lastChangedChallenge = time.time()
        self.challengelock = threading.Lock()
        self.targetslock = threading.Lock()
        self.lock = threading.Lock()
        self.nonce = os.urandom(32)
        self.challenge = os.urandom(16)
        self.usedServerNonces = {}

        #Conceptually, there is exactly one server, but in the case of multicast there's
        #multiple machines even if they all have the same key.
        self.max_servers = 128

        #Known servers, indexed by (addr,port)
        self.known_servers = {}

        #Last sent message that was sent to the default address
        self._keepalive_time = time.time()

        self.skey = None
        self.messageTargets = {}

        if self.keypair == "guest":
            self.keypair = libnacl.crypto_box_keypair()

        
        if self.psk:
            self.key = self.cipher.keyedhash(self.nonce,psk)
            self.sessionID = os.urandom(16)


        
        elif  self.keypair:
            self.key = os.urandom(32)
            self.sessionID = os.urandom(16)
        else:
            self.key= None
            self.sessionID = os.urandom(16)


        if not self.clientID:
            if self.keypair:
                self.clientID = libnacl.crypto_generichash(self.keypair[0])[:16]

        
        

        self_address = ('', 0)

        self.lock=threading.Lock()

        # Create the socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
        # Bind to the server address
        self.sock.bind(self_address)
        self.sock.settimeout(1)


        if is_multicast(address[0]):
            # Create the socket
            self.msock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            self.msock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)  
            self.msock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
            self.msock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 
            # Bind to the server address
            self.msock.bind((self_address[0],self.server_address[1]))
            self.msock.settimeout(1)
            group = socket.inet_aton(address[0])
            mreq = struct.pack('4sL', group, socket.INADDR_ANY)
            self.msock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
        else:
            self.msock = False

        
        self.running = True

        def cl(*args):
            self.close()
        self.clfun = cl
        #If we have a handle, make it so that if the handle gets collected the server thread stops
        if handle:
            self.handle = weakref.ref(handle,cl)

        #lastseen time  dicts indexed by the name of what you are subscribing to, then indexed by subscriber IP
        #This is a list of *other* machines that are subscribing. 
        # A "subscription" can be implicit, a response to a multicast packet.
        #Or it can be an explicit subscribe message
        #If we get less responses than usual, we know we should retry.
        self.knownSubscribers = {}

        self.subslock = threading.Lock()
        self.waitingForAck = weakref.WeakValueDictionary()
        self.backoff_until = time.time()


        t = threading.Thread(target=self.loop)
        t.daemon = daemon
        t.name+=":PavillionClient"

        t.start()


        self._kathread = threading.Thread(target=self._keepAliveLoop)
        self._kathread.daemon = True
        self._kathread.name+=":PavillionClientKeepalive"
        self._kathread.start()

        #Attempt to connect. The protocol has reconnection built in,
        #But this lets us connect in advance
        if self.psk and self.clientID:
            pass
            self.sendNonceRequest()
        elif self.keypair:
            self.sendNonceRequest()
            pass

        else:
            self.synced = False
            counter = 8
            while not self.synced and counter:
                self.sendSetup(0, 1, struct.pack("<B",self.cipher.id)+self.clientID+self.challenge)
                time.sleep(0.05)
                counter-=1