예제 #1
0
def gen_account_key(account_id=None):
    """
    Generate key for account ID

    :param account_id:
    :return: Key ID for created key
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    account_kid = "acc-kid-" + str(uuid4())
    logger.debug('Generated account_kid: ' + str(account_kid))

    try:
        account_key = gen_key_as_jwk(account_kid=account_kid)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Failed to generate key for account')
        logger.error('Failed to generate key for account: ' + repr(exp))
        raise

    try:
        store_jwk(account_id=account_id, account_kid=account_kid, account_key=account_key)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Failed to store generated key. Key must be regenerated.')
        logger.error('Failed to store generated key: ' + repr(exp))
        raise
    else:
        logger.info('For account with id: ' + str(account_id) + ' has been generated JWK with kid: ' + str(account_kid))
        return account_kid
예제 #2
0
def jwk_json_to_object(jwk_json=None):
    """
    Converts JWK json presentation to JWK object

    :param jwk_json:
    :return: JWK object
    """
    if jwk_json is None:
        raise AttributeError("Provide jwk_json as parameter")
    else:
        logger.debug("As parameter jwk_json: " +
                     repr(jwk_json).replace('u\'', '\''))

    try:
        jwk_dict = json.loads(jwk_json)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWK json to dict')
        logger.error('Could not convert JWK json to JWK dict: ' + repr(exp))
        raise
    else:
        logger.debug("jwk_json: " + repr(jwk_json))
        logger.info("JWK json converted to JWK dict")

    try:
        jwk_object = jwk.JWK(**jwk_dict)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWK json to JWK object')
        logger.error('Could not convert JWK json to JWK object: ' + repr(exp))
        raise
    else:
        logger.debug('JWK json converted to JWK object')
        logger.debug('jwk_object: ' + repr(jwk_object.__dict__))
        return jwk_object
예제 #3
0
def clear_blackbox_sqlite_db():
    """
    Initializes SQLite database.

    :param connection: Database connection object
    :return: Database connection object
    """
    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get database connection')
        logger.error('get_sqlite_connection: ' + repr(exp))
        raise

    sql_query = '''DELETE FROM account_keys WHERE account_id > 3;'''

    try:
        logger.info('Clearing database')
        logger.debug('Executing: ' + str(sql_query))
        connection.execute(sql_query)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not clear database')
        logger.error('connection.execute(sql): ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.commit()
        connection.close()
        logger.info('Database cleared')
        return True
예제 #4
0
def jws_object_to_json(jws_object=None):
    """
    Converts JWS object to JWS JSON presentation
    - http://jwcrypto.readthedocs.io/en/stable/jws.html

    :param jws_object: JSON object
    :return: JSON presentation of JWS object
    """
    if jws_object is None:
        raise AttributeError("Provide jws_object as parameter")
    else:
        logger.debug("As parameter jws_object: " + repr(jws_object.__dict__).replace('u\'', '\''))

    try:
        jws_json = jws_object.serialize(compact=False)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not convert JWS object to JWS json')
        logger.error('Could not convert JWS object to JWS json: ' + repr(exp))
        raise
    else:
        logger.debug('jws_json: ' + str(jws_json))
        logger.info('JWS object converted to JWS json')

    try:
        jws_json_fixed = jws_header_fix(malformed_jws_json=jws_json)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not fix header in JWS json')
        logger.error('Could not fix header in JWS json: ' + repr(exp))
        raise
    else:
        logger.debug('jws_json_fixed: ' + str(jws_json_fixed))
        logger.info('Header fixed in JWS json')
        return jws_json_fixed
예제 #5
0
def get_key_by_account_id(account_id=None, cursor=None):
    """
    Gets Key by user account ID

    :param account_id: ID of user account
    :param cursor: Database cursor
    :return: Database cursor, JSON presentation of Key and Key ID
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")
    if cursor is None:
        raise AttributeError("Provide cursor as parameter")

    try:
        cursor, jwk_object, kid = get_key(account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get JWK object')
        logger.error('Could not get JWK object: ' + repr(exp))
        raise

    try:
        jwk_json = jwk_object_to_json(jwk_object=jwk_object)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not export key from JWK object')
        logger.error('Could not export key from JWK object: ' + repr(exp))
        raise
    else:
        logger.debug('kid: ' + str(kid))
        logger.debug('jwk_object_public: ' + repr(jwk_object))
        return cursor, jwk_json, kid
예제 #6
0
def execute_sql_select(cursor=None, sql_query=None):
    """
    Executes SQL SELECT queries.

    :param cursor: Database cursor
    :param sql_query: SQl query to execute
    :return: Database cursor and result of database query
    """

    if cursor is None:
        raise AttributeError("Provide cursor as parameter")
    if sql_query is None:
        raise AttributeError("Provide sql_query as parameter")

    try:
        cursor.execute(sql_query)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Error in SQL SELECT query execution')
        logger.error('Error in SQL query execution: ' + repr(exp))
        raise
    else:
        logger.debug('SQL query executed')

    try:
        data = cursor.fetchall()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='cursor.fetchall() failed')
        logger.error('cursor.fetchall() failed: ' + repr(exp))
        raise
    else:
        logger.debug('Data fetched')

    return cursor, data
