62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
/* SPDX-License-Identifier: GPL-2.0
|
|
*
|
|
* Copyright (C) 2021 Jason A. Donenfeld. All Rights Reserved.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
const privateKeyCacheFile = "./private-key.cache"
|
|
|
|
func loadCachedPrivateKey() ([]byte, error) {
|
|
bytes, err := os.ReadFile(privateKeyCacheFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
log.Println("Loading cached private key from file")
|
|
privateKeyB64 := strings.TrimSpace(string(bytes))
|
|
privateKey, err := base64.StdEncoding.DecodeString(privateKeyB64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(privateKey) != 32 {
|
|
return nil, errors.New("invalid private key")
|
|
}
|
|
return privateKey, nil
|
|
}
|
|
|
|
func saveCachedPrivateKey(privateKey []byte) error {
|
|
if len(privateKey) != 32 {
|
|
return errors.New("invalid private key")
|
|
}
|
|
return os.WriteFile(privateKeyCacheFile, []byte(base64.StdEncoding.EncodeToString(privateKey)+"\n"), 0600)
|
|
}
|
|
|
|
func loadOrGeneratePrivateKey() ([]byte, error) {
|
|
privateKey, err := loadCachedPrivateKey()
|
|
if err == nil {
|
|
return privateKey, nil
|
|
}
|
|
log.Println("Generating new private key")
|
|
var k [32]byte
|
|
_, err = rand.Read(k[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
k[0] &= 248
|
|
k[31] = (k[31] & 127) | 64
|
|
err = saveCachedPrivateKey(k[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return k[:], nil
|
|
}
|