コード例 #1
0
def challenge():

    #create host object
    host = Host()

    #Create a hash of the node's public key to send to the auth node for identity verification
    keyhash = str(
        base64.b64encode(
            hashlib.sha256(
                rsa_encrypt.get_pub_key().exportKey("PEM")).digest()), 'ascii')

    #creates a payload of the message that identifies that this is a client node that needs to be updated
    payload = "imup" + ":" + str(
        comms_number) + ":" + keyhash + ":" + settings.ID

    #create a socket to communicate with the auth nodes
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                       socket.IPPROTO_UDP) as s:
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

        #Create an empty data and address variable and a socket to recieve the data
        data = ""
        addr = 0
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as us:

            #set a timeout for if there is no auth node ready
            us.settimeout(1)
            us.bind(('0.0.0.0', 55551))

            #send the challenge tag to the auth nodes along with a public key to encrypt their return message with
            s.sendto(
                aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                  "who?:" + keyhash), ((host.host, host.port)))

            #Recv a number from the auth node to connect to
            try:
                data, addr = us.recvfrom(4096)
            #if it fails return an error
            except socket.timeout:
                us.close()
                return -1

        #Decrypt the recieved message
        data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), data)

        #if message is bad return error
        if data == -1 or data == -2:
            return -1

        #convert data to a string to return to the auth nodes along with the instruction payload
        data = str(data, 'ascii')

        #send payload and return expected address
        s.sendto(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                              "you!:" + data + ":" + payload),
            ((host.host, host.port)))
        return addr
コード例 #2
0
def register():

    #Create socket to recieve updates from
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(5)
        s.bind(("0.0.0.0", 55550))
        s.listen(5)

        #make sure that challenge executes correctly, else return error
        print("Looking for Auth Node")
        address = challenge()
        if address == -1:
            return -1

        #Create a connection with the auth node, if it is not the
        #expected address than continue waiting
        try:
            cli, addr = s.accept()
            while not addr[0] == address[0]:
                cli, addr = s.accept()
        except socket.timeout:
            return -1

        #Report
        print("Recieving Updates Now")

        #Recieve two sums for challenge response authentication
        #One for the database and one for the public key
        sums = cli.recv(2048).split(b"::")

        #Decrypt the sums using the node and db public keys
        sums[0] = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), sums[0])
        sums[1] = aes_crypt.aes_dec(rsa_encrypt.get_priv_key_db(settings.ID),
                                    sums[1])

        #if there is an error in the communication of the sums return an error
        if sums[0] == -1 or sums[0] == -2 or sums[1] == -1 or sums[1] == -2:
            return 1

        #Increment the sums and return them via the auth public key
        sum1 = str(int(sums[0]) + 1)
        sum2 = str(int(sums[1]) + 1)

        #send the incremented sums back to proove node identity
        payload = aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(),
                                    sum1 + ":" + sum2)
        #Fill recv buffer
        cli.send(payload + b"\x00" * (4096 - len(payload)))

        #Grab the latest timestamp
        timestamps = grab_timestamps()

        #Send the timestamp encrypted with the auth public key
        cli.send(
            aes_crypt.aes_enc(rsa_encrypt.get_pub_key_auth(), str(timestamps)))

        #Run the update process
        num_updates = shamir_updater.update(cli)

        #make number presentable
        if num_updates == -1:
            num_updates = 0

        #Report shares
        print("Registered: " + str(num_updates) + " updates")

        #clean up and exit
        cli.close()
    return