예제 #7
0
def get_key(account_id=None, cursor=None):
    """
    Fetches JSON presentation of JWK object from database and converts JSON presentation to JWK object.

    :param account_id: ID of user account
    :param cursor: Database cursor
    :return: Database cursot, JWK Object and Key ID
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")
    if cursor is None:
        raise AttributeError("Provide cursor as parameter")

    jwk_dict = {}

    sql_query = "SELECT id, kid, account_id, jwk FROM account_keys WHERE account_id='%s' ORDER BY id DESC LIMIT 1" % (
        account_id)

    try:
        cursor, data = execute_sql_select(sql_query=sql_query, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not fetch key from database')
        logger.error('Could not fetch key from database: ' + repr(exp))
        logger.debug('sql_query: ' + repr(sql_query))
        raise
    else:
        logger.debug("JWK json fetched from database")

        try:
            jwk_dict['id'] = data[0][0]
            jwk_dict['kid'] = data[0][1]
            jwk_dict['account_id'] = data[0][2]
            jwk_dict['jwk_key'] = data[0][3]
        except Exception as exp:
            exp = append_description_to_exception(
                exp=exp,
                description='Could not move database response to new dict')
            logger.error('Key for account not found from database: ' +
                         repr(exp))
            raise KeyNotFoundError("Key for account not found from database")

        log_dict_as_json(data=jwk_dict, pretty=0)
        try:
            jwk_object = jwk_json_to_object(jwk_json=jwk_dict['jwk_key'])
        except Exception as exp:
            exp = append_description_to_exception(
                exp=exp,
                description='Could not convert JWK json to JWK object')
            logger.error('Could not convert JWK json to JWK object: ' +
                         repr(exp))
            raise
        else:
            logger.debug('jwk_object: ' + str(jwk_object.__dict__))
            logger.debug('kid: ' + str(jwk_dict['kid']))
            return cursor, jwk_object, jwk_dict['kid']
예제 #8
0
def jws_sign(account_id=None, account_kid=None, jws_object=None, jwk_object=None, jwk_public_json=None, alg="ES256"):
    """
    Signs JWS with JWK.

    :param account_id: User account ID
    :param account_kid: Key ID for user's key
    :param jws_object: JWS object
    :param jwk_object: JWK object
    :param jwk_public_json: JSON presentation of public part of JWK
    :param alg: Signature algorithm to use, Defaults to ES256
    :return: Signed JWS object
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")
    if account_kid is None:
        raise AttributeError("Provide account_kid as parameter")
    if jws_object is None:
        raise AttributeError("Provide jws_object as parameter")
    if jwk_object is None:
        raise AttributeError("Provide jwk_object as parameter")
    if jwk_public_json is None:
        raise AttributeError("Provide jwk_public_json as parameter")
    if alg is None:
        raise AttributeError("Provide alg as parameter")

    try:
        unprotected_header = {'kid': account_kid, 'jwk': json.loads(jwk_public_json)}
        protected_header = {'alg': alg}
        unprotected_header_json = json.dumps(unprotected_header)
        protected_header_json = json.dumps(protected_header)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not create headers')
        logger.error('Could not create headers: ' + repr(exp))
        raise
    else:
        logger.info("Created headers")
        log_dict_as_json(data=unprotected_header)
        log_dict_as_json(data=protected_header)

    try:
        logger.debug("Signing JWS with following")
        log_dict_as_json(lineno=get_current_line_no(), data={'jws_object': repr(jws_object.__dict__)})
        log_dict_as_json(lineno=get_current_line_no(), data={'alg': alg})
        log_dict_as_json(lineno=get_current_line_no(), data={'unprotected_header_json': unprotected_header})
        log_dict_as_json(lineno=get_current_line_no(), data={'protected_header_json': protected_header})

        jws_object.add_signature(jwk_object, alg=alg, header=unprotected_header_json, protected=protected_header_json)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not sign JWS with JWK')
        logger.error('Could not sign JWS with JWK: ' + repr(exp))
        #log_dict_as_json(data={'msg': 'Could not sign JWS with JWK', 'unprotected_header': unprotected_header, 'protected_header': protected_header})
        raise
    else:
        logger.info("Signed JWS with JWK")
        logger.debug("Signed jws_object: " + str(jws_object.__dict__))
        return jws_object
