/* 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 }