## Test GET pubkey
pubkey_response = requests.get(notary_url+'/api/v1/pubkey', verify=False)
data = pubkey_response.json()
other_party_public_key_hex = data['public_key']
print data['public_key']
other_party_public_key_decoded = other_party_public_key_hex.decode("hex")
other_party_public_key = CPubKey(other_party_public_key_decoded)
other_party_address = P2PKHBitcoinAddress.from_pubkey(other_party_public_key)
address = str(wallet.get_bitcoin_address())

## Test GET challenge

response = requests.get(notary_url+'/api/v1/challenge/' + address, verify=False)
payload = json.loads(response.content)
if secure_message.verify_secure_payload(other_party_address, payload):
    message = secure_message.get_message_from_secure_payload(payload)
    print(message)

payload = secure_message.create_secure_payload(other_party_public_key_hex, message)
response = requests.put(notary_url+'/api/v1/challenge/' + address, data=payload, verify=False)
cookies = requests.utils.dict_from_cookiejar(response.cookies)

metadata = {
    'title': 'Stillwater Shame',
    'creator': 'Ploughman, J.J.',
    'subject': 'Rock Music',
    'description': 'A song about lying politicians',
    'publisher': 'J.J. Ploughman',
    'contributor': 'J.J. Ploughman',
    'date': '2001-08-03T03:00:00.000000',
    'type': 'Music',
## Test GET pubkey
pubkey_response = requests.get(notary_url+'/api/v1/pubkey', verify=False)
data = pubkey_response.json()
other_party_public_key_hex = data['public_key']
print data['public_key']
other_party_public_key_decoded = other_party_public_key_hex.decode("hex")
other_party_public_key = CPubKey(other_party_public_key_decoded)
other_party_address = P2PKHBitcoinAddress.from_pubkey(other_party_public_key)
address = str(wallet.get_bitcoin_address())

## Test GET challenge

response = requests.get(notary_url+'/api/v1/challenge/' + address, verify=False)
payload = json.loads(response.content)
if secure_message.verify_secure_payload(other_party_address, payload):
    message = secure_message.get_message_from_secure_payload(payload)
    print(message)

payload = secure_message.create_secure_payload(other_party_public_key_hex, message)
response = requests.put(notary_url+'/api/v1/challenge/' + address, data=payload, verify=False)
cookies = requests.utils.dict_from_cookiejar(response.cookies)

document_hash = hashfile.hash_file(test_data.notary_file_name)

response = requests.get(notary_url+'/api/v1/account/' + address + '/document/' + document_hash + '/status', cookies=cookies, verify=False)
if response.content is not None:
    if response.status_code == 404:
        print ("Document not found!")
    elif response.status_code == 200:
        str_content = response.content
        payload = json.loads(response.content)
Esempio n. 3
0
class Notary(object):
    def __init__(self, config_file, password):
        '''
           constructs needed objects
        Parameters
        ----------
        password  : takes the password of the wallet

        Returns
        -------

        '''

        self.config = NotaryConfiguration(config_file)
        self.logger = log_handlers.get_logger(self.config)
        self.ssl_verify_mode = self.config.get_ssl_verify_mode()
        self.wallet = wallet.create_wallet(self.config.get_wallet_type(), password, self.logger)
        self.secure_message = SecureMessage(self.wallet)
        self.notary_server = NotaryServer(self.config)
        self.address = str(self.wallet.get_bitcoin_address())

    def get_payload(self, message):
        str_message = json.dumps(message)
        return self.secure_message.create_secure_payload(self.notary_server.get_public_key_hex(), str_message)

    def authenticate(self):
        challenge_url = self.notary_server.get_challenge_url(self.address)
        response = requests.get(challenge_url, verify=self.ssl_verify_mode)
        if response.status_code != 200:
            return None
        payload = json.loads(response.content)
        if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
            message = self.secure_message.get_message_from_secure_payload(payload)
            payload = self.secure_message.create_secure_payload(self.notary_server.get_public_key_hex(), message)
            response = requests.put(challenge_url, data=payload, verify=self.ssl_verify_mode)
            if response.status_code != 200:
                return None
            return requests.utils.dict_from_cookiejar(response.cookies)

    def register_user(self, email):
        '''
           first step in registering an user to our system.
        Parameters
        ----------
        email   : the email address of the user.

        Returns
        -------
              the http response status code.
        '''
        # prepare the input.

        payload = self.get_payload({'public_key': self.wallet.get_public_key_hex(), 'email': email})

        # send to server
        response = requests.put(self.notary_server.get_account_url(self.address), data=payload,
                                verify=self.ssl_verify_mode)

        return response.status_code

    def register_user_status(self):
        '''
           This method returns the registration status.
        Parameters
        ----------
        email   : the email address of the user.

        Returns
        -------
              the http response status code.
        '''


        # send to server
        # Have to authenticate
        cookies = self.authenticate()
        if cookies is None:
            return None
        response = requests.get(self.notary_server.get_account_url(self.address),cookies=cookies,
                                verify=self.ssl_verify_mode)
        if response.status_code == 200:
            payload = json.loads(response.content)
            if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                message = self.secure_message.get_message_from_secure_payload(payload)
                return json.loads(message)

        return response.status_code

    def notarize_file(self, path_to_file, metadata):
        '''
        the main method to notarize a file.
        Parameters
        ----------
        path_to_file   : the fp to the file. ( Not file name). Need to support file name.
        metadata  : a JSON object containing metadata

        Returns
        -------
           returns the transaction hash and document hash.

        '''

        # hash the file and generate the document hashh
        if type(path_to_file) is str:
            document_hash = hashfile.hash_file(path_to_file)
        else:
            document_hash = hashfile.hash_file_fp(path_to_file)
        metadata['document_hash'] = document_hash
        # create a secure payload
        notarization_payload = self.get_payload(metadata)
        # Have to authenticate
        cookies = self.authenticate()
        if cookies is not None:
            response = requests.put(self.notary_server.get_notarization_url(self.address, document_hash),
                                    cookies=cookies, data=notarization_payload, verify=self.ssl_verify_mode)
            if response.status_code == 200:
                payload = json.loads(response.content)
                if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                    message = self.secure_message.get_message_from_secure_payload(payload)
                    return json.loads(message)

        return None

    def upload_file(self, path_to_file, encrypted=False):
        '''
        uploads a file to server
        Parameters
        ----------
        path_to_file : give a file pointer,i.e. file pointer. Need change code support file full path name.

        Returns
        -------
         the http status from the server

        '''
        if encrypted:
            reg_status = self.register_user_status()
            private_key_hex = str(reg_status['file_encryption_key'])
            private_key_wif = base58.base58_check_encode(0x80, private_key_hex.decode("hex"))
            private_key = CBitcoinSecret(private_key_wif)
            public_key = private_key.pub

        if type(path_to_file) is str:
            document_hash = hashfile.hash_file(path_to_file)
        else:
            document_hash = hashfile.hash_file_fp(path_to_file)

        cookies = self.authenticate()
        if cookies is not None:
            check_notarized = requests.get(self.notary_server.get_notarization_status_url(self.address, document_hash),
                                           cookies=cookies, verify=False)
            if check_notarized is not None:
                if check_notarized.status_code == 404:
                    return None
                elif check_notarized.status_code == 200:
                    try:
                        cookies = requests.utils.dict_from_cookiejar(check_notarized.cookies)
                        if encrypted:
                            file_stream_encrypt.encrypt_file(path_to_file,path_to_file+".encrypted", public_key)
                            files = {'document_content': open(path_to_file+".encrypted", 'rb')}
                        else:
                            files = {'document_content': open(path_to_file, 'rb')}
                        upload_response = requests.put(
                                self.notary_server.get_upload_url(self.address, document_hash), cookies=cookies,
                                files=files, verify=False)
                        return upload_response.status_code
                    except requests.ConnectionError as e:
                        print (e.message)
        return None

    def download_file(self, document_hash, storing_file_name, encrypted=False):
        if encrypted:
            reg_status = self.register_user_status()
            private_key_hex = str(reg_status['file_encryption_key'])
            private_key_wif = base58.base58_check_encode(0x80, private_key_hex.decode("hex"))
            private_key = CBitcoinSecret(private_key_wif)
            public_key = private_key.pub

        cookies = self.authenticate()
        if cookies is not None:
            download_response = requests.get(self.notary_server.get_upload_url(self.address, document_hash),
                                             cookies=cookies, allow_redirects=True, verify=False)
            if download_response.status_code == 200:
                # Need to add error handling
                ultimate_file_name = str(storing_file_name)
                if encrypted:
                    ultimate_file_name = storing_file_name+".download_encrypted"
                with open(ultimate_file_name, 'wb') as f:
                    for chunk in download_response.iter_content(chunk_size=1024):
                        if chunk:  # filter out keep-alive new chunks
                            f.write(chunk)
                if encrypted:
                    file_stream_encrypt.decrypt_file(storing_file_name+".download_encrypted",  storing_file_name, private_key_wif)
                return storing_file_name
        return None

    def notary_status(self, document_hash):
        '''
        This method returns the notary status
        Parameters
        ----------
        document_hash : the document hash value.

        Returns
        -------
             status value.
        '''
        cookies = self.authenticate()
        if cookies is not None:
            response = requests.get(self.notary_server.get_notarization_status_url(self.address, document_hash),
                                    cookies=cookies, verify=False)
            if response.status_code == 404:
                print ('No notarization!')
            elif response.content is not None:
                payload = json.loads(response.content)
                if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                    message = self.secure_message.get_message_from_secure_payload(payload)
                    return message
        return None
Esempio n. 4
0
class NotaryClient(object):
    def __init__(self, config_file, password):
        """
           constructs needed objects
        Parameters
        ----------
        password  : takes the password of the wallet

        Returns
        -------

        """

        self.config = NotaryConfiguration(config_file)
        self.logger = log_handlers.get_logger(self.config)
        self.ssl_verify_mode = self.config.get_ssl_verify_mode()
        self.wallet = wallet.create_wallet(self.config.get_wallet_type(), password, self.logger)
        self.secure_message = SecureMessage(self.wallet)
        self.notary_server = NotaryServer(self.config)
        self.address = str(self.wallet.get_bitcoin_address())

    def get_server_pubkey(self):
        return self.notary_server.get_public_key_hex()

    def get_payload(self, message):
        str_message = json.dumps(message)
        return self.secure_message.create_secure_payload(self.notary_server.get_public_key_hex(), str_message)

    def authenticate(self):
        challenge_url = self.notary_server.get_challenge_url(self.address)
        response = requests.get(challenge_url, verify=self.ssl_verify_mode)
        if response.status_code != 200:
            raise NotaryException(response.status_code, "Error getting authentication challenge!")
        payload = json.loads(response.content)
        if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
            message = self.secure_message.get_message_from_secure_payload(payload)
            payload = self.secure_message.create_secure_payload(self.notary_server.get_public_key_hex(), message)
            response = requests.put(challenge_url, data=payload, verify=self.ssl_verify_mode)
            if response.status_code != 200:
                raise NotaryException(response.status_code, "Error authenticating!")
            return requests.utils.dict_from_cookiejar(response.cookies)
        raise NotaryException(-1, "Error Verifying signature!")

    def register_user(self, email):
        """
           first step in registering an user to our system.
        Parameters
        ----------
        email   : the email address of the user.

        Returns
        -------
              the http response status code.
        """
        # prepare the input.

        payload = self.get_payload({"public_key": self.wallet.get_public_key_hex(), "email": email})

        # send to server
        response = requests.put(
            self.notary_server.get_account_url(self.address), data=payload, verify=self.ssl_verify_mode
        )
        if response.status_code != 200:
            raise NotaryException(response.status_code, "Error registering!")
        return response.status_code

    def get_file_encryption_wallet(self):
        try:
            account = self.get_account()
            file_encryption_wallet = wallet.create_wallet("MemoryWallet", account["file_encryption_key"], self.logger)
            return file_encryption_wallet
        except NotaryException as e:
            raise NotaryException(e.error_code, "Error getting file encryption key!")

    def get_account(self):
        """
        This method tells us many things:

        1. If a user has never been registered, then an exception with an error code of 404 will be raised
        2. If a user has registered but hasn't confirmed, then an exception with an error code of 403 will be raised
        3. If a user is registered and confirmed, account data will be returned. That data contains a file_encryption_key.

        Returns
        -------
              the account
        """
        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        response = requests.get(
            self.notary_server.get_account_url(self.address), cookies=cookies, verify=self.ssl_verify_mode
        )
        registration_status = response.status_code
        if registration_status == 200:
            payload = json.loads(response.content)
            if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                message = self.secure_message.get_message_from_secure_payload(payload)
                return json.loads(message)
        raise NotaryException(registration_status, "Error Verifying signature!")

    def notarize_file(self, path_to_file, metadata):
        """
        the main method to notarize a file.
        Parameters
        ----------
        path_to_file   : the fp to the file. ( Not file name). Need to support file name.
        metadata  : a JSON object containing metadata

        Returns
        -------
           returns the transaction hash and document hash.

        """

        # hash the file and generate the document hashh

        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        document_hash = hashfile.hash_file(path_to_file)

        metadata["document_hash"] = document_hash
        # create a secure payload
        notarization_payload = self.get_payload(metadata)
        # Have to authenticate
        response = requests.put(
            self.notary_server.get_notarization_url(self.address, document_hash),
            cookies=cookies,
            data=notarization_payload,
            verify=self.ssl_verify_mode,
        )
        if response.status_code == 200:
            payload = json.loads(response.content)
            if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                message = self.secure_message.get_message_from_secure_payload(payload)
                return json.loads(message)
        else:
            raise NotaryException(response.status_code, "Error notarizing!")

    def upload_file_encrypted(self, path_to_file):
        """
        uploads a file to server encrypting along the way
        Parameters
        ----------
        path_to_file :  file full path name.

        Returns
        -------
         the http status from the server

        """
        try:
            file_encryption_wallet = self.get_file_encryption_wallet()
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        document_hash = hashfile.hash_file(path_to_file)

        try:
            file_stream_encrypt.encrypt_file(
                path_to_file, path_to_file + ".encrypted", file_encryption_wallet.get_public_key()
            )
            files = {"document_content": open(path_to_file + ".encrypted", "rb")}
            upload_response = requests.put(
                self.notary_server.get_document_url(self.address, document_hash),
                cookies=cookies,
                files=files,
                verify=False,
            )
            return upload_response.status_code
        except requests.ConnectionError as e:
            raise NotaryException(upload_response.status_code, "Problem uploading file!")

    def upload_file(self, path_to_file):
        """
        uploads a file to server
        Parameters
        ----------
        path_to_file : file full path name.

        Returns
        -------
         the http status from the server

        """

        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        document_hash = hashfile.hash_file(path_to_file)

        try:
            files = {"document_content": open(path_to_file, "rb")}
            upload_response = requests.put(
                self.notary_server.get_document_url(self.address, document_hash),
                cookies=cookies,
                files=files,
                verify=False,
            )
            if upload_response.status_code != 200:
                raise NotaryException(upload_response.status_code, "Problem uploading file!")
            return upload_response.status_code
        except requests.ConnectionError as e:
            raise NotaryException(-1, e.message)
        except NotaryException as ne:
            raise NotaryException(ne.error_code, ne.message)

    def download_file(self, document_hash, storing_file_name):
        """
        uploads a file to server
        Parameters
        ----------
        document_hash : hash of file.
        storing_file_name : file name to write to.

        Returns
        -------
         storing_file_name

        """

        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        try:
            download_response = requests.get(
                self.notary_server.get_document_url(self.address, document_hash),
                cookies=cookies,
                allow_redirects=True,
                verify=False,
            )
            if download_response.status_code != 200:
                raise NotaryException(download_response.status_code, "Problem downloading file!")
                # Need to add error handling
            ultimate_file_name = str(storing_file_name)
            with open(ultimate_file_name, "wb") as f:
                for chunk in download_response.iter_content(chunk_size=1024):
                    if chunk:  # filter out keep-alive new chunks
                        f.write(chunk)
            return storing_file_name
        except requests.ConnectionError as e:
            raise NotaryException(-1, e.message)
        except NotaryException as ne:
            raise NotaryException(ne.error_code, ne.message)

    def download_file_decrypted(self, document_hash, storing_file_name):
        """
        uploads a file to server
        Parameters
        ----------
        document_hash : hash of file.
        storing_file_name : file name to write to.

        Returns
        -------
         storing_file_name

        """

        try:
            file_encryption_wallet = self.get_file_encryption_wallet()
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        try:
            download_response = requests.get(
                self.notary_server.get_document_url(self.address, document_hash),
                cookies=cookies,
                allow_redirects=True,
                verify=False,
            )
            if download_response.status_code != 200:
                raise NotaryException(download_response.status_code, "Problem downloading file!")
                # Need to add error handling
            ultimate_file_name = str(storing_file_name)
            with open(ultimate_file_name + ".decrypted", "wb") as f:
                for chunk in download_response.iter_content(chunk_size=1024):
                    if chunk:  # filter out keep-alive new chunks
                        f.write(chunk)

            file_stream_encrypt.decrypt_file(
                ultimate_file_name + ".decrypted", storing_file_name, file_encryption_wallet.get_private_key_wif()
            )
            return storing_file_name
        except requests.ConnectionError as e:
            raise NotaryException(-1, e.message)
        except NotaryException as ne:
            raise NotaryException(ne.error_code, ne.message)

    def get_notarization_status(self, document_hash):
        """
        This method returns the notary status
        Parameters
        ----------
        document_hash : the document hash value.

        Returns
        -------
             status value.
        """
        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        response = requests.get(
            self.notary_server.get_notarization_status_url(self.address, document_hash), cookies=cookies, verify=False
        )
        if response.status_code != 200 or response.content is None:
            raise NotaryException(response.status_code, "Error retrieving notarization status")
        else:
            payload = json.loads(response.content)
            if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                message = self.secure_message.get_message_from_secure_payload(payload)
                return json.loads(message)

    def get_notarizations(self):
        """

        Returns
        -------
              the account
        """
        try:
            cookies = self.authenticate()
        except NotaryException as e:
            raise NotaryException(e.error_code, e.message)

        response = requests.get(
            self.notary_server.get_notarizations_url(self.address), cookies=cookies, verify=self.ssl_verify_mode
        )
        if response.status_code == 200:
            payload = json.loads(response.content)
            if self.secure_message.verify_secure_payload(self.notary_server.get_address(), payload):
                message = self.secure_message.get_message_from_secure_payload(payload)
                return json.loads(message)
        else:
            raise NotaryException(response.status_code, "Error getting notarizations!")