コード例 #3
0
def update(cli):

    #open connection to local database
    conn = sqlite3.connect(settings.DBdir + settings.ID + ".db")
    conn.row_factory = sqlite3.Row
    conn.cursor().execute("CREATE TABLE IF NOT EXISTS shares(id PRIMARY KEY, x, y, key, timestamp DOUBLE)")
    conn.commit()

    #Create empty data string
    data = b""

    #Recieve until done
    try:
        while 1==1:
            temp = cli.recv(4096)
            if temp:
                data += temp
            else:
                break
    
    #if the connection dies
    except:
        #Return no updates
        return 0        
    
    #close the socket
    cli.close()
    
    #get encrypted list of encrypted shares
    #ENCRYPTED_MESSAGE(ENCRYPTED_SHARES)
    #The shares are encrypted to prevent the auth node from having all knowledge
    data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), data)
    
    #If the data is invalid return an error
    if data == -1 or data == -2:
        return -1

    #Convert data to a list
    data = str(data, 'ascii').split(":")
    
    #if no data then return
    if data == ['']:
        return 

    #For each share
    for i in data:

        #Split the share into its content and timestamp
        d = i.split("|")

        #If user is marked for deletion
        if d[0] == "DEL":

            #Delete the share and commit the action
            conn.cursor().execute("DELETE FROM shares WHERE id = ?", [d[1]])
            conn.commit()
            continue

        #decrypt the share and concatenate it with the timestamp
        temp = rsa_encrypt.get_priv_key_db(settings.ID).decrypt((base64.b64decode(d[0]),)) + b':' + bytes(d[1], 'ascii')
        
        #Pass the share into the database
        update_db(temp, conn)

    #close the connection and return the number of shares commited
    conn.close()
    return(len(data))
コード例 #4
0
def update(cli):

    #open connection to local database
    conn = sqlite3.connect(settings.DBdir + settings.ID + ".db")
    conn.row_factory = sqlite3.Row
    conn.cursor().execute(
        "CREATE TABLE IF NOT EXISTS shares(id PRIMARY KEY, x, y, key, timestamp DOUBLE)"
    )
    conn.commit()

    #Create empty data string
    data = b""

    #Recieve until done
    try:
        while 1 == 1:
            temp = cli.recv(4096)
            if temp and len(temp) == 4096:
                data += temp
            else:
                break
        data += temp

    #if the connection dies
    except:
        #Return no updates
        return 0

    #close the socket
    cli.close()

    #get encrypted list of encrypted shares
    #ENCRYPTED_MESSAGE(ENCRYPTED_SHARES)
    #The shares are encrypted to prevent the auth node from having all knowledge
    data = aes_crypt.aes_dec(rsa_encrypt.get_priv_key(), data)

    #If the data is invalid return an error
    if data == -1 or data == -2:
        print("Error in transmission, updates will be applied shortly")
        return -1

    #Convert data to a list
    data = str(data, 'ascii').split(":")

    #if no data then return
    if data == ['']:
        return

    #record number of updates
    num_updates = len(data)

    #For each share
    for i in data:

        #Split the share into its content and timestamp
        d = i.split("|")

        #If user is marked for deletion
        if d[0] == "DEL":
            new = delete_user(conn, d)
            if not new:
                num_updates -= 1
            continue

        #if data is longer than 344 then it means the data was chunked then concatenated together
        #need to decrypt each chunk individually
        if len(d[0]) > 344:
            msg = b''
            curr_len = len(d[0])
            start = 0
            end = 344
            while curr_len > 0:

                # subtract 344 on each iteration
                curr_len -= 344

                # decrypt a single chunk, the starting and ending index are specified by start and end
                dec_chunk = rsa_encrypt.get_priv_key_db(settings.ID).decrypt(
                    (base64.b64decode(d[0][start:end]), ))

                # append the single chunk to the full message
                msg += dec_chunk

                # increment start and end to the next chunk
                start += 344
                end += 344

            # append the timestamp to the entire message
            msg += b':' + bytes(d[1], 'ascii')

            #Pass the share into the database
            update_db(msg, conn)

        # if the data was not chunked then pass the entire string
        else:

            #decrypt the share and concatenate it with the timestamp
            temp = rsa_encrypt.get_priv_key_db(settings.ID).decrypt(
                (base64.b64decode(d[0]), )) + b':' + bytes(d[1], 'ascii')

            #Pass the share into the database
            update_db(temp, conn)

    #close the connection and return the number of shares commited
    conn.close()
    return num_updates