예제 #9
0
def store_jwk(account_id=None, account_kid=None, account_key=None):
    """
    Stores JWK to key storage

    :param account_id: User account ID
    :param account_kid: Key ID
    :param account_key: JWK
    :return:
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")
    if account_kid is None:
        raise AttributeError("Provide account_kid as parameter")
    if account_key is None:
        raise AttributeError("Provide account_key as parameter")

    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise

    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise

    try:
        cursor = store_jwk_to_db(account_id=account_id,
                                 account_kid=account_kid,
                                 account_key=account_key,
                                 cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not store jwk to database')
        logger.error('Could not store jwk to database: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.commit()
        connection.close()
        logger.debug('JWK, kid and account_id stored')
예제 #10
0
def jws_json_to_object(jws_json=None):
    """
    Converts JWS json presentation to JWS object
    - http://jwcrypto.readthedocs.io/en/stable/jws.html

    :param jws_json: JSON presentation of JWS object
    :return: JWS object
    """
    if jws_json is None:
        raise AttributeError("Provide jws_json as parameter")
    else:
        logger.debug("As parameter jws_json: " +
                     repr(jws_json).replace('u\'', '\''))

    try:
        jws_object = jws.JWS()
        jws_object.deserialize(raw_jws=jws_json)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWS json to JWS object')
        logger.error('Could not convert JWS json to JWS object: ' + repr(exp))
        raise
    else:
        logger.info('JWS json converted to JWS object')
        logger.debug('jws_object: ' + repr(jws_object.__dict__))
        return jws_object
예제 #11
0
def init_sqlite_db(connection=None):
    """
    Initializes SQLite database.

    :param connection: Database connection object
    :return: Database connection object
    """
    if connection is None:
        raise AttributeError("Provide connection as parameter")

    sql_query = '''CREATE TABLE account_keys (
              id            INTEGER   PRIMARY KEY AUTOINCREMENT,
              kid           TEXT  UNIQUE NOT NULL,
              account_id    INTEGER  UNIQUE NOT NULL,
              jwk       BLOB  NOT NULL
          );'''

    try:
        logger.debug('Initializing database')
        connection.execute(sql_query)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not initialize database')
        logger.error('connection.execute(sql): ' + repr(exp))
        connection.rollback()
        raise
    else:
        connection.commit()
        logger.debug('Database initialized')
        return connection
예제 #12
0
def store_jwk_to_db(account_id=None, account_kid=None, account_key=None, cursor=None):
    """
    Stores JWK to database.

    :param account_id: User account ID
    :param account_kid: Key ID
    :param account_key: Key
    :param cursor: Database cursor
    :return: Database cursor and last inserted row id
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")
    if account_kid is None:
        raise AttributeError("Provide account_kid as parameter")
    if account_key is None:
        raise AttributeError("Provide account_key as parameter")
    if cursor is None:
        raise AttributeError("Provide cursor as parameter")

    sql_query = "INSERT INTO account_keys (kid, account_id, jws_key) VALUES ('%s', '%s', '%s')" % \
                (account_kid, account_id, account_key)

    try:
        cursor, last_id = execute_sql_insert(cursor=cursor, sql_query=sql_query)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not store JWK to Database')
        logger.error('Could not store JWK to Database: ' + repr(exp))
        logger.debug('sql_query: ' + repr(sql_query))
        raise
    else:
        return cursor, last_id
