loading and decryption works

This commit is contained in:
2025-08-17 10:57:54 -07:00
parent fd0732e6f0
commit 33938a31e8

67
main.go
View File

@@ -3,6 +3,7 @@ package main
import ( import (
// "database/sql" // "database/sql"
"bufio" "bufio"
"bytes"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/pbkdf2" "crypto/pbkdf2"
@@ -16,12 +17,14 @@ import (
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
"os"
"os/exec"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
"os"
"golang.org/x/term" "golang.org/x/term"
_ "modernc.org/sqlite" _ "modernc.org/sqlite"
) )
@@ -35,6 +38,14 @@ var (
scanner bufio.Scanner scanner bufio.Scanner
) )
type Note struct {
Body string `json:"body"`
Color int64 `json:"color"`
Date string `json:"date"`
ID string `json:"id"`
Title string `json:"title"`
}
func check(err error, format string, a ...any) bool { func check(err error, format string, a ...any) bool {
if err != nil { if err != nil {
log.Fatalf(format, a, err) log.Fatalf(format, a, err)
@@ -43,7 +54,7 @@ func check(err error, format string, a ...any) bool {
return true return true
} }
func ReadPassword() (string, error) { func readPassword() (string, error) {
stdin := int(syscall.Stdin) stdin := int(syscall.Stdin)
oldState, err := term.GetState(stdin) oldState, err := term.GetState(stdin)
if err != nil { if err != nil {
@@ -68,6 +79,22 @@ func ReadPassword() (string, error) {
return string(password), nil return string(password), nil
} }
func pkcs7strip(data []byte, blockSize int) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("pkcs7: Data is empty")
}
if length%blockSize != 0 {
return nil, errors.New("pkcs7: Data is not block-aligned")
}
padLen := int(data[length-1])
ref := bytes.Repeat([]byte{byte(padLen)}, padLen)
if padLen > blockSize || padLen == 0 || !bytes.HasSuffix(data, ref) {
return nil, errors.New("pkcs7: Invalid padding")
}
return data[:length-padLen], nil
}
func main() { func main() {
scanner = *bufio.NewScanner(os.Stdin) scanner = *bufio.NewScanner(os.Stdin)
home := os.Getenv("HOME") home := os.Getenv("HOME")
@@ -116,13 +143,22 @@ func main() {
err = json.Unmarshal(body, &jsonBody) err = json.Unmarshal(body, &jsonBody)
check(err, "Error unmarshalling response body: %s") check(err, "Error unmarshalling response body: %s")
decryptedBody := make([]string, len(jsonBody)) fzf := exec.Command("fzf")
stdin, err := fzf.StdinPipe()
check(err, "Error executing fzf: %s")
check(fzf.Start(), "Error starting fzf: %s")
decryptedBody := make([]Note, len(jsonBody))
for i := range len(jsonBody) { for i := range len(jsonBody) {
decryptedBody[i] = decrypt(jsonBody[i][1], password) err := json.Unmarshal([]byte(decrypt(jsonBody[i][1], password)), &decryptedBody[i])
jsonDecryptedBody := json.Marshal(decryptedBody) if err != nil {
decryptedBody[i] continue
}
if len(decryptedBody[i].Title) > 0 && len(decryptedBody[i].Body) > 0 {
fmt.Fprintf(stdin, "%s | %s\n", decryptedBody[i].Title, strings.ReplaceAll(decryptedBody[i].Body, "\n", " "))
}
} }
fmt.Println(decryptedBody) fzf.Wait()
default: default:
login() login()
@@ -139,12 +175,12 @@ func login() {
fmt.Print("Username: ") fmt.Print("Username: ")
scanner.Scan() scanner.Scan()
username = scanner.Text() username = url.QueryEscape(scanner.Text())
fmt.Print("Password: ") fmt.Print("Password: ")
passwordBytes, err := ReadPassword() passwordBytes, err := readPassword()
password = string(passwordBytes)
check(err, "Error reading user input (password): %s") check(err, "Error reading user input (password): %s")
password = url.QueryEscape(string(passwordBytes))
jsonData, err := json.Marshal([]string{serverAddress, username, password}) jsonData, err := json.Marshal([]string{serverAddress, username, password})
check(err, "Error marshalling server address and credentials: %s") check(err, "Error marshalling server address and credentials: %s")
@@ -163,7 +199,6 @@ func decrypt(data string, password string) string {
check(err, "Error decoding base64 data: %s") check(err, "Error decoding base64 data: %s")
if len(dataBytes) < 32 { if len(dataBytes) < 32 {
fmt.Printf("Not enough data (got %d bytes, expected at least 32)\n", len(dataBytes))
return "" return ""
} }
@@ -179,9 +214,15 @@ func decrypt(data string, password string) string {
key, err := pbkdf2.Key(sha256.New, password, salt, 65536, 32) key, err := pbkdf2.Key(sha256.New, password, salt, 65536, 32)
check(err, "Error deriving pbkdf2-sha256 key from password: %s") check(err, "Error deriving pbkdf2-sha256 key from password: %s")
block, err := aes.NewCipher(key) block, err := aes.NewCipher(key)
check(err, "Error creating AES key: %s")
mode := cipher.NewCBCDecrypter(block, iv) mode := cipher.NewCBCDecrypter(block, iv)
plaintext := make([]byte, len(ciphertext)) plaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(plaintext, ciphertext) mode.CryptBlocks(plaintext, ciphertext)
return string(plaintext)
strippedPlaintext, err := pkcs7strip(plaintext, 16)
if err != nil {
return ""
}
return string(strippedPlaintext)
} }