1// Copyright (C) 2021 Storj Labs, Inc. 2// See LICENSE for copying information. 3 4package encryption 5 6import ( 7 "github.com/zeebo/errs" 8 9 "storj.io/common/paths" 10 "storj.io/common/storj" 11) 12 13// PrefixInfo is a helper type that contains all of the encrypted and unencrypted paths related 14// to some path and its parent. It includes the cipher that was used to encrypt and decrypt 15// the paths and what bucket it is in. 16type PrefixInfo struct { 17 Bucket string 18 Cipher storj.CipherSuite 19 20 PathUnenc paths.Unencrypted 21 PathEnc paths.Encrypted 22 PathKey storj.Key 23 24 ParentUnenc paths.Unencrypted 25 ParentEnc paths.Encrypted 26 ParentKey storj.Key 27} 28 29// GetPrefixInfo returns the PrefixInfo for some unencrypted path inside of a bucket. 30func GetPrefixInfo(bucket string, path paths.Unencrypted, store *Store) (pi *PrefixInfo, err error) { 31 _, remaining, base := store.LookupUnencrypted(bucket, path) 32 if base == nil { 33 return nil, ErrMissingEncryptionBase.New("%q/%q", bucket, path) 34 } 35 36 if path.Valid() && remaining.Done() { 37 return nil, ErrMissingEncryptionBase.New("no parent: %q/%q", bucket, path) 38 } 39 40 // if we're using the default base (meaning the default key), we need 41 // to include the bucket name in the path derivation. 42 key := &base.Key 43 if base.Default { 44 key, err = derivePathKeyComponent(key, bucket) 45 if err != nil { 46 return nil, errs.Wrap(err) 47 } 48 } 49 50 var ( 51 pathUnenc pathBuilder 52 pathEnc pathBuilder 53 parentUnenc pathBuilder 54 parentEnc pathBuilder 55 ) 56 57 pathKey := *key 58 parentKey := *key 59 60 if !base.Default && base.Encrypted.Valid() { 61 pathUnenc.append(base.Unencrypted.Raw()) 62 pathEnc.append(base.Encrypted.Raw()) 63 parentUnenc.append(base.Unencrypted.Raw()) 64 parentEnc.append(base.Encrypted.Raw()) 65 } 66 67 var componentUnenc string 68 var componentEnc string 69 70 for i := 0; !remaining.Done(); i++ { 71 if i > 0 { 72 parentKey = *key 73 parentEnc.append(componentEnc) 74 parentUnenc.append(componentUnenc) 75 } 76 77 componentUnenc = remaining.Next() 78 79 componentEnc, err = encryptPathComponent(componentUnenc, base.PathCipher, key) 80 if err != nil { 81 return nil, errs.Wrap(err) 82 } 83 key, err = derivePathKeyComponent(key, componentUnenc) 84 if err != nil { 85 return nil, errs.Wrap(err) 86 } 87 88 pathKey = *key 89 pathUnenc.append(componentUnenc) 90 pathEnc.append(componentEnc) 91 } 92 93 return &PrefixInfo{ 94 Bucket: bucket, 95 Cipher: base.PathCipher, 96 97 PathKey: pathKey, 98 PathUnenc: pathUnenc.Unencrypted(), 99 PathEnc: pathEnc.Encrypted(), 100 101 ParentKey: parentKey, 102 ParentUnenc: parentUnenc.Unencrypted(), 103 ParentEnc: parentEnc.Encrypted(), 104 }, nil 105} 106