git-secure-export

Experimental tooling for encrypting the git-fast-export(1) output

git clone https://git.8pit.net/git-secure-export.git

 1package export
 2
 3import (
 4	"crypto/rand"
 5	"errors"
 6	"golang.org/x/crypto/nacl/secretbox"
 7	"io"
 8)
 9
10const (
11	// From the secretbox example code.
12	nonceSize = 24
13
14	// From `go doc secretbox`:
15	//  If in doubt, 16KB is a reasonable chunk size.
16	maxChunkSize = 16 * 1024
17)
18
19func Encrypt(in io.Reader, inLen int64, out io.Writer, key *[32]byte) (int, error) {
20	nwritten := 0
21	remaining := inLen
22
23	for remaining > 0 {
24		// From `go doc secretbox`:
25		//   You must use a different nonce for each message you encrypt
26		//   with the same key. Since the nonce here is 192 bits long, a
27		//   random value provides a sufficiently small probability of
28		//   repeats.
29		var nonce [nonceSize]byte
30		if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
31			return nwritten, err
32		}
33
34		chunckLen := min(maxChunkSize, remaining)
35		remaining -= chunckLen
36
37		plain := make([]byte, chunckLen)
38		_, err := io.ReadFull(in, plain)
39		if err != nil {
40			return nwritten, err
41		}
42
43		cipher := secretbox.Seal(nonce[:], plain, &nonce, key)
44		n, err := out.Write(cipher)
45		if err != nil {
46			return nwritten, err
47		}
48
49		nwritten += n
50	}
51
52	return nwritten, nil
53}
54
55func Decrypt(in io.Reader, inLen int64, out io.Writer, key *[32]byte) (int, error) {
56	nwritten := 0
57	remaining := inLen
58
59	for remaining > nonceSize {
60		var nonce [nonceSize]byte
61		if _, err := io.ReadFull(in, nonce[:]); err != nil {
62			return nwritten, err
63		}
64		remaining -= nonceSize
65
66		chunckLen := min(maxChunkSize, remaining)
67		remaining -= chunckLen
68
69		chunck := make([]byte, chunckLen)
70		if _, err := io.ReadFull(in, chunck); err != nil {
71			return nwritten, err
72		}
73
74		decrypted, ok := secretbox.Open(nil, chunck, &nonce, key)
75		if !ok {
76			return nwritten, errors.New("decryption error")
77		}
78		n, err := out.Write(decrypted)
79		if err != nil {
80			return nwritten, err
81		}
82
83		nwritten += n
84	}
85
86	return nwritten, nil
87}