Browse Source

In progress. Not currently working

Simon Watson 2 years ago
parent
commit
20e696536c
1 changed files with 55 additions and 10 deletions
  1. 55 10
      fin-lisp.lisp

+ 55 - 10
fin-lisp.lisp

@@ -1,6 +1,8 @@
-(ql:quickload "cl-store")
+;;;(ql:quickload "cl-store")
+(ql:quickload "yason")
 (ql:quickload "cl-ppcre")
 (ql:quickload "unix-opts")
+(ql:quickload "ironclad")
 
 ;;; Features
 ;;; - Import records from old .txt format
@@ -57,8 +59,47 @@
 (defun reload ()
   (load "~/Repos/fin-lisp/fin-lisp.lisp"))
 
+(defun wfile (file-content file-path)
+  (alexandria:write-string-into-file
+   (concatenate 'string file-content) file-path :if-exists :overwrite
+						:if-does-not-exist :create))
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Encryption stuff ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;; See: https://www.cliki.net/Ironclad
+
+;;; Return cipher when provided key
+(defun get-cipher (key)
+  (ironclad:make-cipher
+   :blowfish
+   :mode :ecb
+   :key (ironclad:ascii-string-to-byte-array key)))
+
+;;; First serialize the file,
+;;; then encrypt it from disk
+(defun encrypt-records (key filename)
+  (let ((cipher (get-cipher key))
+	(file-content (uiop:read-file-string filename)))
+    (let ((content (ironclad:ascii-string-to-byte-array file-content)))
+      (ironclad:encrypt-in-place cipher content)
+      (wfile
+       (write-to-string (ironclad:octets-to-integer content))
+       (concatenate 'string filename ".enc")))))
+
+(defun decrypt-records (key filename)
+  (let ((cipher (get-cipher key))
+	(file-content (uiop:read-file-string filename)))
+    (let ((content (ironclad:integer-to-octets (parse-integer file-content))))
+      (ironclad:decrypt-in-place cipher content)
+      (coerce (mapcar #'code-char (coerce content 'list)) 'string))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; End Encryption Stuff ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defun reset-records ()
-  (setf *records* (make-hash-table :test 'equalp)))
+  (setf *records* (make-hash-table :test 'equal)))
   
 ;; Called like: (add-month '202107)
 (defun add-month (month-key)
@@ -97,17 +138,20 @@
       (format t "~a : ~a~C" exp-key (gethash exp-key month-hash) #\linefeed))))
 
 ;;; Dump all records.
-;;; This will also be used for data serialization at some point
 (defun dump-records ()
   (let ((record-key-list (loop for key being the hash-keys of *records* collect key)))
     (dolist (month-key record-key-list) (dump-month month-key))))
 
-(defun serialize-records (filename)
-  (cl-store:store *records* filename))
+(defun serialize-records (key filename)
+  (with-open-file (stream filename
+			  :direction :output
+			  :if-exists :overwrite
+			  :if-does-not-exist :create)
+    (yason:encode *records* stream))
+  (encrypt-records key filename))
 
-(defun deserialize-records (filename)
-  ;(setf *records* (cl-store:restore (pathname filename))))
-  (setf *records* (cl-store:restore filename)))
+(defun deserialize-records (key filename)
+  
 
 ;; Import records from old perl version (plaintext file)
 (defun import-records (filename)
@@ -168,7 +212,8 @@
 	 "Invalid month"))
     (if (string= answer "3")
 	(generic-handler
-	 (serialize-records (prompt-read "Enter filename"))
+	 (serialize-records (prompt-read "Enter encryption key")
+			    (prompt-read "Enter filename"))
 	 "Serialization error or invalid filename"))
     (if (string= answer "4")
 	(generic-handler
@@ -202,5 +247,5 @@
     (when-option (matches :interactive-mode)
       (progn
 	(interactive-mode)
-	(quit)))))
+	(quit))))))