def command_change_expire_date(update, context):
    '''Set the symmetric secret key expire date'''
    uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id))
    if sql.sql_check_user(uid_hash) != 1:
        return

    keyboard = keyboards.expiredate_unit_selection_keyboard()

    encryption_mode = sql.sql_get_encryption_mode(uid_hash)
    if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE:
        expire_time = sql.sql_get_secret_key_expire_date_from_config(uid_hash)
        text = 'Change the (default is %s) <b>symmetric encryption</b> expired time.' % (
            str(timedelta(seconds=int(expire_time))))
    elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE:
        expire_time = sql.sql_get_public_key_expire_date_from_config(uid_hash)
        text = 'Change the (default is %s) <b>asymmetric encryption</b> expired time.' % (
            str(timedelta(seconds=int(expire_time))))

    update.message.reply_text(text=text,
                              parse_mode=ParseMode.HTML,
                              reply_markup=keyboard)
    now_time = datetime.fromtimestamp(int(time.time()))
    text = '<b>Please select the unit you want to set the time for (now time is: %s):</b>' % now_time
    update.message.reply_text(text=text,
                              parse_mode=ParseMode.HTML,
                              reply_markup=keyboard)
Ejemplo n.º 2
0
def symmetric_encrypt_inline(update, context, uid_hash, text):
    '''Never use @run_asyn here.'''

    if sql.sql_check_user(uid_hash) != 1:
        # Make sure the inline user is registerd.
        return -1

    secret_key_bytes = encrypt.symmetric_key_generate()
    secret_key_str = encrypt.convert_bytes_to_str(secret_key_bytes)
    secret_key_str_hash = encrypt.sha256_hash(secret_key_str)
    sql.sql_insert_secret_key(uid_hash, secret_key_str_hash, secret_key_str)

    encrypt_result_dict = encrypt.symmetric_encryption(secret_key_bytes, text)

    if encrypt_result_dict:
        cipher_text_bytes = encrypt_result_dict['cipher_text']
        cipher_text_str = encrypt.convert_bytes_to_str(cipher_text_bytes)

        nonce_bytes = encrypt_result_dict['nonce']
        nonce_str = encrypt.convert_bytes_to_str(nonce_bytes)
        nonce_str_hash = encrypt.sha256_hash(nonce_str)
        if sql.sql_insert_nonce(uid_hash, nonce_str_hash, nonce_str) != 0:
            result_str = config.SERVER_ERROR_EXPRESSION
        else:
            result_str = 'sencrypted[%s%s%s]' % (
                nonce_str_hash, secret_key_str_hash, cipher_text_str)

    else:
        result_str = config.SERVER_ERROR_EXPRESSION

    return result_str
def command_change_time_to_live(update, context):
    uid_hash = encrypt.blake2b_hash(str(update.message.from_user.id))
    if sql.sql_check_user(uid_hash) != 1:
        return

    keyboard = keyboards.inline_chtm_keyboard()
    text = 'Please choose the message decryption time to live value.'
    update.message.reply_text(text=text,
                              parse_mode=ParseMode.HTML,
                              reply_markup=keyboard)
