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"`
|
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) {
|
func Unlock(c *gin.Context) {
|
||||||
var input UnlockInput
|
var input UnlockInput
|
||||||
|
|
||||||
|
@@ -1,11 +1,63 @@
|
|||||||
package models
|
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
|
// TODO: Look at using shamir's secret sharing to distribute components of the secret key
|
||||||
var secretKey []byte
|
var secretKey []byte
|
||||||
var secretReceived bool
|
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 {
|
func ReceiveKey(key string) error {
|
||||||
|
|
||||||
// confirm that the key is 32 bytes long exactly
|
// 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")
|
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)
|
secretKey = []byte(key)
|
||||||
secretReceived = true
|
secretReceived = true
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -424,11 +424,3 @@ func UserCheckIfAdmin(userId int) bool {
|
|||||||
|
|
||||||
return u.Admin
|
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