verify unlock key against hash on disk
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -12,8 +12,7 @@ type UnlockInput struct {
|
||||
SecretKey string `json:"secretKey"`
|
||||
}
|
||||
|
||||
// receive secret key and store it using the Key model
|
||||
|
||||
// Unlock receives secret key and store it in memory
|
||||
func Unlock(c *gin.Context) {
|
||||
var input UnlockInput
|
||||
|
||||
|
@@ -1,11 +1,63 @@
|
||||
package models
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
const hashFileName = "verify.hash"
|
||||
|
||||
// TODO: Look at using shamir's secret sharing to distribute components of the secret key
|
||||
var secretKey []byte
|
||||
var secretReceived bool
|
||||
|
||||
func getHashFilePath() (string, error) {
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
filePath := filepath.Join(dir, hashFileName)
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
func storeKeyHash(plaintext string, filePath string) error {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(plaintext), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.WriteFile(filePath, hash, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Bcrypt hash stored in file:", filePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func compareHashWithPlaintext(plaintext string, filePath string) (bool, error) {
|
||||
hashBytes, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(hashBytes, []byte(plaintext))
|
||||
if err != nil {
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
return false, nil // Passwords don't match
|
||||
}
|
||||
return false, err // Other error occurred
|
||||
}
|
||||
|
||||
return true, nil // Passwords match
|
||||
}
|
||||
|
||||
func ReceiveKey(key string) error {
|
||||
|
||||
// confirm that the key is 32 bytes long exactly
|
||||
@@ -13,9 +65,26 @@ func ReceiveKey(key string) error {
|
||||
return errors.New("secret key provided is not exactly 32 bytes long")
|
||||
}
|
||||
|
||||
// Store the secret key so that we can access it when encrypting/decrypting
|
||||
// TODO hash the secret key and store it on disk so we can verify if correct secret key is received
|
||||
filePath, _ := getHashFilePath()
|
||||
|
||||
if filePath != "" {
|
||||
// File already exists, compare received key with hash in file
|
||||
compare, err := compareHashWithPlaintext(key, filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to verify secret key: '%s'", err.Error())
|
||||
}
|
||||
if !compare {
|
||||
return errors.New("secret key is not correct")
|
||||
}
|
||||
} else {
|
||||
storeKeyHash(key, filePath)
|
||||
}
|
||||
|
||||
// Store the secret key in memory so that we can access it when encrypting/decrypting
|
||||
secretKey = []byte(key)
|
||||
secretReceived = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -424,11 +424,3 @@ func UserCheckIfAdmin(userId int) bool {
|
||||
|
||||
return u.Admin
|
||||
}
|
||||
|
||||
func UserGetSafe() {
|
||||
|
||||
}
|
||||
|
||||
// need a way of checking what safe a user has access to
|
||||
// if they only have access to one then that is easy
|
||||
// if they are an admin then they have access to everything
|
||||
|
Reference in New Issue
Block a user