def command_account(update, context):
    '''Show the account details for user.
    '''
    uid = update.message.from_user.id
    uid_hash = encrypt.blake2b_hash(str(uid))
    if sql.sql_check_user(uid_hash) != 1:
        re_text = "<b>Please register first!</b>"
        update.message.reply_text(text=re_text, parse_mode=ParseMode.HTML)
        return

    expire_data_dict = sql.sql_get_all_expire_date(uid_hash)
    date_s = str(timedelta(seconds=int(expire_data_dict['sexpire_date'])))
    date_a = datetime.fromtimestamp(
        int(sql.sql_get_public_key_expire_date_from_public_key(uid_hash)))
    date_aa = str(timedelta(seconds=int(expire_data_dict['aexpire_date'])))
    date_n = datetime.fromtimestamp(int(time.time()))

    encryption_mode = sql.sql_get_encryption_mode(uid_hash)

    if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE:
        encryption_mode = 'Symmetric'
    elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE:
        encryption_mode = 'Asymmetric'

    uid_text = 'UID: <b>%d</b>\nEncryption mode: <b>%s</b>\nUTC time now: <b>%s</b>' % (
        uid, encryption_mode, date_n)
    update.message.reply_text(text=uid_text, parse_mode=ParseMode.HTML)

    symmetirc_text = 'Each symmetric secret key expire interval (UTC): <b>%s</b>' % (
        date_s)
    update.message.reply_text(text=symmetirc_text, parse_mode=ParseMode.HTML)

    asymmetric_text = (
        'Asymmetric public key (Note: we will not save the private key): <b>%s</b>\nExpire date (UTC): <b>%s</b>\n'
        'Each asymmetric public key expire interval (UTC): <b>%s</b>\n'
        'If your public key become 0, that mean your public key is expired, you need to re-gen new key.'
    ) % (sql.sql_get_public_key(uid_hash), date_a, date_aa)
    update.message.reply_text(text=asymmetric_text, parse_mode=ParseMode.HTML)
