github.com/ethersphere/bee/v2@v2.2.0/pkg/accesscontrol/access_test.go (about) 1 // Copyright 2024 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package accesscontrol_test 6 7 import ( 8 "context" 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rand" 12 "encoding/hex" 13 "fmt" 14 "testing" 15 16 "github.com/ethersphere/bee/v2/pkg/accesscontrol" 17 kvsmock "github.com/ethersphere/bee/v2/pkg/accesscontrol/kvs/mock" 18 "github.com/ethersphere/bee/v2/pkg/crypto" 19 "github.com/ethersphere/bee/v2/pkg/swarm" 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func assertNoError(t *testing.T, msg string, err error) { 24 t.Helper() 25 if err != nil { 26 assert.FailNowf(t, err.Error(), msg) 27 } 28 } 29 30 func assertError(t *testing.T, msg string, err error) { 31 t.Helper() 32 if err == nil { 33 assert.FailNowf(t, fmt.Sprintf("Expected %s error, got nil", msg), "") 34 } 35 } 36 37 // Generates a new test environment with a fix private key. 38 func setupAccessLogic() accesscontrol.ActLogic { 39 privateKey := getPrivKey(1) 40 diffieHellman := accesscontrol.NewDefaultSession(privateKey) 41 al := accesscontrol.NewLogic(diffieHellman) 42 43 return al 44 } 45 46 func getPrivKey(keyNumber int) *ecdsa.PrivateKey { 47 var keyHex string 48 49 switch keyNumber { 50 case 0: 51 keyHex = "a786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfa" 52 case 1: 53 keyHex = "b786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfb" 54 case 2: 55 keyHex = "c786dd84b61485de12146fd9c4c02d87e8fd95f0542765cb7fc3d2e428c0bcfc" 56 default: 57 panic("Invalid key number") 58 } 59 60 data, err := hex.DecodeString(keyHex) 61 if err != nil { 62 panic(err) 63 } 64 65 privKey, err := crypto.DecodeSecp256k1PrivateKey(data) 66 if err != nil { 67 panic(err) 68 } 69 70 return privKey 71 } 72 73 func TestDecryptRef_Publisher(t *testing.T) { 74 t.Parallel() 75 ctx := context.Background() 76 id1 := getPrivKey(1) 77 s := kvsmock.New() 78 al := setupAccessLogic() 79 err := al.AddGrantee(ctx, s, &id1.PublicKey, &id1.PublicKey) 80 assertNoError(t, "AddGrantee", err) 81 82 byteRef, err := hex.DecodeString("39a5ea87b141fe44aa609c3327ecd896c0e2122897f5f4bbacf74db1033c5559") 83 assertNoError(t, "DecodeString", err) 84 expectedRef := swarm.NewAddress(byteRef) 85 encryptedRef, err := al.EncryptRef(ctx, s, &id1.PublicKey, expectedRef) 86 assertNoError(t, "al encryptref", err) 87 88 t.Run("decrypt success", func(t *testing.T) { 89 actualRef, err := al.DecryptRef(ctx, s, encryptedRef, &id1.PublicKey) 90 assertNoError(t, "decrypt ref", err) 91 92 if !expectedRef.Equal(actualRef) { 93 assert.FailNowf(t, fmt.Sprintf("DecryptRef gave back wrong Swarm reference! Expedted: %v, actual: %v", expectedRef, actualRef), "") 94 } 95 }) 96 t.Run("decrypt with nil publisher", func(t *testing.T) { 97 _, err = al.DecryptRef(ctx, s, encryptedRef, nil) 98 assertError(t, "al decryptref", err) 99 }) 100 } 101 102 func TestDecryptRefWithGrantee_Success(t *testing.T) { 103 t.Parallel() 104 ctx := context.Background() 105 id0, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 106 assertNoError(t, "GenerateKey", err) 107 diffieHellman := accesscontrol.NewDefaultSession(id0) 108 al := accesscontrol.NewLogic(diffieHellman) 109 110 s := kvsmock.New() 111 err = al.AddGrantee(ctx, s, &id0.PublicKey, &id0.PublicKey) 112 assertNoError(t, "AddGrantee publisher", err) 113 114 id1, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 115 assertNoError(t, "GenerateKey", err) 116 err = al.AddGrantee(ctx, s, &id0.PublicKey, &id1.PublicKey) 117 assertNoError(t, "AddGrantee id1", err) 118 119 byteRef, err := hex.DecodeString("39a5ea87b141fe44aa609c3327ecd896c0e2122897f5f4bbacf74db1033c5559") 120 assertNoError(t, "DecodeString", err) 121 122 expectedRef := swarm.NewAddress(byteRef) 123 124 encryptedRef, err := al.EncryptRef(ctx, s, &id0.PublicKey, expectedRef) 125 assertNoError(t, "al encryptref", err) 126 127 diffieHellman2 := accesscontrol.NewDefaultSession(id1) 128 granteeAccessLogic := accesscontrol.NewLogic(diffieHellman2) 129 actualRef, err := granteeAccessLogic.DecryptRef(ctx, s, encryptedRef, &id0.PublicKey) 130 assertNoError(t, "grantee al decryptref", err) 131 132 if !expectedRef.Equal(actualRef) { 133 assert.FailNowf(t, fmt.Sprintf("DecryptRef gave back wrong Swarm reference! Expedted: %v, actual: %v", expectedRef, actualRef), "") 134 } 135 } 136 137 func TestAddPublisher(t *testing.T) { 138 t.Parallel() 139 id0 := getPrivKey(0) 140 savedLookupKey := "b6ee086390c280eeb9824c331a4427596f0c8510d5564bc1b6168d0059a46e2b" 141 s := kvsmock.New() 142 ctx := context.Background() 143 144 al := setupAccessLogic() 145 err := al.AddGrantee(ctx, s, &id0.PublicKey, &id0.PublicKey) 146 assertNoError(t, "AddGrantee", err) 147 148 decodedSavedLookupKey, err := hex.DecodeString(savedLookupKey) 149 assertNoError(t, "decode LookupKey", err) 150 151 encryptedAccessKey, err := s.Get(ctx, decodedSavedLookupKey) 152 assertNoError(t, "kvs Get accesskey", err) 153 154 decodedEncryptedAccessKey := hex.EncodeToString(encryptedAccessKey) 155 156 // A random value is returned, so it is only possible to check the length of the returned value 157 // We know the lookup key because the generated private key is fixed 158 if len(decodedEncryptedAccessKey) != 64 { 159 assert.FailNowf(t, fmt.Sprintf("AddGrantee: expected encrypted access key length 64, got %d", len(decodedEncryptedAccessKey)), "") 160 } 161 } 162 163 func TestAddNewGranteeToContent(t *testing.T) { 164 t.Parallel() 165 id0 := getPrivKey(0) 166 id1 := getPrivKey(1) 167 id2 := getPrivKey(2) 168 ctx := context.Background() 169 170 publisherLookupKey := "b6ee086390c280eeb9824c331a4427596f0c8510d5564bc1b6168d0059a46e2b" 171 firstAddedGranteeLookupKey := "a13678e81f9d939b9401a3ad7e548d2ceb81c50f8c76424296e83a1ad79c0df0" 172 secondAddedGranteeLookupKey := "d5e9a6499ca74f5b8b958a4b89b7338045b2baa9420e115443a8050e26986564" 173 174 s := kvsmock.New() 175 al := setupAccessLogic() 176 err := al.AddGrantee(ctx, s, &id0.PublicKey, &id0.PublicKey) 177 assertNoError(t, "AddGrantee id0", err) 178 179 err = al.AddGrantee(ctx, s, &id0.PublicKey, &id1.PublicKey) 180 assertNoError(t, "AddGrantee id1", err) 181 182 err = al.AddGrantee(ctx, s, &id0.PublicKey, &id2.PublicKey) 183 assertNoError(t, "AddGrantee id2", err) 184 185 lookupKeyAsByte, err := hex.DecodeString(publisherLookupKey) 186 assertNoError(t, "publisher lookupkey DecodeString", err) 187 188 result, err := s.Get(ctx, lookupKeyAsByte) 189 assertNoError(t, "1st kvs get", err) 190 hexEncodedEncryptedAK := hex.EncodeToString(result) 191 if len(hexEncodedEncryptedAK) != 64 { 192 assert.FailNowf(t, fmt.Sprintf("AddNewGrantee: expected encrypted access key length 64, got %d", len(hexEncodedEncryptedAK)), "") 193 } 194 195 lookupKeyAsByte, err = hex.DecodeString(firstAddedGranteeLookupKey) 196 assertNoError(t, "1st lookupkey DecodeString", err) 197 198 result, err = s.Get(ctx, lookupKeyAsByte) 199 assertNoError(t, "2nd kvs get", err) 200 hexEncodedEncryptedAK = hex.EncodeToString(result) 201 if len(hexEncodedEncryptedAK) != 64 { 202 assert.FailNowf(t, fmt.Sprintf("AddNewGrantee: expected encrypted access key length 64, got %d", len(hexEncodedEncryptedAK)), "") 203 } 204 205 lookupKeyAsByte, err = hex.DecodeString(secondAddedGranteeLookupKey) 206 assertNoError(t, "2nd lookupkey DecodeString", err) 207 208 result, err = s.Get(ctx, lookupKeyAsByte) 209 assertNoError(t, "3rd kvs get", err) 210 hexEncodedEncryptedAK = hex.EncodeToString(result) 211 if len(hexEncodedEncryptedAK) != 64 { 212 assert.FailNowf(t, fmt.Sprintf("AddNewGrantee: expected encrypted access key length 64, got %d", len(hexEncodedEncryptedAK)), "") 213 } 214 }