1package blobstore 2 3import ( 4 "os" 5 6 boshcrypto "github.com/cloudfoundry/bosh-utils/crypto" 7 bosherr "github.com/cloudfoundry/bosh-utils/errors" 8 boshsys "github.com/cloudfoundry/bosh-utils/system" 9) 10 11type digestVerifiableBlobstore struct { 12 blobstore Blobstore 13 fs boshsys.FileSystem 14 createAlgorithms []boshcrypto.Algorithm 15} 16 17func NewDigestVerifiableBlobstore(blobstore Blobstore, fs boshsys.FileSystem, createAlgorithms []boshcrypto.Algorithm) DigestBlobstore { 18 return digestVerifiableBlobstore{ 19 blobstore: blobstore, 20 fs: fs, 21 createAlgorithms: createAlgorithms, 22 } 23} 24 25func (b digestVerifiableBlobstore) Get(blobID string, digest boshcrypto.Digest) (string, error) { 26 fileName, err := b.blobstore.Get(blobID) 27 if err != nil { 28 return "", bosherr.WrapError(err, "Getting blob from inner blobstore") 29 } 30 31 file, err := b.fs.OpenFile(fileName, os.O_RDONLY, 0) 32 if err != nil { 33 return "", err 34 } 35 36 defer file.Close() 37 38 err = digest.Verify(file) 39 if err != nil { 40 return "", bosherr.WrapErrorf(err, "Checking downloaded blob '%s'", blobID) 41 } 42 43 return fileName, nil 44} 45 46func (b digestVerifiableBlobstore) Delete(blobId string) error { 47 return b.blobstore.Delete(blobId) 48} 49 50func (b digestVerifiableBlobstore) CleanUp(fileName string) error { 51 return b.blobstore.CleanUp(fileName) 52} 53 54func (b digestVerifiableBlobstore) Create(fileName string) (string, boshcrypto.MultipleDigest, error) { 55 multipleDigest, err := b.createDigest(fileName) 56 if err != nil { 57 return "", boshcrypto.MultipleDigest{}, err 58 } 59 60 blobID, err := b.blobstore.Create(fileName) 61 return blobID, multipleDigest, err 62} 63 64func (b digestVerifiableBlobstore) Validate() error { 65 return b.blobstore.Validate() 66} 67 68func (b digestVerifiableBlobstore) createDigest(fileName string) (boshcrypto.MultipleDigest, error) { 69 digests := []boshcrypto.Digest{} 70 for _, algo := range b.createAlgorithms { 71 digest, err := b.computeDigest(algo, fileName) 72 if err != nil { 73 return boshcrypto.MultipleDigest{}, err 74 } 75 digests = append(digests, digest) 76 } 77 return boshcrypto.MustNewMultipleDigest(digests...), nil 78} 79 80func (b digestVerifiableBlobstore) computeDigest(algo boshcrypto.Algorithm, fileName string) (boshcrypto.Digest, error) { 81 file, err := b.fs.OpenFile(fileName, os.O_RDONLY, 0) 82 if err != nil { 83 return boshcrypto.MultipleDigest{}, err 84 } 85 86 defer file.Close() 87 88 return algo.CreateDigest(file) 89} 90