-
Notifications
You must be signed in to change notification settings - Fork 9
/
digest.go
136 lines (115 loc) · 3.65 KB
/
digest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2017 Debpkg authors. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package debpkg
import (
"bytes"
"crypto"
"crypto/md5"
"crypto/sha1"
"fmt"
"hash"
"io"
"os"
"time"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/clearsign"
"golang.org/x/crypto/openpgp/packet"
)
const digestDefaultHash = crypto.SHA1
const digestVersion = 4
const digestRole = "builder"
// Digest file for GPG signing
type digest struct {
plaintext string // Plaintext package digest (empty when unsigned)
clearsign string // GPG clearsigned package digest (empty when unsigned)
signer string // Name <email>
date string // Mon Jan 2 15:04:05 2006 (time.ANSIC)
files string // Multiple "\t<md5sum> <sha1sum> <size> <filename>"
// E.g:
// 3cf918272ffa5de195752d73f3da3e5e 7959c969e092f2a5a8604e2287807ac5b1b384ad 4 debian-binary
// 79bb73dbb522dc1a2dd1b9c2ec89fc79 26d29d15aad5c0e051d07571e28da2bc0009707e 366 control.tar.gz
// e1a6e48c95a760170029ef7872cec994 e02ed99e5c4fd847bde12b4c2c30dd814b26ec27 136 data.tar.gz
}
// Create unsigned digest file at toplevel of deb package
// NOTE: the deb.digest.version and deb.digest.role are set in this function!
func createDigestFileString(deb *DebPkg) string {
const digestFileTmpl = `Version: %d
Signer: %s
Date: %s
Role: %s
Files:
%s`
// debian-binary
md5sum, _ := digestCalcDataHash(bytes.NewBuffer([]byte(deb.debianBinary)), md5.New())
sha1sum, _ := digestCalcDataHash(bytes.NewBuffer([]byte(deb.debianBinary)), sha1.New())
deb.digest.files += fmt.Sprintf("\t%x %x %d %s\n",
md5sum,
sha1sum,
len(deb.debianBinary),
"debian-binary")
deb.digestAddFile("control.tar.gz", deb.control.tgz.Name(), deb.control.tgz.Size())
deb.digestAddFile("data.tar.gz", deb.data.tgz.Name(), deb.data.tgz.Size())
return fmt.Sprintf(digestFileTmpl,
digestVersion,
deb.digest.signer,
deb.digest.date,
digestRole,
deb.digest.files)
}
func (deb *DebPkg) digestAddFile(filename, filepath string, size int64) {
md5sum, _ := digestCalcDataHashFromFile(filepath, md5.New())
sha1sum, _ := digestCalcDataHashFromFile(filepath, sha1.New())
deb.digest.files += fmt.Sprintf("\t%x %x %d %s\n",
md5sum,
sha1sum,
size,
filename)
}
func digestCalcDataHashFromFile(filename string, hash hash.Hash) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()
return digestCalcDataHash(f, hash)
}
func digestCalcDataHash(in io.Reader, hash hash.Hash) (string, error) {
var result []byte
if _, err := io.Copy(hash, in); err != nil {
return "", err
}
return string(hash.Sum(result)), nil
}
// WriteSigned package with GPG entity
func (deb *DebPkg) WriteSigned(filename string, entity *openpgp.Entity) error {
var buf bytes.Buffer
var cfg packet.Config
var signer string
cfg.DefaultHash = digestDefaultHash
for id := range entity.Identities {
// TODO real search for keyid, need to investigate maybe a subkey?
signer = id
}
deb.digest.date = time.Now().Format(time.ANSIC)
deb.digest.signer = signer
clearsign, err := clearsign.Encode(&buf, entity.PrivateKey, &cfg)
if err != nil {
return fmt.Errorf("error while signing: %s", err)
}
if err := deb.writeControlData(); err != nil {
return err
}
deb.digest.plaintext = createDigestFileString(deb)
if _, err = clearsign.Write([]byte(deb.digest.plaintext)); err != nil {
return fmt.Errorf("error from Write: %s", err)
}
if err = clearsign.Close(); err != nil {
return fmt.Errorf("error from Close: %s", err)
}
deb.digest.clearsign = buf.String()
if filename == "" {
filename = deb.GetFilename()
}
return deb.createDebAr(filename)
}