@@ -17,7 +17,10 @@ limitations under the License.
17
17
package controllers
18
18
19
19
import (
20
+ "bytes"
20
21
"context"
22
+ "crypto/sha1"
23
+ "crypto/sha256"
21
24
"fmt"
22
25
"io"
23
26
"io/ioutil"
@@ -126,13 +129,42 @@ func (r *HelmReleaseReconciler) loadHelmChart(source *sourcev1.HelmChart) (*char
126
129
return nil , fmt .Errorf ("artifact '%s' download failed (status code: %s)" , source .GetArtifact ().URL , resp .Status )
127
130
}
128
131
129
- if _ , err = io .Copy (f , resp .Body ); err != nil {
132
+ var buf bytes.Buffer
133
+
134
+ // verify checksum matches origin
135
+ if err := r .verifyArtifact (source .GetArtifact (), & buf , resp .Body ); err != nil {
136
+ return nil , err
137
+ }
138
+
139
+ if _ , err = io .Copy (f , & buf ); err != nil {
130
140
return nil , err
131
141
}
132
142
133
143
return loader .Load (f .Name ())
134
144
}
135
145
146
+ func (r * HelmReleaseReconciler ) verifyArtifact (artifact * sourcev1.Artifact , buf * bytes.Buffer , reader io.Reader ) error {
147
+ hasher := sha256 .New ()
148
+
149
+ // for backwards compatibility with source-controller v0.17.2 and older
150
+ if len (artifact .Checksum ) == 40 {
151
+ hasher = sha1 .New ()
152
+ }
153
+
154
+ // compute checksum
155
+ mw := io .MultiWriter (hasher , buf )
156
+ if _ , err := io .Copy (mw , reader ); err != nil {
157
+ return err
158
+ }
159
+
160
+ if checksum := fmt .Sprintf ("%x" , hasher .Sum (nil )); checksum != artifact .Checksum {
161
+ return fmt .Errorf ("failed to verify artifact: computed checksum '%s' doesn't match advertised '%s'" ,
162
+ checksum , artifact .Checksum )
163
+ }
164
+
165
+ return nil
166
+ }
167
+
136
168
// deleteHelmChart deletes the v1beta1.HelmChart of the v2beta1.HelmRelease.
137
169
func (r * HelmReleaseReconciler ) deleteHelmChart (ctx context.Context , hr * v2.HelmRelease ) error {
138
170
if hr .Status .HelmChart == "" {
0 commit comments