예제 #13
0
def gen_key_as_jwk(account_kid=None):
    """
    Generates JWK (JSON Web Key) object with JWCrypto's jwk module.
    - Module documentation: http://jwcrypto.readthedocs.io/en/stable/jwk.html

    :param account_kid: Key ID, https://tools.ietf.org/html/rfc7517#section-4.5
    :return: Generated JWK object
    """
    if account_kid is None:
        raise AttributeError("Provide account_kid as parameter")

    gen = {"generate": "EC", "cvr": "P-256", "kid": account_kid}

    try:
        account_key = jwk.JWK(**gen)
        account_key = jwk_object_to_json(jwk_object=account_key)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not generate JWK')
        logger.error('Could not generate JWK: ' + repr(exp))
        raise
    else:
        logger.debug('JWK for account generated')
        logger.debug('account_key: ' + repr(account_key))
        return account_key
예제 #14
0
def get_sqlite_connection():
    """
    Get connection for SQLite Database

    :return: Database connection object
    """

    if (os.path.exists(DATABASE) and os.path.isfile(DATABASE)):
        logger.debug("init_db = False")
        init_db = False
    else:
        logger.debug("init_db = True")
        init_db = True

    try:
        connection = sqlite3.connect(DATABASE)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description=
            "Could not get database connection. Could not open db file.")
        logger.error('sqlite3.connect(' + DATABASE + '): ' + repr(exp))
        raise
    else:
        if init_db:
            try:
                connection = init_sqlite_db(connection=connection)
            except Exception:
                raise

        logger.debug('DB connection at ' + repr(connection))
        return connection
