@@ -24,9 +24,9 @@ import (
24
24
func getPassphraseRetriever () notary.PassRetriever {
25
25
baseRetriever := passphrase .PromptRetriever ()
26
26
env := map [string ]string {
27
- "root" : os .Getenv ("SIGNY_ROOT_PASSPHRASE" ),
28
- "targets" : os .Getenv ("SIGNY_TARGETS_PASSPHRASE" ),
29
- "releases" : os .Getenv ("SIGNY_RELEASES_PASSPHRASE" ),
27
+ "root" : os .Getenv ("SIGNY_ROOT_PASSPHRASE" ),
28
+ "targets" : os .Getenv ("SIGNY_TARGETS_PASSPHRASE" ),
29
+ "targets/ releases" : os .Getenv ("SIGNY_RELEASES_PASSPHRASE" ),
30
30
}
31
31
32
32
return func (keyName string , alias string , createNew bool , numAttempts int ) (string , bool , error ) {
@@ -39,18 +39,20 @@ func getPassphraseRetriever() notary.PassRetriever {
39
39
40
40
// Attempt to read a role key from a file, and return it as a data.PrivateKey
41
41
// If key is for the Root role, it must be encrypted
42
- func readKey (role data.RoleName , keyFilename string , retriever notary.PassRetriever ) (data.PrivateKey , error ) {
42
+ func readPrivateKey (role data.RoleName , keyFilename string , retriever notary.PassRetriever ) (data.PrivateKey , error ) {
43
43
pemBytes , err := ioutil .ReadFile (keyFilename )
44
44
if err != nil {
45
45
return nil , fmt .Errorf ("Error reading input root key file: %v" , err )
46
46
}
47
+
47
48
isEncrypted := true
48
49
if err = cryptoservice .CheckRootKeyIsEncrypted (pemBytes ); err != nil {
49
50
if role == data .CanonicalRootRole {
50
51
return nil , err
51
52
}
52
53
isEncrypted = false
53
54
}
55
+
54
56
var privKey data.PrivateKey
55
57
if isEncrypted {
56
58
privKey , _ , err = trustmanager .GetPasswdDecryptBytes (retriever , pemBytes , "" , data .CanonicalRootRole .String ())
@@ -71,7 +73,7 @@ func importRootKey(rootKey string, nRepo client.Repository, retriever notary.Pas
71
73
var rootKeyList []string
72
74
73
75
if rootKey != "" {
74
- privKey , err := readKey (data .CanonicalRootRole , rootKey , retriever )
76
+ privKey , err := readPrivateKey (data .CanonicalRootRole , rootKey , retriever )
75
77
if err != nil {
76
78
return nil , err
77
79
}
@@ -89,77 +91,91 @@ func importRootKey(rootKey string, nRepo client.Repository, retriever notary.Pas
89
91
// Chooses the first root key available, which is initialization specific
90
92
// but should return the HW one first.
91
93
rootKeyID := rootKeyList [0 ]
92
- log .Debugf ("Signy found root key, using: %s\n " , rootKeyID )
93
-
94
+ log .Debugf ("found root key: %s\n " , rootKeyID )
94
95
return []string {rootKeyID }, nil
95
96
}
96
97
97
98
return []string {}, nil
98
99
}
99
100
101
+ // Try to reuse a single targets/releases key across repositories.
102
+ func reuseReleasesKey (r client.Repository ) (data.PublicKey , error ) {
103
+ // Get all known targets keys.
104
+ cryptoService := r .GetCryptoService ()
105
+ keyList := cryptoService .ListKeys (releasesRoleName )
106
+
107
+ // Try to extract a single targets/releases key we can reuse.
108
+ switch len (keyList ) {
109
+ case 0 :
110
+ log .Debugf ("No %s key available, need to make one" , releasesRoleName )
111
+ return cryptoService .Create (releasesRoleName , r .GetGUN (), data .ECDSAKey )
112
+ case 1 :
113
+ log .Debugf ("Nothing to do, only one %s key available" , releasesRoleName )
114
+ return cryptoService .GetKey (keyList [0 ]), nil
115
+ default :
116
+ return nil , fmt .Errorf ("there is more than one %s keys" , releasesRoleName )
117
+ }
118
+ }
119
+
100
120
// Try to reuse a single targets key across repositories.
101
121
// FIXME: Unfortunately, short of forking Notary or sending a PR upstream, there isn't an easy way to prevent it
102
122
// from automagically creating a new, local targets key per TUF metadata repository. We fix this here by undoing
103
123
// more than one new, local targets key, and reusing any existing local targets key, just like the way Notary
104
124
// reuses the root key.
105
125
func reuseTargetsKey (r client.Repository ) error {
106
- var (
107
- err error
108
- thisTargetsKeyID , thatTargetsKeyID string
109
- )
110
-
111
126
// Get all known targets keys.
112
- targetsKeyList := r .GetCryptoService ().ListKeys (data .CanonicalTargetsRole )
127
+ keyList := r .GetCryptoService ().ListKeys (data .CanonicalTargetsRole )
128
+
113
129
// Try to extract a single targets key we can reuse.
114
- switch len (targetsKeyList ) {
130
+ switch len (keyList ) {
115
131
case 0 :
116
- err = fmt .Errorf ("no targets key despite having initialized a repo" )
132
+ return fmt .Errorf ("no targets key despite having initialized a repo" )
117
133
case 1 :
118
134
log .Debug ("Nothing to do, only one targets key available" )
135
+ return nil
119
136
case 2 :
120
137
// First, we publish current changes to repository in order to list roles.
121
138
// FIXME: Find a find better way to list roles w/o publishing changes first.
122
- publishErr := r .Publish ()
123
- if publishErr != nil {
124
- err = publishErr
125
- break
139
+ err := r .Publish ()
140
+ if err != nil {
141
+ return err
126
142
}
127
143
128
144
// Get the current top-level roles.
129
- roleWithSigs , listRolesErr := r .ListRoles ()
130
- if listRolesErr != nil {
131
- err = listRolesErr
132
- break
145
+ roleWithSigs , err := r .ListRoles ()
146
+ if err != nil {
147
+ return err
133
148
}
134
149
135
150
// Get the current targets key.
136
151
// NOTE: We do not delete it, in case the user wants to keep it.
152
+ var thisKeyID string
137
153
for _ , roleWithSig := range roleWithSigs {
138
154
role := roleWithSig .Role
139
155
if role .Name == data .CanonicalTargetsRole {
140
156
if len (role .KeyIDs ) == 1 {
141
- thisTargetsKeyID = role .KeyIDs [0 ]
142
- log .Debugf ("This targets keyid: %s" , thisTargetsKeyID )
157
+ thisKeyID = role .KeyIDs [0 ]
158
+ log .Debugf ("This targets keyid: %s" , thisKeyID )
143
159
} else {
144
160
return fmt .Errorf ("this targets role has more than 1 key" )
145
161
}
146
162
}
147
163
}
148
164
149
165
// Get and reuse the other targets key.
150
- for _ , keyID := range targetsKeyList {
151
- if keyID != thisTargetsKeyID {
152
- thatTargetsKeyID = keyID
166
+ var thatKeyID string
167
+ for _ , keyID := range keyList {
168
+ if keyID != thisKeyID {
169
+ thatKeyID = keyID
153
170
break
154
171
}
155
172
}
156
- log .Debugf ("That targets keyID: %s" , thatTargetsKeyID )
157
- log .Debugf ("Before rotating targets key from %s to %s" , thisTargetsKeyID , thatTargetsKeyID )
158
- err = r .RotateKey (data .CanonicalTargetsRole , false , []string {thatTargetsKeyID })
173
+ log .Debugf ("That targets keyID: %s" , thatKeyID )
174
+ log .Debugf ("Before rotating targets key from %s to %s" , thisKeyID , thatKeyID )
175
+ err = r .RotateKey (data .CanonicalTargetsRole , false , []string {thatKeyID })
159
176
log .Debugf ("After targets key rotation" )
177
+ return err
160
178
default :
161
- err = fmt .Errorf ("there are more than 2 targets keys" )
179
+ return fmt .Errorf ("there are more than two targets keys" )
162
180
}
163
-
164
- return err
165
181
}
0 commit comments