1717package ocicrypt
1818
1919import (
20+ "bytes"
2021 "encoding/base64"
22+ "encoding/hex"
2123 "encoding/json"
2224 "fmt"
23- keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
24- "github.com/containers/ocicrypt/keywrap/keyprovider"
2525 "io"
2626 "strings"
2727
2828 "github.com/containers/ocicrypt/blockcipher"
2929 "github.com/containers/ocicrypt/config"
30+ keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
3031 "github.com/containers/ocicrypt/keywrap"
3132 "github.com/containers/ocicrypt/keywrap/jwe"
33+ "github.com/containers/ocicrypt/keywrap/keyprovider"
3234 "github.com/containers/ocicrypt/keywrap/pgp"
3335 "github.com/containers/ocicrypt/keywrap/pkcs11"
3436 "github.com/containers/ocicrypt/keywrap/pkcs7"
37+ "github.com/containers/ocicrypt/utils"
3538 "github.com/opencontainers/go-digest"
36- log "github.com/sirupsen/logrus"
3739 ocispec "github.com/opencontainers/image-spec/specs-go/v1"
3840 "github.com/pkg/errors"
41+ log "github.com/sirupsen/logrus"
3942)
4043
4144// EncryptLayerFinalizer is a finalizer run to return the annotations to set for
@@ -86,8 +89,20 @@ func GetWrappedKeysMap(desc ocispec.Descriptor) map[string]string {
8689 return wrappedKeysMap
8790}
8891
92+ // comparePreviousLayersDigests compares the given digests and returns an error if they do not match
93+ func comparePreviousLayersDigests (previousLayersDigest []byte , expPreviousLayersDigest digest.Digest ) error {
94+ digest , err := hex .DecodeString (expPreviousLayersDigest .Encoded ())
95+ if err != nil {
96+ return errors .Wrapf (err , "Hex-decoding expected previous layers hash failed" )
97+ }
98+ if ! bytes .Equal (digest , previousLayersDigest ) {
99+ return errors .Errorf ("Previous layer digest '%x' does not match expected one '%x'" , previousLayersDigest , digest )
100+ }
101+ return nil
102+ }
103+
89104// EncryptLayer encrypts the layer by running one encryptor after the other
90- func EncryptLayer (ec * config.EncryptConfig , encOrPlainLayerReader io.Reader , desc ocispec.Descriptor ) (io.Reader , EncryptLayerFinalizer , error ) {
105+ func EncryptLayer (ec * config.EncryptConfig , encOrPlainLayerReader io.Reader , desc ocispec.Descriptor , previousLayersDigest [] byte ) (io.Reader , EncryptLayerFinalizer , [] byte , error ) {
91106 var (
92107 encLayerReader io.Reader
93108 err error
@@ -97,20 +112,30 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
97112 pubOptsData []byte
98113 )
99114
115+ if len (previousLayersDigest ) == 0 {
116+ /* bottom-most layer MUST start with sha256.Sum(nil) */
117+ return nil , nil , nil , errors .New ("previousLayersDigest must not be nil" )
118+ }
119+
100120 if ec == nil {
101- return nil , nil , errors .New ("EncryptConfig must not be nil" )
121+ return nil , nil , nil , errors .New ("EncryptConfig must not be nil" )
122+ }
123+
124+ newLayersDigest , err := utils .GetNewLayersDigest (previousLayersDigest , desc .Digest )
125+ if err != nil {
126+ return nil , nil , nil , err
102127 }
103128
104129 for annotationsID := range keyWrapperAnnotations {
105130 annotation := desc .Annotations [annotationsID ]
106131 if annotation != "" {
107132 privOptsData , err = decryptLayerKeyOptsData (& ec .DecryptConfig , desc )
108133 if err != nil {
109- return nil , nil , err
134+ return nil , nil , nil , err
110135 }
111136 pubOptsData , err = getLayerPubOpts (desc )
112137 if err != nil {
113- return nil , nil , err
138+ return nil , nil , nil , err
114139 }
115140 // already encrypted!
116141 encrypted = true
@@ -120,7 +145,7 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
120145 if ! encrypted {
121146 encLayerReader , bcFin , err = commonEncryptLayer (encOrPlainLayerReader , desc .Digest , blockcipher .AES256CTR )
122147 if err != nil {
123- return nil , nil , err
148+ return nil , nil , nil , err
124149 }
125150 }
126151
@@ -131,6 +156,8 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
131156 if err != nil {
132157 return nil , err
133158 }
159+
160+ opts .Private .PreviousLayersDigest = digest .NewDigestFromBytes (digest .SHA256 , previousLayersDigest )
134161 privOptsData , err = json .Marshal (opts .Private )
135162 if err != nil {
136163 return nil , errors .Wrapf (err , "could not JSON marshal opts" )
@@ -169,8 +196,7 @@ func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, des
169196 }
170197
171198 // if nothing was encrypted, we just return encLayer = nil
172- return encLayerReader , encLayerFinalizer , err
173-
199+ return encLayerReader , encLayerFinalizer , newLayersDigest , err
174200}
175201
176202// preWrapKeys calls WrapKeys and handles the base64 encoding and concatenation of the
@@ -190,22 +216,22 @@ func preWrapKeys(keywrapper keywrap.KeyWrapper, ec *config.EncryptConfig, b64Ann
190216// DecryptLayer decrypts a layer trying one keywrap.KeyWrapper after the other to see whether it
191217// can apply the provided private key
192218// If unwrapOnly is set we will only try to decrypt the layer encryption key and return
193- func DecryptLayer (dc * config.DecryptConfig , encLayerReader io.Reader , desc ocispec.Descriptor , unwrapOnly bool ) (io.Reader , digest.Digest , error ) {
219+ func DecryptLayer (dc * config.DecryptConfig , encLayerReader io.Reader , desc ocispec.Descriptor , unwrapOnly bool , previousLayersDigest [] byte ) (io.Reader , digest.Digest , [] byte , error ) {
194220 if dc == nil {
195- return nil , "" , errors .New ("DecryptConfig must not be nil" )
221+ return nil , "" , nil , errors .New ("DecryptConfig must not be nil" )
196222 }
197223 privOptsData , err := decryptLayerKeyOptsData (dc , desc )
198224 if err != nil || unwrapOnly {
199- return nil , "" , err
225+ return nil , "" , nil , err
200226 }
201227
202228 var pubOptsData []byte
203229 pubOptsData , err = getLayerPubOpts (desc )
204230 if err != nil {
205- return nil , "" , err
231+ return nil , "" , nil , err
206232 }
207233
208- return commonDecryptLayer (encLayerReader , privOptsData , pubOptsData )
234+ return commonDecryptLayer (encLayerReader , privOptsData , pubOptsData , previousLayersDigest )
209235}
210236
211237func decryptLayerKeyOptsData (dc * config.DecryptConfig , desc ocispec.Descriptor ) ([]byte , error ) {
@@ -301,23 +327,36 @@ func commonEncryptLayer(plainLayerReader io.Reader, d digest.Digest, typ blockci
301327
302328// commonDecryptLayer decrypts an encrypted layer previously encrypted with commonEncryptLayer
303329// by passing along the optsData
304- func commonDecryptLayer (encLayerReader io.Reader , privOptsData []byte , pubOptsData []byte ) (io.Reader , digest.Digest , error ) {
330+ func commonDecryptLayer (encLayerReader io.Reader , privOptsData []byte , pubOptsData []byte , previousLayersDigest [] byte ) (io.Reader , digest.Digest , [] byte , error ) {
305331 privOpts := blockcipher.PrivateLayerBlockCipherOptions {}
306332 err := json .Unmarshal (privOptsData , & privOpts )
307333 if err != nil {
308- return nil , "" , errors .Wrapf (err , "could not JSON unmarshal privOptsData" )
334+ return nil , "" , nil , errors .Wrapf (err , "could not JSON unmarshal privOptsData" )
335+ }
336+
337+ if len (privOpts .PreviousLayersDigest ) > 0 {
338+ /* older images do not have this */
339+ err = comparePreviousLayersDigests (previousLayersDigest , privOpts .PreviousLayersDigest )
340+ if err != nil {
341+ return nil , "" , nil , err
342+ }
343+ }
344+
345+ newLayersDigest , err := utils .GetNewLayersDigest (previousLayersDigest , privOpts .Digest )
346+ if err != nil {
347+ return nil , "" , nil , err
309348 }
310349
311350 lbch , err := blockcipher .NewLayerBlockCipherHandler ()
312351 if err != nil {
313- return nil , "" , err
352+ return nil , "" , nil , err
314353 }
315354
316355 pubOpts := blockcipher.PublicLayerBlockCipherOptions {}
317356 if len (pubOptsData ) > 0 {
318357 err := json .Unmarshal (pubOptsData , & pubOpts )
319358 if err != nil {
320- return nil , "" , errors .Wrapf (err , "could not JSON unmarshal pubOptsData" )
359+ return nil , "" , nil , errors .Wrapf (err , "could not JSON unmarshal pubOptsData" )
321360 }
322361 }
323362
@@ -328,10 +367,10 @@ func commonDecryptLayer(encLayerReader io.Reader, privOptsData []byte, pubOptsDa
328367
329368 plainLayerReader , opts , err := lbch .Decrypt (encLayerReader , opts )
330369 if err != nil {
331- return nil , "" , err
370+ return nil , "" , nil , err
332371 }
333372
334- return plainLayerReader , opts .Private .Digest , nil
373+ return plainLayerReader , opts .Private .Digest , newLayersDigest , nil
335374}
336375
337376// FilterOutAnnotations filters out the annotations belonging to the image encryption 'namespace'
0 commit comments