def command_inline(update, context):
    '''Process the message from inline query'''
    # type(text) is str.
    text = update.inline_query.query
    text = text.strip()
    if len(text) == 0:
        return 0

    uuid_me = uuid.uuid4()
    results = list()
    uid = update.inline_query.from_user.id
    uid_hash = encrypt.blake2b_hash(str(uid))

    if config.maintenance_mode:
        results.append(
            InlineQueryResultArticle(
                id=uuid_me,
                title=config.SERVER_ERROR_EXPRESSION,
                description=config.MAINTENANCE_EXPRESSION,
                input_message_content=InputTextMessageContent(
                    config.MAINTENANCE_EXPRESSION, parse_mode=ParseMode.HTML)))
        try:
            update.inline_query.answer(results,
                                       cache_time=60,
                                       is_personal=True)
        except Exception:
            pass
        return 0

    if sql.sql_check_user(uid_hash) != 1:
        plain_text = 'Sorry, we can\'t decrypt this ciphertext'
        results.append(
            InlineQueryResultArticle(
                id=uuid_me,
                title=config.SERVER_ERROR_EXPRESSION,
                description=plain_text,
                input_message_content=InputTextMessageContent(
                    config.SERVER_ERROR_EXPRESSION,
                    parse_mode=ParseMode.HTML)))
        try:
            update.inline_query.answer(results,
                                       cache_time=60,
                                       is_personal=True)
        except Exception:
            pass
        return 0

    if 'seinline[' in text:
        try:
            cipher_text_hash = text.split('seinline')[1][1:-1]
        except IndexError:
            return -1

        if len(cipher_text_hash) == 0 or not check_string(cipher_text_hash):
            return -1

        # Check the cipher_text.
        cipher_text = sql.sql_get_cipher_text(cipher_text_hash)
        # print('commands(cipher_text): ' + cipher_text)
        if not cipher_text:
            # try:
            #     bot.editMessageText(
            #         message_id=update.callback_query.message.message_id,
            #         chat_id=update.callback_query.message.chat.id,
            #         text='This ciphertext has expired. %s' % (
            #             config.GOOD_EXPRESSION),
            #         parse_mode=ParseMode.HTML,
            #         # reply_markup=keyboards.inline_chtm_keyboard()
            #     )
            # except Exception:
            #     pass

            results.append(
                InlineQueryResultArticle(
                    id=uuid_me,
                    title=config.EXPIRE_ERROR_EXPRESSION,
                    description='please check your input',
                    input_message_content=InputTextMessageContent(
                        config.SERVER_ERROR_EXPRESSION,
                        parse_mode=ParseMode.HTML)))
            try:
                update.inline_query.answer(results,
                                           cache_time=60,
                                           is_personal=True)
            except Exception:
                pass
            return -1

        # Check the plain_text.
        plain_text = messages.symmetric_decrypt_inline(update, context,
                                                       uid_hash, cipher_text)
        # print('commands(plain_text): ' + plain_text)
        if not plain_text:
            results.append(
                InlineQueryResultArticle(
                    id=uuid_me,
                    title=config.SERVER_ERROR_EXPRESSION,
                    description='please check your input',
                    input_message_content=InputTextMessageContent(
                        config.SERVER_ERROR_EXPRESSION,
                        parse_mode=ParseMode.HTML)))
            try:
                update.inline_query.answer(results,
                                           cache_time=60,
                                           is_personal=True)
            except Exception:
                pass
            return -1

        results.append(
            InlineQueryResultArticle(
                id=uuid_me,
                title='De-Result',
                description=plain_text,
                input_message_content=InputTextMessageContent(
                    plain_text, parse_mode=ParseMode.HTML)))
        try:
            update.inline_query.answer(results,
                                       cache_time=60,
                                       is_personal=True)
        except Exception:
            pass

    else:
        cipher_text = messages.symmetric_encrypt_inline(
            update, context, uid_hash, text)
        cipher_text_hash = encrypt.sha256_hash(cipher_text)
        if not cipher_text or cipher_text == -1 or not cipher_text_hash:
            results.append(
                InlineQueryResultArticle(
                    id=uuid_me,
                    title=config.SERVER_ERROR_EXPRESSION,
                    description='please check your input',
                    input_message_content=InputTextMessageContent(
                        config.SERVER_ERROR_EXPRESSION,
                        parse_mode=ParseMode.HTML)))
            try:
                update.inline_query.answer(results,
                                           cache_time=60,
                                           is_personal=True)
            except Exception:
                pass

            return -1

        switch_inline_query_str = 'seinline[%s]' % cipher_text_hash
        keyboard = keyboards.inline_keyboard(switch_inline_query_str)
        sql.sql_insert_cipher_text(uid_hash, cipher_text_hash, cipher_text)

        # Disable the sql_get_emoji_mode in the inline mode.
        # if 1 == 2:
        if sql.sql_get_emoji_mode(uid_hash):
            # if user want to use the emoji encrption.
            try:
                cipher_data = cipher_text.split('sencrypted')[1][1:-1]
                # print(cipher_text)
            except IndexError:
                return -1

            if len(cipher_data) == 0 or not check_string(cipher_data):
                return -1

            emoji_text = encrypt.convert_str_to_emoji_c(cipher_data)
            # print(emoji_text)
            # emoji_text = 'sencrypted[%s]' % emoji_text
            results.append(
                InlineQueryResultArticle(
                    id=uuid_me,
                    title='En-Result',
                    description='id: %s' % str(uuid_me)[0:8],
                    input_message_content=InputTextMessageContent(
                        emoji_text, parse_mode=ParseMode.HTML),
                    reply_markup=keyboard))
            try:
                update.inline_query.answer(results,
                                           cache_time=60,
                                           is_personal=True)
            except Exception:
                pass
        else:
            results.append(
                InlineQueryResultArticle(
                    id=uuid_me,
                    title='En-Result',
                    description='id: %s' % str(uuid_me)[0:8],
                    input_message_content=InputTextMessageContent(
                        cipher_text, parse_mode=ParseMode.HTML),
                    reply_markup=keyboard))
            try:
                update.inline_query.answer(results,
                                           cache_time=60,
                                           is_personal=True)
            except Exception:
                pass
