wal-g

Форк
0
/
crypto.go 
85 строк · 2.0 Кб
1
package crypto
2

3
import (
4
	"bytes"
5
	"encoding/json"
6
	"fmt"
7
	"os"
8
	"os/exec"
9
	"os/user"
10
	"path/filepath"
11
	"strings"
12

13
	"github.com/pkg/errors"
14
	"github.com/wal-g/tracelog"
15
)
16

17
type GpgKeyExportError struct {
18
	error
19
}
20

21
func NewGpgKeyExportError(text string) GpgKeyExportError {
22
	return GpgKeyExportError{errors.Errorf("Got error while exporting gpg key: '%s'", text)}
23
}
24

25
func (err GpgKeyExportError) Error() string {
26
	return fmt.Sprintf(tracelog.GetErrorFormatter(), err.error)
27
}
28

29
const GpgBin = "gpg"
30

31
// CachedKey is the data transfer object describing format of key ring cache
32
type CachedKey struct {
33
	KeyID string `json:"keyId"`
34
	Body  []byte `json:"body"`
35
}
36

37
// TODO : unit tests
38
// Here we read armored version of Key by calling GPG process
39
func GetPubRingArmor(keyID string) ([]byte, error) {
40
	var cache CachedKey
41
	var cacheFilename string
42

43
	usr, err := user.Current()
44
	if err == nil {
45
		cacheFilename = filepath.Join(usr.HomeDir, ".walg_key_cache")
46
		file, err := os.ReadFile(cacheFilename)
47
		// here we ignore whatever error can occur
48
		if err == nil {
49
			err = json.Unmarshal(file, &cache)
50
			tracelog.ErrorLogger.PrintOnError(err)
51
			if err == nil && cache.KeyID == keyID && len(cache.Body) > 0 { // don't return an empty cached value
52
				return cache.Body, nil
53
			}
54
		}
55
	}
56

57
	cmd := exec.Command(GpgBin, "-a", "--export", keyID)
58
	var stderr bytes.Buffer
59
	cmd.Stderr = &stderr
60
	out, err := cmd.Output()
61
	if err != nil {
62
		return nil, err
63
	}
64
	if stderr.Len() > 0 { // gpg -a --export <key-id> reports error on stderr and exits == 0 if the key isn't found
65
		return nil, NewGpgKeyExportError(strings.TrimSpace(stderr.String()))
66
	}
67

68
	cache.KeyID = keyID
69
	cache.Body = out
70
	marshal, err := json.Marshal(&cache)
71
	if err == nil && len(cacheFilename) > 0 {
72
		err = os.WriteFile(cacheFilename, marshal, 0644)
73
		tracelog.ErrorLogger.PrintOnError(err)
74
	}
75

76
	return out, nil
77
}
78

79
func GetSecretRingArmor(keyID string) ([]byte, error) {
80
	out, err := exec.Command(GpgBin, "-a", "--export-secret-key", keyID).Output()
81
	if err != nil {
82
		return nil, err
83
	}
84
	return out, nil
85
}
86

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.