figenc

[RADIOACTIVE] rsa and symmetric key encryption scripts and executables
git clone git://git.figbert.com/figenc.git
Log | Files | Refs | README

figENC.py (36683B)


      1 import sys, json, getpass
      2 import tkinter as tk
      3 from tkinter import filedialog
      4 from random import choice
      5 import key, check
      6 from encrypt import enc_manager
      7 from decrypt import dec_manager
      8 import version_check as vc
      9 from path import find_path
     10 
     11 
     12 class App():
     13 
     14     def __init__(self, root):
     15         """Create and hide the main window then open the launcher window
     16         
     17         Keyword arguments:
     18         root -- the Tk() frame for the main window
     19         """
     20         self.crypto_mode = ""
     21         self.show_pass = False
     22         self.crypto_filepaths = ()
     23         self.key_dir = ""
     24         
     25         self.settings_file = find_path("settings.json")
     26         self.tips_file = find_path("tips.json")
     27         with open(self.settings_file) as settings_file:
     28             settings = json.load(settings_file)
     29         root.withdraw()
     30 
     31         self.launcher(settings)
     32         root.mainloop()
     33 
     34     def main_app(self, root, settings):
     35         """Create the main app widgets in the passed root variable, and then
     36         minimize the root window.
     37 
     38         Keyword arguments:
     39         root -- the main app window
     40         settings -- a dictionary of settings used to build the widget
     41         """
     42         root.wm_title("figENC")
     43         self.canvas = tk.Canvas(
     44             root,
     45             height=settings["win_height"],
     46             width=settings["win_width"]
     47         )
     48         self.canvas.pack(fill="both", expand=True, side=tk.LEFT)
     49         self.frame = tk.Frame(self.canvas, bg="#1A181C")
     50         self.frame.place(relwidth=1, relheight=1)
     51         self.header = tk.Label(
     52             self.frame,
     53             text="figENC",
     54             justify=tk.CENTER,
     55             font=("Arial", settings["font_size"] + 6),
     56             bg="#643181",
     57             fg="#F2DAFF",
     58             pady=2
     59         )
     60         self.subheader = tk.Label(
     61             self.frame,
     62             text="Industry leading encryption by FIGBERT",
     63             justify=tk.CENTER,
     64             font=("Arial", settings["font_size"]),
     65             bg="#643181",
     66             fg="#F2DAFF",
     67             pady=2
     68         )
     69         self.header.pack(fill="x", side=tk.TOP)
     70         self.subheader.pack(fill="x", side=tk.TOP)
     71         self.action = tk.Frame(self.frame, bg="#1A181C", pady=5)
     72         self.action.pack(fill="both")
     73         self.action_label = tk.Label(
     74             self.action,
     75             text="Action:",
     76             justify=tk.LEFT,
     77             font=("Arial", settings["font_size"]),
     78             bg="#1A181C",
     79             fg="#F2DAFF",
     80         )
     81         self.action_label.pack()
     82         self.action_list = tk.Listbox(
     83             self.action,
     84             justify=tk.CENTER,
     85             font=("Arial", settings["font_size"] - 2),
     86             bg="#1A181C",
     87             fg="#ACA0B2",
     88             selectbackground="#643181",
     89             selectmode=tk.SINGLE,
     90             relief=tk.SUNKEN,
     91             height=7
     92         )
     93         self.action_list.insert(
     94             1,
     95             "Encrypt with fresh keys (password locked)"
     96         )
     97         self.action_list.insert(2, "Encrypt with fresh keys (no password)")
     98         self.action_list.insert(3, "Encrypt with generated keys")
     99         self.action_list.insert(
    100             4,
    101             "Decrypt with generated keys (password locked)"
    102         )
    103         self.action_list.insert(
    104             5,
    105             "Decrypt with generated keys (no password)"
    106         )
    107         self.action_list.insert(6, "Only create fresh keys (password locked)")
    108         self.action_list.insert(7, "Only create fresh keys (no password)")
    109         self.action_list.pack(fill="both", pady=10)
    110         if sys.platform == "darwin":
    111             self.submit_action = tk.Button(
    112                 self.action,
    113                 text="Begin Process",
    114                 font=("Arial", settings["font_size"] - 2),
    115                 fg="#643181",
    116                 highlightthickness=0,
    117                 highlightbackground="#1A181C",
    118                 command=lambda: self.setup(self.action_list.curselection())
    119             )
    120         else:
    121             self.submit_action = tk.Button(
    122                 self.action,
    123                 text="Begin Process",
    124                 font=("Arial", settings["font_size"] - 2),
    125                 bg="#8A8A8A",
    126                 fg="#643181",
    127                 command=lambda: self.setup(self.action_list.curselection())
    128             )
    129         self.submit_action.pack()
    130         self.step_two = tk.Frame(self.frame, bg="#1A181C")
    131         self.step_two.pack(fill="both")
    132         self.file_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8)
    133         self.file_label = tk.Label(
    134             self.file_frame,
    135             text="If you see this, the app broke",
    136             font=("Arial", settings["font_size"]),
    137             bg="#1A181C",
    138             fg="#F2DAFF"
    139         )
    140         if sys.platform == "darwin":
    141             self.file_input = tk.Button(
    142                 self.file_frame,
    143                 text="Select File/s",
    144                 font=("Arial", settings["font_size"] - 2),
    145                 fg="#643181",
    146                 highlightthickness=0,
    147                 highlightbackground="#1A181C",
    148                 command=self.select_filepaths
    149             )
    150         else:
    151             self.file_input = tk.Button(
    152                 self.file_frame,
    153                 text="Select File/s",
    154                 font=("Arial", settings["font_size"] - 2),
    155                 bg="#8A8A8A",
    156                 fg="#643181",
    157                 command=self.select_filepaths
    158             )
    159         self.passcode_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8)
    160         self.passcode_label = tk.Label(
    161             self.passcode_frame,
    162             text="If you see this, the app broke",
    163             font=("Arial", settings["font_size"]),
    164             bg="#1A181C",
    165             fg="#F2DAFF"
    166         )
    167         self.passcode_instructions = tk.Label(
    168             self.passcode_frame,
    169             text="If you see this, the app broke",
    170             font=("Arial", settings["font_size"] - 2),
    171             bg="#1A181C",
    172             fg="#B494C7"
    173         )
    174         self.passcode_input = tk.Entry(
    175             self.passcode_frame,
    176             font=("Arial", settings["font_size"] - 2),
    177             justify=tk.CENTER,
    178             textvariable=tk.StringVar,
    179             show="*",
    180             bg="#1A181C",
    181             fg="#F2DAFF",
    182             highlightthickness=0,
    183             insertbackground="#F2DAFF"
    184         )
    185         self.passcode_input.bind("<Button-2>", self.toggle_pass)
    186         self.confirm_label = tk.Label(
    187             self.passcode_frame,
    188             text="Confirm passkey",
    189             font=("Arial", settings["font_size"]),
    190             bg="#1A181C",
    191             fg="#F2DAFF"
    192         )
    193         self.confirm_instructions = tk.Label(
    194             self.passcode_frame,
    195             text="Re-enter the provided passkey",
    196             font=("Arial", settings["font_size"] - 2),
    197             bg="#1A181C",
    198             fg="#B494C7"
    199         )
    200         self.confirm_input = tk.Entry(
    201             self.passcode_frame,
    202             font=("Arial", settings["font_size"] - 2),
    203             justify=tk.CENTER,
    204             textvariable=tk.StringVar,
    205             show="*",
    206             bg="#1A181C",
    207             fg="#F2DAFF",
    208             highlightthickness=0,
    209             insertbackground="#F2DAFF"
    210         )
    211         self.confirm_input.bind("<Button-2>", self.toggle_pass)
    212         self.save = tk.Frame(self.step_two, bg="#1A181C", pady=8)
    213         self.save_label = tk.Label(
    214             self.save,
    215             text="Save location for keys",
    216             font=("Arial", settings["font_size"]),
    217             bg="#1A181C",
    218             fg="#F2DAFF"
    219         )
    220         self.save_instructions = tk.Label(
    221             self.save,
    222             text="If you see this, the app broke",
    223             font=("Arial", settings["font_size"] - 2),
    224             bg="#1A181C",
    225             fg="#B494C7"
    226         )
    227         if sys.platform == "darwin":
    228             self.save_input = tk.Button(
    229                 self.save,
    230                 text="Select Directory",
    231                 font=("Arial", settings["font_size"] - 2),
    232                 fg="#643181",
    233                 highlightthickness=0,
    234                 highlightbackground="#1A181C",
    235                 command=self.select_key_dir
    236             )
    237         else:
    238             self.save_input = tk.Button(
    239                 self.save,
    240                 text="Select Directory",
    241                 font=("Arial", settings["font_size"] - 2),
    242                 bg="#8A8A8A",
    243                 fg="#643181",
    244                 command=self.select_key_dir
    245             )
    246         self.type_frame = tk.Frame(self.step_two, bg="#1A181C", pady=8)
    247         self.type_label = tk.Label(
    248             self.type_frame,
    249             text="Type of keys to generate",
    250             font=("Arial", settings["font_size"]),
    251             bg="#1A181C",
    252             fg="#F2DAFF"
    253         )
    254         self.type_instructions = tk.Label(
    255             self.type_frame,
    256             text=("Selecting RSA will generate a public and private key,\nbut"
    257             " selecting Mixed will also generate a symmetric key."
    258             ),
    259             font=("Arial", settings["font_size"] - 2),
    260             bg="#1A181C",
    261             fg="#B494C7"
    262         )
    263         self.type_button_frame = tk.Frame(self.type_frame, bg="#1A181C")
    264         self.type_control = tk.IntVar()
    265         self.rsa_radiobutton = tk.Radiobutton(
    266             self.type_button_frame,
    267             text="RSA",
    268             bg="#1A181C",
    269             fg="#F2DAFF" if sys.platform == "darwin" else "#B494C7",
    270             variable=self.type_control,
    271             value=0
    272         )
    273         self.mixed_radiobutton = tk.Radiobutton(
    274             self.type_button_frame,
    275             text="Mixed",
    276             bg="#1A181C",
    277             fg="#F2DAFF" if sys.platform == "darwin" else "#B494C7",
    278             variable=self.type_control,
    279             value=1
    280         )
    281         if sys.platform == "darwin":
    282             self.submit = tk.Button(
    283                 self.step_two,
    284                 text="If you see this, the app broke",
    285                 font=("Arial", settings["font_size"] - 2),
    286                 fg="#643181",
    287                 highlightbackground="#1A181C",
    288                 highlightthickness=0,
    289                 command=lambda: self.go(
    290                     mode=self.crypto_mode,
    291                     key_dir=self.key_paths,
    292                     target_files=self.crypto_filepaths,
    293                     passkey=self.passcode_input.get(),
    294                     passcheck=self.confirm_input.get()
    295                 )
    296             )
    297         else:
    298             self.submit = tk.Button(
    299                 self.step_two,
    300                 text="If you see this, the app broke",
    301                 font=("Arial", settings["font_size"] - 2),
    302                 bg="#8A8A8A",
    303                 fg="#643181",
    304                 command=lambda: self.go(
    305                     mode=self.crypto_mode,
    306                     key_dir=self.key_paths,
    307                     target_files=self.crypto_filepaths,
    308                     passkey=self.passcode_input.get(),
    309                     passcheck=self.confirm_input.get()
    310                 )
    311             )
    312 
    313     def open_settings(self, root):
    314         """Open the settings window and temporarily minimize the root window
    315         
    316         Keyword arguments:
    317         root -- the window to be minimized
    318         """
    319         root.withdraw()
    320         with open(self.settings_file) as settings_file:
    321             self.settings = json.load(settings_file)
    322         self.settings_window = tk.Toplevel(
    323             height=self.settings["win_height"],
    324             width=self.settings["win_width"],
    325             bg="#1A181C"
    326         )
    327         self.settings_window.wm_title("figENC - Settings")
    328         self.canvas = tk.Canvas(
    329             self.settings_window,
    330             height=self.settings["win_height"],
    331             width=self.settings["win_width"]
    332         )
    333         self.canvas.pack(fill=tk.BOTH, expand=True, side=tk.LEFT)
    334         self.frame = tk.Frame(self.canvas, bg="#1A181C")
    335         self.frame.place(relwidth=1, relheight=1)
    336         self.header = tk.Label(
    337             self.frame,
    338             text="Settings",
    339             justify=tk.CENTER,
    340             font=("Arial", str(self.settings["font_size"] + 4)),
    341             bg="#643181",
    342             fg="#F2DAFF",
    343             pady=6
    344         )
    345         self.header.pack(fill=tk.X)
    346         self.font_frame = tk.Frame(self.frame, bg="#1A181C")
    347         self.font_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10)
    348         self.font_label = tk.Label(
    349             self.font_frame,
    350             text="Font Size: ",
    351             justify=tk.LEFT,
    352             font=("Arial", str(self.settings["font_size"])),
    353             bg="#1A181C",
    354             fg="#F2DAFF",
    355             pady=2
    356         )
    357         self.font_label.pack(side=tk.LEFT)
    358         self.font_options = [12, 14, 16, 18, 20, 24, 32]
    359         self.font_dropdown = tk.StringVar()
    360         self.font_dropdown.set(self.settings["font_size"])
    361         self.font_menu = tk.OptionMenu(
    362             self.font_frame,
    363             self.font_dropdown,
    364             *self.font_options,
    365             command=self.modify_font
    366         )
    367         if sys.platform == "darwin":
    368             self.font_menu.config(bg="#1A181C", fg="#643181")
    369         else:
    370             self.font_menu.config(
    371                 bg="#1A181C",
    372                 fg="#643181",
    373                 highlightbackground="#643181",
    374                 activebackground="#F2DAFF",
    375                 activeforeground="#1A181C"
    376             )
    377             self.font_menu["menu"].config(
    378                 bg="#1A181C",
    379                 fg="#643181",
    380                 activebackground="#643181",
    381                 activeforeground="#F2DAFF"
    382             )
    383         self.font_menu.pack(side=tk.LEFT)
    384         self.dim_frame = tk.Frame(self.frame, bg="#1A181C")
    385         self.dim_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10)
    386         self.dim_label = tk.Label(
    387             self.dim_frame,
    388             text="Default window dimension: ",
    389             justify=tk.LEFT,
    390             font=("Arial", str(self.settings["font_size"])),
    391             bg="#1A181C",
    392             fg="#F2DAFF",
    393             pady=2
    394         )
    395         self.dim_label.pack(side=tk.LEFT)
    396         self.dim_options = [
    397             "Small",
    398             "Medium (Default)",
    399             "Large",
    400             "Extra Large"
    401         ]
    402         if self.settings["win_width"] == 500:
    403             self.dim_start_value = "Small"
    404         elif self.settings["win_width"] == 1000:
    405             self.dim_start_value = "Large"
    406         elif self.settings["win_width"] == 1200:
    407             self.dim_start_value = "Extra Large"
    408         else:
    409             self.dim_start_value = "Medium (Default)"
    410         self.dim_dropdown = tk.StringVar()
    411         self.dim_dropdown.set(self.dim_start_value)
    412         self.dim_menu = tk.OptionMenu(
    413             self.dim_frame,
    414             self.dim_dropdown,
    415             *self.dim_options,
    416             command=self.modify_dim
    417         )
    418         if sys.platform == "darwin":
    419             self.dim_menu.config(bg="#1A181C", fg="#643181")
    420         else:
    421             self.dim_menu.config(
    422                 bg="#1A181C",
    423                 fg="#643181",
    424                 highlightbackground="#643181",
    425                 activebackground="#F2DAFF",
    426                 activeforeground="#1A181C"
    427             )
    428             self.dim_menu["menu"].config(
    429                 bg="#1A181C",
    430                 fg="#643181",
    431                 activebackground="#643181",
    432                 activeforeground="#F2DAFF"
    433             )
    434         self.dim_menu.pack(side=tk.LEFT)
    435         self.update_frame = tk.Frame(self.frame, bg="#1A181C")
    436         self.update_frame.pack(side=tk.TOP, fill=tk.BOTH, pady=10)
    437         self.update_label = tk.Label(
    438             self.update_frame,
    439             text="Update Status: ",
    440             justify=tk.LEFT,
    441             font=("Arial", str(self.settings["font_size"])),
    442             bg="#1A181C",
    443             fg="#F2DAFF",
    444             pady=2
    445         )
    446         self.update_label.pack(side=tk.LEFT)
    447         self.update_bool = vc.update_available()
    448         if self.update_bool == "available":
    449             self.update_text = "Available"
    450             self.update_color = "#84D373"
    451         elif self.update_bool == "updated":
    452             self.update_text = "Up to date!"
    453             self.update_color = "#B1A5B8"
    454         elif self.update_bool == "dev":
    455             self.update_text = "Hello FIGBERT"
    456             self.update_color = "#643181"
    457         else:
    458             self.update_text = "Connection failed"
    459             self.update_color = "#FC142F"
    460         self.update_status = tk.Label(
    461             self.update_frame,
    462             text=self.update_text,
    463             justify=tk.LEFT,
    464             font=("Arial", str(self.settings["font_size"])),
    465             bg="#1A181C",
    466             fg=self.update_color,
    467             pady=2
    468         )
    469         self.update_status.pack(side=tk.LEFT)
    470         self.save_frame = tk.Frame(self.frame, bg="#1A181C", pady=5, padx=5)
    471         self.save_frame.pack(side=tk.BOTTOM, fill=tk.BOTH)
    472         if sys.platform == "darwin":
    473             self.save_button = tk.Button(
    474                 self.save_frame,
    475                 fg="#643181",
    476                 text="Save",
    477                 font=("Arial", self.settings["font_size"] - 2),
    478                 highlightthickness=5,
    479                 highlightbackground="#1A181C",
    480                 padx=10,
    481                 pady=2,
    482                 command=lambda: self.close_settings(self.settings_window)
    483             )
    484         else:
    485             self.save_button = tk.Button(
    486                 self.save_frame,
    487                 fg="#643181",
    488                 bg="#8A8A8A",
    489                 text="Save",
    490                 font=("Arial", self.settings["font_size"] - 2),
    491                 padx=10,
    492                 pady=2,
    493                 command=lambda: self.close_settings(self.settings_window)
    494             )
    495         self.save_button.pack(side=tk.LEFT)
    496         self.settings_window.protocol(
    497             "WM_DELETE_WINDOW",
    498             lambda: self.close_settings(self.settings_window)
    499         )
    500         self.settings_window.mainloop()
    501 
    502     def launcher(self, settings):
    503         self.launcher_window = tk.Toplevel()
    504         self.launcher_window.wm_title("figENC")
    505         self.canvas = tk.Canvas(
    506             self.launcher_window,
    507             height=settings["win_height"]/6,
    508             width=settings["win_width"]/1.5
    509         )
    510         self.canvas.pack(fill=tk.BOTH, expand=True)
    511         self.frame = tk.Frame(self.canvas, bg="#1A181C")
    512         self.frame.place(relwidth=1, relheight=1)
    513         self.header = tk.Label(
    514             self.frame,
    515             text="Loading application...",
    516             font=("Arial", (
    517                 settings["font_size"]-2 if settings["font_size"]-2 > 0 else 2
    518                 )
    519             ),
    520             bg="#1A181C",
    521             fg="#F2DAFF",
    522             pady=5
    523         )
    524         self.header.pack(side=tk.TOP)
    525         self.subheader = tk.Label(
    526             self.frame,
    527             text=self.pick_tip(),
    528             font=("Arial", settings["font_size"]-4),
    529             bg="#1A181C",
    530             fg="#B494C7"
    531         )
    532         self.subheader.pack(side=tk.TOP)
    533         self.button_frame = tk.Frame(self.frame, bg="#1A181C", pady=5)
    534         self.button_frame.pack(side=tk.TOP)
    535         if sys.platform == "darwin":
    536             self.launch_button = tk.Button(
    537                 self.button_frame,
    538                 fg="#643181",
    539                 text="Launch App",
    540                 font=("Arial", settings["font_size"]-6),
    541                 highlightthickness=5,
    542                 highlightbackground="#1A181C",
    543                 command=lambda: self.launch_app(root)
    544             )
    545             self.settings_button = tk.Button(
    546                 self.button_frame,
    547                 fg="#643181",
    548                 text="Settings",
    549                 font=("Arial", settings["font_size"]-6),
    550                 highlightbackground="#1A181C",
    551                 highlightthickness=5,
    552                 command=lambda: self.open_settings(self.launcher_window)
    553             )
    554         else:
    555             self.launch_button = tk.Button(
    556                 self.button_frame,
    557                 fg="#643181",
    558                 bg="#8A8A8A",
    559                 text="Launch App",
    560                 font=("Arial", settings["font_size"]-6),
    561                 command=lambda: self.launch_app(root)
    562             )
    563             self.settings_button = tk.Button(
    564                 self.button_frame,
    565                 fg="#643181",
    566                 bg="#8A8A8A",
    567                 text="Settings",
    568                 font=("Arial", settings["font_size"]-6),
    569                 command=lambda: self.open_settings(self.launcher_window)
    570             )
    571         self.launch_button.pack(side=tk.LEFT)
    572         self.settings_button.pack(side=tk.RIGHT)
    573         self.launcher_window.protocol(
    574             "WM_DELETE_WINDOW",
    575             lambda: self.full_shutdown(self.launcher_window, root)
    576         )
    577 
    578     def launch_app(self, root):
    579         """Deiconify the passed root window, destroy the launcher
    580         window and update the frame
    581         
    582         Keyword arguments:
    583         root -- the main app window
    584         """
    585         with open(self.settings_file) as settings_file:
    586             settings = json.load(settings_file)
    587         self.main_app(root, settings)
    588         root.deiconify()
    589         self.launcher_window.destroy()
    590 
    591 
    592     def reset(self):
    593         """Hide all elements of the main app GUI and reset the entered text"""
    594         self.file_frame.pack_forget()
    595         self.file_label.pack_forget()
    596         self.file_input.pack_forget()
    597         self.passcode_frame.pack_forget()
    598         self.passcode_label.pack_forget()
    599         self.passcode_instructions.pack_forget()
    600         self.reset_text(self.passcode_input)
    601         self.passcode_input.pack_forget()
    602         self.confirm_label.pack_forget()
    603         self.confirm_instructions.pack_forget()
    604         self.reset_text(self.confirm_input)
    605         self.confirm_input.pack_forget()
    606         self.save.pack_forget()
    607         self.save_label.pack_forget()
    608         self.save_instructions.pack_forget()
    609         self.save_input.pack_forget()
    610         self.type_frame.pack_forget()
    611         self.type_label.pack_forget()
    612         self.type_instructions.pack_forget()
    613         self.type_button_frame.pack_forget()
    614         self.rsa_radiobutton.pack_forget()
    615         self.mixed_radiobutton.pack_forget()
    616         self.submit.pack_forget()
    617 
    618     def reset_text(self, entry_widget):
    619         """Reset the string value of a tk.Entry object to an empty string
    620         
    621         Keyword arguments:
    622         entry_widget -- a tk.Entry object
    623         """
    624         entry_widget.delete(0,tk.END)
    625         entry_widget.insert(0,"")
    626 
    627     def setup(self, mode):
    628         """"Change the GUI to match the app mode,
    629         based on the user's action_list selection.
    630 
    631         Keyword arguments:
    632         mode -- an int (0-6) corresponding with the action_list selection
    633         """
    634         mode = mode[0]
    635         if mode == 0: #Encrypt with fresh keys (password locked)
    636             self.reset()
    637             self.file_frame.pack(fill="both")
    638             self.file_label.config(text="Filepath/s to the file/s to encrypt")
    639             self.file_label.pack()
    640             self.file_input.pack(fill="x")
    641             self.passcode_frame.pack(fill="both")
    642             self.passcode_label.config(text="Set private key passcode")
    643             self.passcode_label.pack()
    644             self.passcode_instructions.config(
    645                 text=(
    646                     "CRITICAL: DO NOT FORGET YOUR"
    647                     "PASSCODE.\nWITHOUT IT, "
    648                     "YOUR DATA WILL BE LOST."
    649                 )
    650             )
    651             self.passcode_instructions.pack()
    652             self.passcode_input.pack(fill="x")
    653             self.confirm_label.pack()
    654             self.confirm_instructions.pack()
    655             self.confirm_input.pack(fill="x")
    656             self.save.pack(fill="both")
    657             self.save_label.config(text="Save location for keys")
    658             self.save_label.pack()
    659             self.save_instructions.config(
    660                 text=(
    661                     "Save the keys to an empty folder, "
    662                     "and store them somewhere secure\n"
    663                     "If other key files exist in the same"
    664                     "folder, they will be overwritten"
    665                 )
    666             )
    667             self.save_instructions.pack()
    668             self.save_input.pack(fill="x")
    669             self.submit.config(text="Encrypt file/s")
    670             self.submit.pack(pady=10)
    671             self.crypto_mode = "key_enc"
    672             self.frame.update()
    673         elif mode == 1: #Encrypt with fresh keys (no password)
    674             self.reset()
    675             self.file_frame.pack(fill="both")
    676             self.file_label.config(text="Filepath/s to the file/s to encrypt")
    677             self.file_label.pack()
    678             self.file_input.pack(fill="x")
    679             self.save.pack(fill="both")
    680             self.save_label.config(text="Save location for keys")
    681             self.save_label.pack()
    682             self.save_instructions.config(
    683                 text=(
    684                     "Save the keys to an empty folder, "
    685                     "and store them somewhere secure\n"
    686                     "If other key files exist in the same"
    687                     "folder, they will be overwritten"
    688                 )
    689             )
    690             self.save_instructions.pack()
    691             self.save_input.pack(fill="x")
    692             self.submit.config(text="Encrypt file/s")
    693             self.submit.pack(pady=10)
    694             self.crypto_mode = "weak_key_enc"
    695             self.frame.update()
    696         elif mode == 2: #Encrypt with generated keys
    697             self.reset()
    698             self.file_frame.pack(fill="both")
    699             self.file_label.config(text="Filepath/s to the file/s to encrypt")
    700             self.file_label.pack()
    701             self.file_input.pack(fill="x")
    702             self.save.pack(fill="both")
    703             self.save_label.config(text="Key location")
    704             self.save_label.pack()
    705             self.save_instructions.config(
    706                 text="Filepath to matching key trio"
    707             )
    708             self.save_instructions.pack()
    709             self.save_input.pack(fill="x")
    710             self.submit.config(text="Encrypt file/s")
    711             self.submit.pack(pady=10)
    712             self.crypto_mode = "enc"
    713             self.frame.update()
    714         elif mode == 3: #Decrypt with generated keys (password locked)
    715             self.reset()
    716             self.file_frame.pack(fill="both")
    717             self.file_label.config(text="Filepath/s to the file/s to decrypt")
    718             self.file_label.pack()
    719             self.file_input.pack(fill="x")
    720             self.passcode_frame.pack(fill="both")
    721             self.passcode_label.config(text="Private key passcode")
    722             self.passcode_label.pack()
    723             self.passcode_instructions.config(
    724                 text=(
    725                     "Passcode must be the same "
    726                     "passcode used when the keys were created"
    727                 )
    728             )
    729             self.passcode_instructions.pack()
    730             self.passcode_input.pack(fill="x")
    731             self.confirm_label.pack()
    732             self.confirm_instructions.pack()
    733             self.confirm_input.pack(fill="x")
    734             self.save.pack(fill="both")
    735             self.save_label.config(text="Key location")
    736             self.save_label.pack()
    737             self.save_instructions.config(
    738                 text="Filepath to matching key trio"
    739             )
    740             self.save_instructions.pack()
    741             self.save_input.pack(fill="x")
    742             self.submit.config(text="Decrypt file/s")
    743             self.submit.pack(pady=10)
    744             self.crypto_mode = "dec"
    745             self.frame.update()
    746         elif mode == 4: #Decrypt with generated keys (no password)
    747             self.reset()
    748             self.file_frame.pack(fill="both")
    749             self.file_label.config(text="Filepath/s to the file/s to decrypt")
    750             self.file_label.pack()
    751             self.file_input.pack(fill="x")
    752             self.save.pack(fill="both")
    753             self.save_label.config(text="Key location")
    754             self.save_label.pack()
    755             self.save_instructions.config(
    756                 text="Filepath to matching key trio"
    757             )
    758             self.save_instructions.pack()
    759             self.save_input.pack(fill="x")
    760             self.submit.config(text="Decrypt file/s")
    761             self.submit.pack(pady=10)
    762             self.crypto_mode = "weak_dec"
    763             self.frame.update()
    764         elif mode == 5: #Only create fresh keys (password locked)
    765             self.reset()
    766             self.passcode_frame.pack(fill="both")
    767             self.passcode_label.config(text="Set private key passcode")
    768             self.passcode_label.pack()
    769             self.passcode_instructions.config(
    770                 text=(
    771                     "CRITICAL: DO NOT FORGET YOUR PASSCODE.\nWITHOUT IT, "
    772                     "YOUR DATA WILL BE LOST."
    773                 )
    774             )
    775             self.passcode_instructions.pack()
    776             self.passcode_input.pack(fill="x")
    777             self.confirm_label.pack()
    778             self.confirm_instructions.pack()
    779             self.confirm_input.pack(fill="x")
    780             self.save.pack(fill="both")
    781             self.save_label.config(text="Save location for keys")
    782             self.save_label.pack()
    783             self.save_instructions.config(
    784                 text=(
    785                     "Save the keys to an empty folder, "
    786                     "and store them somewhere secure\n"
    787                     "If other key files exist in the same"
    788                     "folder, they will be overwritten"
    789                 )
    790             )
    791             self.save_instructions.pack()
    792             self.save_input.pack(fill="x")
    793             self.type_frame.pack()
    794             self.type_label.pack()
    795             self.type_instructions.pack()
    796             self.type_button_frame.pack()
    797             self.rsa_radiobutton.pack(side=tk.LEFT)
    798             self.mixed_radiobutton.pack(side=tk.LEFT)
    799             self.submit.config(text="Create keys")
    800             self.submit.pack(pady=10)
    801             self.crypto_mode = "just_key"
    802             self.frame.update()
    803         elif mode == 6: #Only create fresh keys (no password)
    804             self.reset()
    805             self.save.pack(fill="both")
    806             self.save_label.config(text="Save location for keys")
    807             self.save_label.pack()
    808             self.save_instructions.config(
    809                 text=(
    810                     "Save the keys to an empty folder, "
    811                     "and store them somewhere secure\n"
    812                     "If other key files exist in the same"
    813                     "folder, they will be overwritten"
    814                 )
    815             )
    816             self.save_instructions.pack()
    817             self.save_input.pack(fill="x")
    818             self.type_frame.pack()
    819             self.type_label.pack()
    820             self.type_instructions.pack()
    821             self.type_button_frame.pack()
    822             self.rsa_radiobutton.pack(side=tk.LEFT)
    823             self.mixed_radiobutton.pack(side=tk.LEFT)
    824             self.submit.config(text="Create keys")
    825             self.submit.pack(pady=10)
    826             self.crypto_mode = "weak_key"
    827             self.frame.update()
    828 
    829     def go(
    830         self,
    831         mode,
    832         key_dir=None,
    833         target_files=None,
    834         passkey=None,
    835         passcheck=None
    836     ):
    837         """Perform the action corresponding to the mode,
    838         using the input data from the user, after checking the validity
    839         of the filepaths.
    840 
    841         Keyword arguments:
    842         mode -- the mode defined by setup() from action_list
    843         save_folder -- the folder where the keys are or will be stored
    844         target_file -- the file to encrypt or decrypt
    845         passkey - the access code to the RSA keys that have them
    846         passcheck - the access code to the RSA keys that have them confirmed,
    847         to prevent spelling errors.
    848         """
    849         if mode == "key_enc" and check.key_enc(
    850             target_files,
    851             passkey,
    852             passcheck,
    853             key_dir
    854         ):
    855             key.key_manager(target_files, key_dir, passkey)
    856             enc_manager(target_files, key_dir)
    857         elif mode == "weak_key_enc" and check.weak_key_enc(
    858             target_files,
    859             key_dir
    860         ):
    861             key.key_manager(target_files, key_dir, passkey)
    862             enc_manager(target_files, key_dir)
    863         elif mode == "enc" and check.enc(target_files, key_dir):
    864             enc_manager(target_files, key_dir)
    865         elif mode == "dec" and check.dec(
    866             target_files,
    867             passkey,
    868             passcheck,
    869             key_dir
    870         ):
    871             dec_manager(target_files, key_dir, passkey)
    872         elif mode == "weak_dec" and check.weak_dec(target_files, key_dir):
    873             dec_manager(target_files, key_dir, passkey)
    874         elif mode == "just_key" and check.key(key_dir, passkey, passcheck):
    875             key.just_key_manager(self.type_control.get(), key_dir, passkey)
    876         elif mode == "weak_key" and check.weak_key(key_dir):
    877             key.just_key_manager(self.type_control.get(), key_dir, passkey)
    878 
    879     def pick_tip(self):
    880         """Return a random string from the tips.json file"""
    881         with open(self.tips_file) as source:
    882             self.tips = json.load(source)
    883         self.tip = "Tip: " + choice(self.tips)
    884         return self.tip
    885 
    886     def close_settings(self, settings_window):
    887         """Destroy the settings toplevel and deiconify the root window
    888         
    889         Keyword arguments:
    890         settings_window -- the window of the app to destroy
    891         root -- the window of the app to deiconify()
    892         """
    893         settings_window.destroy()
    894         with open(self.settings_file) as settings_file:
    895             settings = json.load(settings_file)
    896         self.launcher(settings)
    897 
    898     def full_shutdown(self, launcher_window, root):
    899         """Destroy the launcher window and the root window
    900         
    901         Keyword arguments:
    902         launcher_window -- the window of the app to destroy
    903         root -- another app to destroy
    904         """
    905         launcher_window.destroy()
    906         root.destroy()
    907 
    908     def modify_font(self, value):
    909         """Change the value of the font_size key in the self.settings variable
    910         and export settings to file.
    911         
    912         Keyword arguments:
    913         value -- the int to which the self.settings variable will change
    914         """
    915         self.settings["font_size"] = value
    916         with open(self.settings_file, "w") as fl:
    917             json.dump(self.settings, fl, indent=4, sort_keys=True)
    918 
    919     def modify_dim(self, value):
    920         """Change the value of the win_width key in the self.settings
    921         variable and export settings to file.
    922         
    923         Keyword arguments:
    924         value -- an int represeting the new width of the window
    925         """
    926         if value == "Small":
    927             dim = 500
    928         elif value == "Large":
    929             dim = 1000
    930         elif value == "Extra Large":
    931             dim = 1200
    932         else:
    933             dim = 700
    934         self.settings["win_width"] = dim
    935         self.settings["win_height"] = dim
    936         with open(self.settings_file, "w") as fl:
    937             json.dump(self.settings, fl, indent=4, sort_keys=True)
    938 
    939     def toggle_pass(self, *args):
    940         """Toogle the password fields between showing the characters and
    941         hiding them.
    942         """
    943         if self.show_pass:
    944             self.passcode_input.config(show="")
    945             self.confirm_input.config(show="")
    946             self.show_pass = not self.show_pass
    947         else:
    948             self.passcode_input.config(show="*")
    949             self.confirm_input.config(show="*")
    950             self.show_pass = not self.show_pass
    951     
    952     def select_filepaths(self):
    953         """Set the cryptofilepath variable to the tuple result of a
    954         tkinter filenames filedialog
    955         """
    956         self.crypto_filepaths = filedialog.askopenfilenames()
    957         self.file_input.config(
    958             text=self.crypto_filepaths[0] if len(self.crypto_filepaths) == 1 else self.crypto_filepaths[0] + "..."
    959         )
    960 
    961     def select_key_dir(self):
    962         """Set the key_paths variable to the string result of a tkinter
    963         askdirectory filedialog. If on MacOS, the start directory will
    964         be home folder of the current user.
    965         """
    966         if sys.platform == "darwin":
    967             self.key_paths = filedialog.askdirectory(initialdir="/Users/%s"%getpass.getuser())
    968         else:
    969             self.key_paths = filedialog.askdirectory()
    970         self.save_input.config(text=self.key_paths)
    971 
    972 
    973 if __name__ == "__main__":
    974     root = tk.Tk()
    975     App(root)
    976     if sys.platform == "darwin":
    977         icon_path = find_path('icon-windowed.icns')
    978     else:
    979         icon_path = find_path('icon-windowed.ico')
    980     root.iconbitmap(icon_path)
    981     root.mainloop()