github.com/panekj/cli@v0.0.0-20230304125325-467dd2f3797e/internal/test/notary/client.go (about) 1 package notary 2 3 import ( 4 "github.com/docker/cli/cli/trust" 5 "github.com/theupdateframework/notary/client" 6 "github.com/theupdateframework/notary/client/changelist" 7 "github.com/theupdateframework/notary/cryptoservice" 8 "github.com/theupdateframework/notary/passphrase" 9 "github.com/theupdateframework/notary/storage" 10 "github.com/theupdateframework/notary/trustmanager" 11 "github.com/theupdateframework/notary/tuf/data" 12 "github.com/theupdateframework/notary/tuf/signed" 13 ) 14 15 // GetOfflineNotaryRepository returns a OfflineNotaryRepository 16 func GetOfflineNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 17 return OfflineNotaryRepository{}, nil 18 } 19 20 // OfflineNotaryRepository is a mock Notary repository that is offline 21 type OfflineNotaryRepository struct{} 22 23 // Initialize creates a new repository by using rootKey as the root Key for the 24 // TUF repository. 25 func (o OfflineNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error { 26 return storage.ErrOffline{} 27 } 28 29 // InitializeWithCertificate initializes the repository with root keys and their corresponding certificates 30 func (o OfflineNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error { 31 return storage.ErrOffline{} 32 } 33 34 // Publish pushes the local changes in signed material to the remote notary-server 35 // Conceptually it performs an operation similar to a `git rebase` 36 func (o OfflineNotaryRepository) Publish() error { 37 return storage.ErrOffline{} 38 } 39 40 // AddTarget creates new changelist entries to add a target to the given roles 41 // in the repository when the changelist gets applied at publish time. 42 func (o OfflineNotaryRepository) AddTarget(target *client.Target, roles ...data.RoleName) error { 43 return nil 44 } 45 46 // RemoveTarget creates new changelist entries to remove a target from the given 47 // roles in the repository when the changelist gets applied at publish time. 48 func (o OfflineNotaryRepository) RemoveTarget(targetName string, roles ...data.RoleName) error { 49 return nil 50 } 51 52 // ListTargets lists all targets for the current repository. The list of 53 // roles should be passed in order from highest to lowest priority. 54 func (o OfflineNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 55 return nil, storage.ErrOffline{} 56 } 57 58 // GetTargetByName returns a target by the given name. 59 func (o OfflineNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 60 return nil, storage.ErrOffline{} 61 } 62 63 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 64 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 65 func (o OfflineNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 66 return nil, storage.ErrOffline{} 67 } 68 69 // GetChangelist returns the list of the repository's unpublished changes 70 func (o OfflineNotaryRepository) GetChangelist() (changelist.Changelist, error) { 71 return changelist.NewMemChangelist(), nil 72 } 73 74 // ListRoles returns a list of RoleWithSignatures objects for this repo 75 func (o OfflineNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) { 76 return nil, storage.ErrOffline{} 77 } 78 79 // GetDelegationRoles returns the keys and roles of the repository's delegations 80 func (o OfflineNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 81 return nil, storage.ErrOffline{} 82 } 83 84 // AddDelegation creates changelist entries to add provided delegation public keys and paths. 85 func (o OfflineNotaryRepository) AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error { 86 return nil 87 } 88 89 // AddDelegationRoleAndKeys creates a changelist entry to add provided delegation public keys. 90 func (o OfflineNotaryRepository) AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error { 91 return nil 92 } 93 94 // AddDelegationPaths creates a changelist entry to add provided paths to an existing delegation. 95 func (o OfflineNotaryRepository) AddDelegationPaths(name data.RoleName, paths []string) error { 96 return nil 97 } 98 99 // RemoveDelegationKeysAndPaths creates changelist entries to remove provided delegation key IDs and paths. 100 func (o OfflineNotaryRepository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error { 101 return nil 102 } 103 104 // RemoveDelegationRole creates a changelist to remove all paths and keys from a role, and delete the role in its entirety. 105 func (o OfflineNotaryRepository) RemoveDelegationRole(name data.RoleName) error { 106 return nil 107 } 108 109 // RemoveDelegationPaths creates a changelist entry to remove provided paths from an existing delegation. 110 func (o OfflineNotaryRepository) RemoveDelegationPaths(name data.RoleName, paths []string) error { 111 return nil 112 } 113 114 // RemoveDelegationKeys creates a changelist entry to remove provided keys from an existing delegation. 115 func (o OfflineNotaryRepository) RemoveDelegationKeys(name data.RoleName, keyIDs []string) error { 116 return nil 117 } 118 119 // ClearDelegationPaths creates a changelist entry to remove all paths from an existing delegation. 120 func (o OfflineNotaryRepository) ClearDelegationPaths(name data.RoleName) error { 121 return nil 122 } 123 124 // Witness creates change objects to witness (i.e. re-sign) the given 125 // roles on the next publish. One change is created per role 126 func (o OfflineNotaryRepository) Witness(roles ...data.RoleName) ([]data.RoleName, error) { 127 return nil, nil 128 } 129 130 // RotateKey rotates a private key and returns the public component from the remote server 131 func (o OfflineNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error { 132 return storage.ErrOffline{} 133 } 134 135 // GetCryptoService is the getter for the repository's CryptoService 136 func (o OfflineNotaryRepository) GetCryptoService() signed.CryptoService { 137 return nil 138 } 139 140 // SetLegacyVersions allows the number of legacy versions of the root 141 // to be inspected for old signing keys to be configured. 142 func (o OfflineNotaryRepository) SetLegacyVersions(version int) {} 143 144 // GetGUN is a getter for the GUN object from a Repository 145 func (o OfflineNotaryRepository) GetGUN() data.GUN { 146 return data.GUN("gun") 147 } 148 149 // GetUninitializedNotaryRepository returns an UninitializedNotaryRepository 150 func GetUninitializedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 151 return UninitializedNotaryRepository{}, nil 152 } 153 154 // UninitializedNotaryRepository is a mock Notary repository that is uninintialized 155 // it builds on top of the OfflineNotaryRepository, instead returning ErrRepositoryNotExist 156 // for any online operation 157 type UninitializedNotaryRepository struct { 158 OfflineNotaryRepository 159 } 160 161 // Initialize creates a new repository by using rootKey as the root Key for the 162 // TUF repository. 163 func (u UninitializedNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error { 164 return client.ErrRepositoryNotExist{} 165 } 166 167 // InitializeWithCertificate initializes the repository with root keys and their corresponding certificates 168 func (u UninitializedNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error { 169 return client.ErrRepositoryNotExist{} 170 } 171 172 // Publish pushes the local changes in signed material to the remote notary-server 173 // Conceptually it performs an operation similar to a `git rebase` 174 func (u UninitializedNotaryRepository) Publish() error { 175 return client.ErrRepositoryNotExist{} 176 } 177 178 // ListTargets lists all targets for the current repository. The list of 179 // roles should be passed in order from highest to lowest priority. 180 func (u UninitializedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 181 return nil, client.ErrRepositoryNotExist{} 182 } 183 184 // GetTargetByName returns a target by the given name. 185 func (u UninitializedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 186 return nil, client.ErrRepositoryNotExist{} 187 } 188 189 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 190 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 191 func (u UninitializedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 192 return nil, client.ErrRepositoryNotExist{} 193 } 194 195 // ListRoles returns a list of RoleWithSignatures objects for this repo 196 func (u UninitializedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) { 197 return nil, client.ErrRepositoryNotExist{} 198 } 199 200 // GetDelegationRoles returns the keys and roles of the repository's delegations 201 func (u UninitializedNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 202 return nil, client.ErrRepositoryNotExist{} 203 } 204 205 // RotateKey rotates a private key and returns the public component from the remote server 206 func (u UninitializedNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error { 207 return client.ErrRepositoryNotExist{} 208 } 209 210 // GetEmptyTargetsNotaryRepository returns an EmptyTargetsNotaryRepository 211 func GetEmptyTargetsNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 212 return EmptyTargetsNotaryRepository{}, nil 213 } 214 215 // EmptyTargetsNotaryRepository is a mock Notary repository that is initialized 216 // but does not have any signed targets 217 type EmptyTargetsNotaryRepository struct { 218 OfflineNotaryRepository 219 } 220 221 // Initialize creates a new repository by using rootKey as the root Key for the 222 // TUF repository. 223 func (e EmptyTargetsNotaryRepository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error { 224 return nil 225 } 226 227 // InitializeWithCertificate initializes the repository with root keys and their corresponding certificates 228 func (e EmptyTargetsNotaryRepository) InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error { 229 return nil 230 } 231 232 // Publish pushes the local changes in signed material to the remote notary-server 233 // Conceptually it performs an operation similar to a `git rebase` 234 func (e EmptyTargetsNotaryRepository) Publish() error { 235 return nil 236 } 237 238 // ListTargets lists all targets for the current repository. The list of 239 // roles should be passed in order from highest to lowest priority. 240 func (e EmptyTargetsNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 241 return []*client.TargetWithRole{}, nil 242 } 243 244 // GetTargetByName returns a target by the given name. 245 func (e EmptyTargetsNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 246 return nil, client.ErrNoSuchTarget(name) 247 } 248 249 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 250 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 251 func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 252 return nil, client.ErrNoSuchTarget(name) 253 } 254 255 // ListRoles returns a list of RoleWithSignatures objects for this repo 256 func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) { 257 rootRole := data.Role{ 258 RootRole: data.RootRole{ 259 KeyIDs: []string{"rootID"}, 260 Threshold: 1, 261 }, 262 Name: data.CanonicalRootRole, 263 } 264 265 targetsRole := data.Role{ 266 RootRole: data.RootRole{ 267 KeyIDs: []string{"targetsID"}, 268 Threshold: 1, 269 }, 270 Name: data.CanonicalTargetsRole, 271 } 272 return []client.RoleWithSignatures{ 273 {Role: rootRole}, 274 {Role: targetsRole}, 275 }, nil 276 } 277 278 // GetDelegationRoles returns the keys and roles of the repository's delegations 279 func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 280 return []data.Role{}, nil 281 } 282 283 // RotateKey rotates a private key and returns the public component from the remote server 284 func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error { 285 return nil 286 } 287 288 // GetLoadedNotaryRepository returns a LoadedNotaryRepository 289 func GetLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 290 return LoadedNotaryRepository{}, nil 291 } 292 293 // LoadedNotaryRepository is a mock Notary repository that is loaded with targets, delegations, and keys 294 type LoadedNotaryRepository struct { 295 EmptyTargetsNotaryRepository 296 statefulCryptoService signed.CryptoService 297 } 298 299 // LoadedNotaryRepository has three delegations: 300 // - targets/releases: includes keys A and B 301 // - targets/alice: includes key A 302 // - targets/bob: includes key B 303 var loadedReleasesRole = data.DelegationRole{ 304 BaseRole: data.BaseRole{ 305 Name: "targets/releases", 306 Keys: map[string]data.PublicKey{"A": nil, "B": nil}, 307 Threshold: 1, 308 }, 309 } 310 311 var loadedAliceRole = data.DelegationRole{ 312 BaseRole: data.BaseRole{ 313 Name: "targets/alice", 314 Keys: map[string]data.PublicKey{"A": nil}, 315 Threshold: 1, 316 }, 317 } 318 319 var loadedBobRole = data.DelegationRole{ 320 BaseRole: data.BaseRole{ 321 Name: "targets/bob", 322 Keys: map[string]data.PublicKey{"B": nil}, 323 Threshold: 1, 324 }, 325 } 326 327 var loadedDelegationRoles = []data.Role{ 328 { 329 Name: loadedReleasesRole.Name, 330 RootRole: data.RootRole{ 331 KeyIDs: []string{"A", "B"}, 332 Threshold: 1, 333 }, 334 }, 335 { 336 Name: loadedAliceRole.Name, 337 RootRole: data.RootRole{ 338 KeyIDs: []string{"A"}, 339 Threshold: 1, 340 }, 341 }, 342 { 343 Name: loadedBobRole.Name, 344 RootRole: data.RootRole{ 345 KeyIDs: []string{"B"}, 346 Threshold: 1, 347 }, 348 }, 349 } 350 351 var loadedTargetsRole = data.DelegationRole{ 352 BaseRole: data.BaseRole{ 353 Name: data.CanonicalTargetsRole, 354 Keys: map[string]data.PublicKey{"C": nil}, 355 Threshold: 1, 356 }, 357 } 358 359 // LoadedNotaryRepository has three targets: 360 // - red: signed by targets/releases, targets/alice, targets/bob 361 // - blue: signed by targets/releases, targets/alice 362 // - green: signed by targets/releases 363 var loadedRedTarget = client.Target{ 364 Name: "red", 365 Hashes: data.Hashes{"sha256": []byte("red-digest")}, 366 } 367 368 var loadedBlueTarget = client.Target{ 369 Name: "blue", 370 Hashes: data.Hashes{"sha256": []byte("blue-digest")}, 371 } 372 373 var loadedGreenTarget = client.Target{ 374 Name: "green", 375 Hashes: data.Hashes{"sha256": []byte("green-digest")}, 376 } 377 378 var loadedTargets = []client.TargetSignedStruct{ 379 // red is signed by all three delegations 380 {Target: loadedRedTarget, Role: loadedReleasesRole}, 381 {Target: loadedRedTarget, Role: loadedAliceRole}, 382 {Target: loadedRedTarget, Role: loadedBobRole}, 383 384 // blue is signed by targets/releases, targets/alice 385 {Target: loadedBlueTarget, Role: loadedReleasesRole}, 386 {Target: loadedBlueTarget, Role: loadedAliceRole}, 387 388 // green is signed by targets/releases 389 {Target: loadedGreenTarget, Role: loadedReleasesRole}, 390 } 391 392 // ListRoles returns a list of RoleWithSignatures objects for this repo 393 func (l LoadedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) { 394 rootRole := data.Role{ 395 RootRole: data.RootRole{ 396 KeyIDs: []string{"rootID"}, 397 Threshold: 1, 398 }, 399 Name: data.CanonicalRootRole, 400 } 401 402 targetsRole := data.Role{ 403 RootRole: data.RootRole{ 404 KeyIDs: []string{"targetsID"}, 405 Threshold: 1, 406 }, 407 Name: data.CanonicalTargetsRole, 408 } 409 410 aliceRole := data.Role{ 411 RootRole: data.RootRole{ 412 KeyIDs: []string{"A"}, 413 Threshold: 1, 414 }, 415 Name: data.RoleName("targets/alice"), 416 } 417 418 bobRole := data.Role{ 419 RootRole: data.RootRole{ 420 KeyIDs: []string{"B"}, 421 Threshold: 1, 422 }, 423 Name: data.RoleName("targets/bob"), 424 } 425 426 releasesRole := data.Role{ 427 RootRole: data.RootRole{ 428 KeyIDs: []string{"A", "B"}, 429 Threshold: 1, 430 }, 431 Name: data.RoleName("targets/releases"), 432 } 433 // have releases only signed off by Alice last 434 releasesSig := []data.Signature{{KeyID: "A"}} 435 436 return []client.RoleWithSignatures{ 437 {Role: rootRole}, 438 {Role: targetsRole}, 439 {Role: aliceRole}, 440 {Role: bobRole}, 441 {Role: releasesRole, Signatures: releasesSig}, 442 }, nil 443 } 444 445 // ListTargets lists all targets for the current repository. The list of 446 // roles should be passed in order from highest to lowest priority. 447 func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 448 filteredTargets := []*client.TargetWithRole{} 449 for _, tgt := range loadedTargets { 450 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 451 filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}) 452 } 453 } 454 return filteredTargets, nil 455 } 456 457 // GetTargetByName returns a target by the given name. 458 func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 459 for _, tgt := range loadedTargets { 460 if name == tgt.Target.Name { 461 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 462 return &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}, nil 463 } 464 } 465 } 466 return nil, client.ErrNoSuchTarget(name) 467 } 468 469 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 470 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 471 func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 472 if name == "" { 473 return loadedTargets, nil 474 } 475 filteredTargets := []client.TargetSignedStruct{} 476 for _, tgt := range loadedTargets { 477 if name == tgt.Target.Name { 478 filteredTargets = append(filteredTargets, tgt) 479 } 480 } 481 if len(filteredTargets) == 0 { 482 return nil, client.ErrNoSuchTarget(name) 483 } 484 return filteredTargets, nil 485 } 486 487 // GetGUN is a getter for the GUN object from a Repository 488 func (l LoadedNotaryRepository) GetGUN() data.GUN { 489 return data.GUN("signed-repo") 490 } 491 492 // GetDelegationRoles returns the keys and roles of the repository's delegations 493 func (l LoadedNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 494 return loadedDelegationRoles, nil 495 } 496 497 // GetCryptoService is the getter for the repository's CryptoService 498 func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService { 499 if l.statefulCryptoService == nil { 500 // give it an in-memory cryptoservice with a root key and targets key 501 l.statefulCryptoService = cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("password"))) 502 l.statefulCryptoService.AddKey(data.CanonicalRootRole, l.GetGUN(), nil) 503 l.statefulCryptoService.AddKey(data.CanonicalTargetsRole, l.GetGUN(), nil) 504 } 505 return l.statefulCryptoService 506 } 507 508 // GetLoadedWithNoSignersNotaryRepository returns a LoadedWithNoSignersNotaryRepository 509 func GetLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 510 return LoadedWithNoSignersNotaryRepository{}, nil 511 } 512 513 // LoadedWithNoSignersNotaryRepository is a mock Notary repository that is loaded with targets but no delegations 514 // it only contains the green target 515 type LoadedWithNoSignersNotaryRepository struct { 516 LoadedNotaryRepository 517 } 518 519 // ListTargets lists all targets for the current repository. The list of 520 // roles should be passed in order from highest to lowest priority. 521 func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 522 filteredTargets := []*client.TargetWithRole{} 523 for _, tgt := range loadedTargets { 524 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 525 filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}) 526 } 527 } 528 return filteredTargets, nil 529 } 530 531 // GetTargetByName returns a target by the given name. 532 func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 533 if name == "" || name == loadedGreenTarget.Name { 534 return &client.TargetWithRole{Target: loadedGreenTarget, Role: data.CanonicalTargetsRole}, nil 535 } 536 return nil, client.ErrNoSuchTarget(name) 537 } 538 539 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 540 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 541 func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 542 if name == "" || name == loadedGreenTarget.Name { 543 return []client.TargetSignedStruct{{Target: loadedGreenTarget, Role: loadedTargetsRole}}, nil 544 } 545 return nil, client.ErrNoSuchTarget(name) 546 } 547 548 // GetDelegationRoles returns the keys and roles of the repository's delegations 549 func (l LoadedWithNoSignersNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 550 return []data.Role{}, nil 551 }