Select Git revision
createManagerKey.go
createManagerKey.go 3.06 KiB
/*
Skills
Copyright (C) 2023 GérardMeunier
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package main
// Creates the key the manager must type when runSkillsC starts.
import (
F "path/filepath"
M "git.duniter.org/gerard94/util/misc"
R "git.duniter.org/gerard94/util/resources"
"crypto/aes"
"errors"
"flag"
"fmt"
"encoding/hex"
"os"
"strings"
"text/scanner"
"crypto/sha256"
)
const (
keySize = 256 / 8
keyPath = "skillsclient/managerKey.txt"
)
var (
keyP = R.FindDir(keyPath)
privKey string
masterKeyPath string
)
func getMasterKey (key *[]byte) bool {
f, err := os.Open(masterKeyPath)
if err != nil {
fmt.Fprintln(os.Stderr, "Incorrect path to Master Key (mk)")
return false
}
defer f.Close()
s := new(scanner.Scanner)
s.Init(f)
s.Error = func(s *scanner.Scanner, msg string) {M.Halt(errors.New("File " + masterKeyPath + " incorrect"), 100)}
s.Mode = scanner.ScanStrings
s.Scan()
ss := s.TokenText()
M.Assert(ss[0] == '"' && ss[len(ss) - 1] == '"', ss, 101)
k, err := hex.DecodeString(ss[1:len(ss) - 1]); M.Assert(err == nil, err, 102)
M.Assert(len(k) == keySize, "key has wrong length:", k, 103)
*key = k
return true
}
func storeKeys (key1, key2 []byte, keyPath string) bool {
f, err := os.Create(keyPath)
if err != nil {
return false
}
defer f.Close()
fmt.Fprint(f, "\"", hex.EncodeToString(key1), "\"\n")
fmt.Fprint(f, "\"", hex.EncodeToString(key2), "\"")
return true
}
func main () {
privKey = strings.TrimSpace(privKey)
if privKey == "" || masterKeyPath == "" {
flag.PrintDefaults()
return
}
var mk []byte
if !getMasterKey(&mk) {
return
}
h := sha256.New()
h.Write([]byte(privKey))
mh := h.Sum(nil)
M.Assert(len(mh) == keySize, len(mh), 103)
b, err := aes.NewCipher(mh); M.Assert(err == nil, err, 104)
bSize := b.BlockSize()
M.Assert(keySize % bSize == 0 && keySize / bSize > 0, "bSize =", bSize, 105)
manK := make([]byte, keySize)
for i := 0; i < keySize; i += bSize {
b.Encrypt(manK[i: i + bSize], mk[i: i + bSize])
}
h.Reset()
h.Write([]byte(mk))
mkh := h.Sum(nil)
if storeKeys(manK, mkh, keyP) {
fmt.Fprintln(os.Stdout, "Your private key has been recorded")
} else {
fmt.Fprintln(os.Stderr, "Error: unable to create", keyP)
}
}
func init () {
d, err := F.Abs(F.Dir(keyP)); M.Assert(err == nil, err, 100)
os.MkdirAll(d, 0o777)
flag.StringVar(&privKey, "k", "", "Private Key")
flag.StringVar(&masterKeyPath, "mk", "", "Path to Master Key")
flag.Parse()
}