Ejemplo n.º 6
0
def process_message_private(update, context):
    '''For private chat use.'''
    message = update.message
    uid = message.from_user.id
    uid_hash = encrypt.blake2b_hash(str(uid))

    # Ignore the command message.
    if message.text and message.text[0] == r'/':
        return

    if sql.sql_check_user(uid_hash) != 1:
        # If the not registed user want to decrypted this message.
        # Be safety considering, not do decrypt job.
        plain_text = 'Sorry, we can\'t decrypt this ciphertext'
        update.message.reply_text(text=plain_text, parse_mode=ParseMode.HTML)
        return

    encryption_mode = sql.sql_get_encryption_mode(uid_hash)
    if config.expire_date_unit_select_dict.__contains__(uid_hash):
        if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE:
            if config.expire_date_unit_select_dict[uid_hash] == 'second':
                try:
                    second = int(message.text)
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_symmetric_expire_date(uid_hash, second)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'minute':
                try:
                    minute = int(message.text) * 60
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_symmetric_expire_date(uid_hash, minute)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'hour':
                try:
                    hour = int(message.text) * 60 * 60
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_symmetric_expire_date(uid_hash, hour)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'day':
                try:
                    day = int(message.text) * 60 * 60 * 24
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_symmetric_expire_date(uid_hash, day)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)
        if encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE:
            if config.expire_date_unit_select_dict[uid_hash] == 'second':
                try:
                    second = int(message.text)
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_asymmetric_expire_date(uid_hash, second)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'minute':
                try:
                    minute = int(message.text) * 60
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_asymmetric_expire_date(uid_hash, minute)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'hour':
                try:
                    hour = int(message.text) * 60 * 60
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_asymmetric_expire_date(uid_hash, hour)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif config.expire_date_unit_select_dict[uid_hash] == 'day':
                try:
                    day = int(message.text) * 60 * 60 * 24
                except Exception:
                    text = '<b>Please check your input.</b>'
                    update.message.reply_text(text=text,
                                              parse_mode=ParseMode.HTML)
                    return

                sql.sql_update_asymmetric_expire_date(uid_hash, day)
                config.expire_date_unit_select_dict.pop(uid_hash)
                config.command_expire_list.remove(uid_hash)
                text = '<b>Update success, please use /account command to see.</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

    # Do the encryption or decryption
    elif message.text:
        # First check the message whether emoji text.
        # if encrypt.detect_encrypted_emoji(message.text):
        if encrypt.detect_encrypted_emoji_c(message.text):
            # text = encrypt.convert_emoji_to_str(message.text)
            text = encrypt.convert_emoji_to_str_c(message.text)
            text = 'sencrypted[%s]' % text
            # print(text)
            symmetric_decrypt_message(update, context, text)

        elif encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE:
            if 'sencrypted[' in message.text:
                # This is encrypted message, we need to decrypt it.
                # Fist check out the user is registerd.
                symmetric_decrypt_message(update, context, message.text)

            elif 'seinline[' in message.text:

                # text = sql.sql_get_cipher_text(message.text)
                # symmetric_decrypt_message(
                #     update, context, text)
                text = '<b>Please use the inline mode to decrypted this message!</b>'
                update.message.reply_text(text=text, parse_mode=ParseMode.HTML)

            elif sql.sql_get_emoji_mode(uid_hash):
                symmetric_encrypt_message_emoji(update, context, message.text)

            else:
                symmetric_encrypt_message(update, context, message.text)

        elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE:
            if 'aencrypted[' in message.text:
                # This is encrypted message, we need to decrypt it.
                asymmetric_decrypt_message(update, context, message.text)

            elif config.private_key_dict.__contains__(uid_hash):
                if config.private_key_dict[uid_hash] == 'encrypt':
                    '''For the asymmetric encryption'''
                    asymmetric_encrypt_message(update, context, message.text)

                elif config.private_key_dict[uid_hash] == 'decrypt':
                    '''In here, we just sent out ciphertext to the bot,
                    now the bot still has to wait for our private key.
                    If use the symmetric key to encrypted or decrypted,
                    this step here will not need, the symmetric encryption just return the result.
                    '''
                    asymmetric_decrypt_message(update, context, message.text)

                elif len(config.private_key_dict[uid_hash]) != 0:
                    asymmetric_encrypt_message(update, context, message.text)

            else:
                asymmetric_encrypt_message(update, context, message.text)

    elif message.photo:
        # We get the last file_id which is the biggest size.
        photo_dict = message.photo[-1]
        file_id = photo_dict['file_id']
        photo_text = 'photo[%s]' % file_id
        if encryption_mode == config.SYMMETRIC_ENCRYPTION_MODE:
            symmetric_encrypt_message(update, context, photo_text)

        elif encryption_mode == config.ASYMMETRIC_ENCRYPTION_MODE:
            asymmetric_encrypt_message(update, context, photo_text)