예제 #15
0
def gen_account_api_key(account_id=None):
    """
    Generate API Key for account ID

    :param account_id:
    :return: API Key
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    account_api_key = "account-api-key-" + str(uuid4())
    account_api_key = base64.b64encode(account_api_key)
    logger.debug('Generated account_api_key: ' + str(account_api_key))

    try:
        store_api_key(account_id=account_id, account_api_key=account_api_key)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description=
            'Failed to store generated Api key. Key must be regenerated.')
        logger.error('Failed to store generated api key: ' + repr(exp))
        raise
    else:
        logger.info('For account with id: ' + str(account_id) +
                    ' has been generated Api Key: ' + str(account_api_key))
        return account_api_key
예제 #16
0
def get_account_key(account_id=None):
    """
    Get Key by account ID

    :param account_id:
    :return: Key
    """
    if (True):
        # For to disable usage of this function
        raise NotImplementedError()
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise

    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise

    try:
        cursor, key, kid = get_key_by_account_id(account_id=account_id,
                                                 cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not lget jwk from database')
        logger.error('Could not get jwk from database: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.close()
        logger.debug('JWK fetched')
        return key
예제 #17
0
def get_account_api_key(account_id=None):
    """
    Get API Key by account ID

    :param account_id:
    :return: API Key
    """
    logger.info("Get Account APIKey by Account ID")

    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    try:
        logger.info("Getting DB connection")
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise
    else:
        logger.info("Got DB connection")

    try:
        logger.info("Getting DB cursor")
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' + repr(exp))
        raise
    else:
        logger.info("Got DB cursor")

    try:
        cursor, api_key = get_api_key(account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not find API key from database')
        logger.error('Could not get API key from database: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.close()
        logger.debug('API key fetched')
        return api_key
예제 #18
0
def get_account_public_key(account_id=None):
    """
    Get public Key by account ID

    :param account_id:
    :return: public Key & Key ID
    """

    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise

    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise

    try:
        cursor, key_public, kid = get_public_key_by_account_id(
            account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get public key from database')
        logger.error('Could not get public key from database: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.close()
        logger.debug('Public key fetched')
        return key_public, kid
예제 #19
0
def delete_entry_from_blackbox_sqlite_db(account_id=None):
    """
    Delete entry from Blackbox database.

    :return: Database connection object
    """
    if account_id is None:
        raise AttributeError("Provide account_id as parameter")

    try:
        account_id = str(account_id)
    except Exception:
        raise TypeError("account_id MUST be str, not " + str(type(account_id)))

    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get database connection')
        logger.error('get_sqlite_connection: ' + repr(exp))
        raise

    sql_query = "DELETE FROM account_keys WHERE account_id='%s';" % (
        account_id)

    try:
        logger.info('Deleting entry')
        logger.debug('Executing: ' + str(sql_query))
        connection.execute(sql_query)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not delete entry from database')
        logger.error('connection.execute(sql): ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.commit()
        connection.close()
        logger.info('Entry deleted')
        return True
예제 #20
0
def get_account_id_by_api_key(api_key=None):
    """
    Get User account ID by Api Key

    :param api_key:
    :return: User account ID
    """
    if api_key is None:
        raise AttributeError("Provide api_key as parameter")

    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise

    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise

    try:
        cursor, account_id = get_account_id(api_key=api_key, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not Account ID from database')
        logger.error('Could not get Account ID from database: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        connection.close()
        logger.debug('Account ID fetched')
        return account_id
예제 #21
0
def check_api_auth_user(api_key):
    logger.info("Checking Api-Key")
    try:
        logger.debug("Fetching Account ID")
        account_id = get_account_id_by_api_key(api_key=api_key)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Fetching Account ID failed')
        logger.error('Fetching Account ID failed: ' + repr(exp))
        return False
    else:
        logger.debug("Found account_id: " + str(account_id) + " with api_key: " + str(api_key))
        return True
예제 #22
0
def execute_sql_insert(cursor, sql_query):
    """
    Executes SQL INSERT queries.

    :param cursor: Database cursor
    :param sql_query: SQl query to execute
    :return: Database cursor and last inserted row id
    """

    if cursor is None:
        raise AttributeError("Provide cursor as parameter")
    if sql_query is None:
        raise AttributeError("Provide sql_query as parameter")

    last_id = ""

    try:
        cursor.execute(sql_query)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Error in SQL INSERT query execution')
        logger.error('Error in SQL query execution: ' + repr(exp))
        raise
    else:
        logger.debug('SQL query executed')

    try:
        last_id = str(cursor.lastrowid)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='lastrowid not found')
        logger.error('cursor.lastrowid not found: ' + repr(exp))
        logger.info('cursor.lastrowid not found. Using None instead')
        last_id = None
    else:
        logger.debug('cursor.lastrowid: ' + last_id)

    return cursor, last_id
예제 #23
0
def get_sqlite_connection():
    """
    Get connection for SQLite Database

    :return: Database connection object
    """

    if (os.path.exists(DATABASE) and os.path.isfile(DATABASE)):
        logger.debug("init_db = False")
        init_db = False
    else:
        logger.debug("init_db = True")
        init_db = True
        # If there is no db directory it will be created
        if DATABASE_DIRECTORY != "./":
            if not os.path.isdir(DATABASE_DIRECTORY):
                try:
                    os.mkdir(DATABASE_DIRECTORY)
                    print(
                        "Creating LOG_PATH: '{}'.".format(DATABASE_DIRECTORY))
                except IOError:
                    print("LOG_PATH: '{}' already exists.".format(
                        DATABASE_DIRECTORY))
                except Exception as e:
                    print(
                        "LOG_PATH: '{}' could not be created. Exception: {}.".
                        format(DATABASE_DIRECTORY, repr(e)))

    try:
        connection = sqlite3.connect(DATABASE)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description=
            "Could not get database connection. Could not open db file.")
        logger.error('sqlite3.connect(' + DATABASE + '): ' + repr(exp))
        raise
    else:
        if init_db:
            try:
                connection = init_sqlite_db(connection=connection)
            except Exception:
                raise

        logger.debug('DB connection at ' + repr(connection))
        return connection
예제 #24
0
def get_sqlite_cursor(connection=None):
    """
    Get cursor for SQLite database connection.

    :param connection: Database connection object
    :return: Database cursor object and Database connection object
    """
    if connection is None:
        raise AttributeError("Provide connection as parameter")

    try:
        cursor = connection.cursor()
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not get database cursor')
        logger.error('connection.cursor(): ' + repr(exp))
        raise
    else:
        logger.debug('DB cursor at ' + repr(cursor))
        return cursor, connection
예제 #25
0
def jws_generate(payload=None):
    if payload is None:
        raise AttributeError("Provide payload as parameter")

    payload_json = json.dumps(payload)
    logger.debug('payload_json: ' + payload_json)

    try:
        jws_object = jws.JWS(payload=payload_json)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not generate JWS object with payload')
        logger.error('Could not generate JWS object with payload: ' + repr(exp))
        log_dict_as_json(data={'payload': repr(payload)})
        raise
    else:
        logger.debug('jws_object: ' + str(jws_object))
        log_dict_as_json(lineno=get_current_line_no(), data={'jws_object': jws_object.__dict__})
        logger.info('JWS object created')
        return jws_object
예제 #26
0
def jwk_object_to_json_public_part(jwk_object=None):
    """
    Exports JWK object's public part to JSON presentation

    :param jwk_object:
    :return: JSON presentation of JWK object
    """
    if jwk_object is None:
        raise AttributeError("Provide jwk_object as parameter")

    try:
        jwk_json_public = jwk_object.export_public()
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Could not export public part of JWK')
        logger.error('Could not export public part of JWK: ' + repr(exp))
        raise
    else:
        logger.debug('JWK exported')
        logger.debug('jwk_json: ' + repr(jwk_json_public))
        return jwk_json_public
예제 #27
0
def jws_verify(jws_object=None, jwk_object=None):
    """
    Verifies signature of JWS.

    :param jws_object: JWS object to verify
    :param jwk_object: JWK onject to use in verification
    :return: Boolean, presenting if verification passed
    """
    if jws_object is None:
        raise AttributeError("Provide jws_json as parameter")
    if jwk_object is None:
        raise AttributeError("Provide jwk_object as parameter")

    try:
        jws_object.verify(jwk_object)
    except Exception as exp:
        exp = append_description_to_exception(exp=exp, description='Signature verification failed')
        logger.error('Signature verification failed: ' + repr(exp))
        return False
    else:
        logger.info("JWS verified")
        return True
예제 #28
0
def generate_and_sign_jws(account_id=None, jws_payload=None):
    if account_id is None:
        raise AttributeError("Provide account_id or as parameter")
    if jws_payload is None:
        raise AttributeError("Provide jws_payload or as parameter")

    # Prepare database connection
    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise
    else:
        logger.info("######## DB Connection -> OK ########")

    # Prepare database cursor
    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise
    else:
        logger.info("######## DB Cursor -> OK ########")

    # Get public Key as JSON and Key ID
    kid = {}
    try:
        cursor, key_public_json, kid[0] = get_public_key_by_account_id(
            account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get public key as JSON')
        logger.error('Could not get public key as JSON: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        logger.info("######## Public Key -> OK ########")

    # Get Key as JWK object and Key ID
    try:
        cursor, key_object, kid[1] = get_key(account_id=account_id,
                                             cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get key object')
        logger.error('Could not get key object: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        logger.info("######## Key Object -> OK ########")
        connection.close()

    # Generate JWS
    try:
        jws_object = jws_generate(payload=jws_payload)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not generate JWS object')
        logger.error('Could not generate JWS object: ' + repr(exp))
        raise
    else:
        logger.info("######## JWS Object -> OK ########")

    # Sign JWS
    try:
        jws_object_signed = jws_sign(account_id=account_id,
                                     account_kid=kid[0],
                                     jws_object=jws_object,
                                     jwk_object=key_object,
                                     jwk_public_json=key_public_json)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not sign JWS object')
        logger.error('Could not sign JWS object: ' + repr(exp))
        raise
    else:
        logger.info("######## JWS signature -> OK ########")

    # JWS object to JWS JSON
    try:
        jws_json = jws_object_to_json(jws_object=jws_object_signed)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWS object to JWS json')
        logger.error('Could not convert JWS object to JWS json: ' + repr(exp))
        raise
    else:
        logger.info("######## JWS conversion -> OK ########")
        return jws_json
예제 #29
0
def verify_jws_signature_with_jwk(account_id=None, jws_json_to_verify=None):
    """
    Verifies signature of JWS with key related to user account.
    Key used in verification is fetched from database by account_id.

    :param account_id: User account ID
    :param jws_json_to_verify: JSON presentation of JWS object that should be verified
    :return: Boolean, presenting if verification passed
    """
    if account_id is None:
        raise AttributeError("Provide account_id or as parameter")
    if jws_json_to_verify is None:
        raise AttributeError("Provide jws_json_to_verify or as parameter")

    # Prepare JWS for signing
    try:
        jws_object_to_verify = jws_json_to_object(jws_json=jws_json_to_verify)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWS json to JWS object')
        logger.error('Could not convert JWS json to JWS object: ' + repr(exp))
        raise
    else:
        logger.debug("jws_object_to_verify: " +
                     str(jws_object_to_verify.__dict__))
        logger.info("######## JWS object  -> OK ########")

    # Prepare database connection
    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise
    else:
        logger.info("######## DB Connection -> OK ########")

    # Prepare database cursor
    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise
    else:
        logger.info("######## DB Cursor -> OK ########")

    # Get Key as JWK object and Key ID
    try:
        cursor, key_object, kid = get_key(account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get key object')
        logger.error('Could not get key object: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        logger.info("######## Key Object -> OK ########")
        connection.close()

    # Verifying JWS
    logger.info("Verifying JWS")
    jws_signature_valid = jws_verify(jws_object=jws_object_to_verify,
                                     jwk_object=key_object)
    logger.info("JWS verified: " + str(jws_signature_valid))

    return jws_signature_valid
예제 #30
0
def sign_jws_with_jwk(account_id=None, jws_json_to_sign=None):
    """
    For signing JWSs that have been generated by others.
    Gathers necessary data for JWS signing. Signs JWS.

    :param account_id: User account ID
    :param jws_json_to_sign: JSON presentation of JWS that should be signed
    :return: Signed JWS json
    """
    if account_id is None:
        raise AttributeError("Provide account_id or as parameter")
    if jws_json_to_sign is None:
        raise AttributeError("Provide jws_json_to_sign or as parameter")

    # jws_json_to_sign to dict
    try:
        jws_structure = json.loads(jws_json_to_sign)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert jws_json_to_sign to dict')
        logger.error('Could not convert jws_json_to_sign to dict: ' +
                     repr(exp))
        raise
    else:
        log_dict_as_json(jws_structure)
        logger.info("######## jws_json_to_sign to dict  -> OK ########")

    # Fix incorrect padding of base64 string
    try:
        # dict_keys = jws_structure.keys()  # Top-level dict key to enable access to JWS payload
        # first_key_in_dict = dict_keys[0]
        # logger.debug('JWS payload before Base64 fix: ' + str(jws_structure[first_key_in_dict]['payload']))
        # jws_structure[first_key_in_dict]['payload'] += '=' * (-len(jws_structure[first_key_in_dict]['payload']) % 4)  # Fix incorrect padding of base64 string.
        logger.debug('JWS payload before Base64 fix: ' +
                     str(jws_structure['payload']))
        jws_structure['payload'] += '=' * (
            -len(jws_structure['payload']) % 4
        )  # Fix incorrect padding of base64 string.
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Failed to fix incorrect padding of base64 string')
        logger.error('Failed to fix incorrect padding of base64 string: ' +
                     repr(exp))
        raise
    else:
        #logger.debug('JWS payload after  Base64 fix: ' + str(jws_structure[first_key_in_dict]['payload']))
        logger.debug('JWS payload after  Base64 fix: ' +
                     str(jws_structure['payload']))
        logger.info("######## Base64 fix -> OK ########")

    # Convert jws_structure to JSON for future steps
    try:
        #jws_structure_json = json.dumps(jws_structure[first_key_in_dict])
        jws_structure_json = json.dumps(jws_structure)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='JSON conversion failed')
        logger.error('JSON conversion failed: ' + repr(exp))
        raise
    else:
        logger.info("######## JSON conversion -> OK ########")

    # Prepare JWS for signing
    try:
        jws_object_to_sign = jws_json_to_object(jws_json=jws_structure_json)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWS json to JWS object')
        logger.error('Could not convert JWS json to JWS object: ' + repr(exp))
        raise
    else:
        logger.debug("jws_object_to_sign: " + str(jws_object_to_sign.__dict__))
        logger.info("######## JWS object  -> OK ########")

    # Prepare database connection
    try:
        connection = get_sqlite_connection()
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get connection SQL database.')
        logger.error('Could not get connection SQL database: ' + repr(exp))
        raise
    else:
        logger.info("######## DB Connection -> OK ########")

    # Prepare database cursor
    try:
        cursor, connection = get_sqlite_cursor(connection=connection)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp,
            description='Could not get cursor for database connection')
        logger.error('Could not get cursor for database connection: ' +
                     repr(exp))
        raise
    else:
        logger.info("######## DB Cursor -> OK ########")

    # Get public Key as JSON and Key ID
    kid = {}
    try:
        cursor, key_public_json, kid[0] = get_public_key_by_account_id(
            account_id=account_id, cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get public key as JSON')
        logger.error('Could not get public key as JSON: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        logger.info("######## Public Key -> OK ########")

    # Get Key as JWK object and Key ID
    try:
        cursor, key_object, kid[1] = get_key(account_id=account_id,
                                             cursor=cursor)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not get key object')
        logger.error('Could not get key object: ' + repr(exp))
        connection.rollback()
        connection.close()
        raise
    else:
        logger.info("######## Key Object -> OK ########")
        connection.close()

    # Sign JWS
    try:
        jws_object_signed = jws_sign(account_id=account_id,
                                     account_kid=kid[0],
                                     jws_object=jws_object_to_sign,
                                     jwk_object=key_object,
                                     jwk_public_json=key_public_json)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not sign JWS object')
        logger.error('Could not sign JWS object: ' + repr(exp))
        raise
    else:
        logger.info("######## JWS signature -> OK ########")

    # JWS object to JWS JSON
    try:
        jws_json = jws_object_to_json(jws_object=jws_object_signed)
    except Exception as exp:
        exp = append_description_to_exception(
            exp=exp, description='Could not convert JWS object to JWS json')
        logger.error('Could not convert JWS object to JWS json: ' + repr(exp))
        raise
    else:
        logger.info("######## JWS conversion -> OK ########")
        return jws_json