github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/cli/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}}, nil 275 } 276 277 // GetDelegationRoles returns the keys and roles of the repository's delegations 278 func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 279 return []data.Role{}, nil 280 } 281 282 // RotateKey rotates a private key and returns the public component from the remote server 283 func (e EmptyTargetsNotaryRepository) RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error { 284 return nil 285 } 286 287 // GetLoadedNotaryRepository returns a LoadedNotaryRepository 288 func GetLoadedNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 289 return LoadedNotaryRepository{}, nil 290 } 291 292 // LoadedNotaryRepository is a mock Notary repository that is loaded with targets, delegations, and keys 293 type LoadedNotaryRepository struct { 294 EmptyTargetsNotaryRepository 295 statefulCryptoService signed.CryptoService 296 } 297 298 // LoadedNotaryRepository has three delegations: 299 // - targets/releases: includes keys A and B 300 // - targets/alice: includes key A 301 // - targets/bob: includes key B 302 var loadedReleasesRole = data.DelegationRole{ 303 BaseRole: data.BaseRole{ 304 Name: "targets/releases", 305 Keys: map[string]data.PublicKey{"A": nil, "B": nil}, 306 Threshold: 1, 307 }, 308 } 309 var loadedAliceRole = data.DelegationRole{ 310 BaseRole: data.BaseRole{ 311 Name: "targets/alice", 312 Keys: map[string]data.PublicKey{"A": nil}, 313 Threshold: 1, 314 }, 315 } 316 var loadedBobRole = data.DelegationRole{ 317 BaseRole: data.BaseRole{ 318 Name: "targets/bob", 319 Keys: map[string]data.PublicKey{"B": nil}, 320 Threshold: 1, 321 }, 322 } 323 var loadedDelegationRoles = []data.Role{ 324 { 325 Name: loadedReleasesRole.Name, 326 RootRole: data.RootRole{ 327 KeyIDs: []string{"A", "B"}, 328 Threshold: 1, 329 }, 330 }, 331 { 332 Name: loadedAliceRole.Name, 333 RootRole: data.RootRole{ 334 KeyIDs: []string{"A"}, 335 Threshold: 1, 336 }, 337 }, 338 { 339 Name: loadedBobRole.Name, 340 RootRole: data.RootRole{ 341 KeyIDs: []string{"B"}, 342 Threshold: 1, 343 }, 344 }, 345 } 346 var loadedTargetsRole = data.DelegationRole{ 347 BaseRole: data.BaseRole{ 348 Name: data.CanonicalTargetsRole, 349 Keys: map[string]data.PublicKey{"C": nil}, 350 Threshold: 1, 351 }, 352 } 353 354 // LoadedNotaryRepository has three targets: 355 // - red: signed by targets/releases, targets/alice, targets/bob 356 // - blue: signed by targets/releases, targets/alice 357 // - green: signed by targets/releases 358 var loadedRedTarget = client.Target{ 359 Name: "red", 360 Hashes: data.Hashes{"sha256": []byte("red-digest")}, 361 } 362 var loadedBlueTarget = client.Target{ 363 Name: "blue", 364 Hashes: data.Hashes{"sha256": []byte("blue-digest")}, 365 } 366 var loadedGreenTarget = client.Target{ 367 Name: "green", 368 Hashes: data.Hashes{"sha256": []byte("green-digest")}, 369 } 370 var loadedTargets = []client.TargetSignedStruct{ 371 // red is signed by all three delegations 372 {Target: loadedRedTarget, Role: loadedReleasesRole}, 373 {Target: loadedRedTarget, Role: loadedAliceRole}, 374 {Target: loadedRedTarget, Role: loadedBobRole}, 375 376 // blue is signed by targets/releases, targets/alice 377 {Target: loadedBlueTarget, Role: loadedReleasesRole}, 378 {Target: loadedBlueTarget, Role: loadedAliceRole}, 379 380 // green is signed by targets/releases 381 {Target: loadedGreenTarget, Role: loadedReleasesRole}, 382 } 383 384 // ListRoles returns a list of RoleWithSignatures objects for this repo 385 func (l LoadedNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) { 386 rootRole := data.Role{ 387 RootRole: data.RootRole{ 388 KeyIDs: []string{"rootID"}, 389 Threshold: 1, 390 }, 391 Name: data.CanonicalRootRole, 392 } 393 394 targetsRole := data.Role{ 395 RootRole: data.RootRole{ 396 KeyIDs: []string{"targetsID"}, 397 Threshold: 1, 398 }, 399 Name: data.CanonicalTargetsRole, 400 } 401 402 aliceRole := data.Role{ 403 RootRole: data.RootRole{ 404 KeyIDs: []string{"A"}, 405 Threshold: 1, 406 }, 407 Name: data.RoleName("targets/alice"), 408 } 409 410 bobRole := data.Role{ 411 RootRole: data.RootRole{ 412 KeyIDs: []string{"B"}, 413 Threshold: 1, 414 }, 415 Name: data.RoleName("targets/bob"), 416 } 417 418 releasesRole := data.Role{ 419 RootRole: data.RootRole{ 420 KeyIDs: []string{"A", "B"}, 421 Threshold: 1, 422 }, 423 Name: data.RoleName("targets/releases"), 424 } 425 // have releases only signed off by Alice last 426 releasesSig := []data.Signature{{KeyID: "A"}} 427 428 return []client.RoleWithSignatures{ 429 {Role: rootRole}, 430 {Role: targetsRole}, 431 {Role: aliceRole}, 432 {Role: bobRole}, 433 {Role: releasesRole, Signatures: releasesSig}, 434 }, nil 435 } 436 437 // ListTargets lists all targets for the current repository. The list of 438 // roles should be passed in order from highest to lowest priority. 439 func (l LoadedNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 440 filteredTargets := []*client.TargetWithRole{} 441 for _, tgt := range loadedTargets { 442 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 443 filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}) 444 } 445 } 446 return filteredTargets, nil 447 } 448 449 // GetTargetByName returns a target by the given name. 450 func (l LoadedNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 451 for _, tgt := range loadedTargets { 452 if name == tgt.Target.Name { 453 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 454 return &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}, nil 455 } 456 } 457 } 458 return nil, client.ErrNoSuchTarget(name) 459 } 460 461 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 462 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 463 func (l LoadedNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 464 if name == "" { 465 return loadedTargets, nil 466 } 467 filteredTargets := []client.TargetSignedStruct{} 468 for _, tgt := range loadedTargets { 469 if name == tgt.Target.Name { 470 filteredTargets = append(filteredTargets, tgt) 471 } 472 } 473 if len(filteredTargets) == 0 { 474 return nil, client.ErrNoSuchTarget(name) 475 } 476 return filteredTargets, nil 477 } 478 479 // GetGUN is a getter for the GUN object from a Repository 480 func (l LoadedNotaryRepository) GetGUN() data.GUN { 481 return data.GUN("signed-repo") 482 } 483 484 // GetDelegationRoles returns the keys and roles of the repository's delegations 485 func (l LoadedNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 486 return loadedDelegationRoles, nil 487 } 488 489 // GetCryptoService is the getter for the repository's CryptoService 490 func (l LoadedNotaryRepository) GetCryptoService() signed.CryptoService { 491 if l.statefulCryptoService == nil { 492 // give it an in-memory cryptoservice with a root key and targets key 493 l.statefulCryptoService = cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("password"))) 494 l.statefulCryptoService.AddKey(data.CanonicalRootRole, l.GetGUN(), nil) 495 l.statefulCryptoService.AddKey(data.CanonicalTargetsRole, l.GetGUN(), nil) 496 } 497 return l.statefulCryptoService 498 } 499 500 // GetLoadedWithNoSignersNotaryRepository returns a LoadedWithNoSignersNotaryRepository 501 func GetLoadedWithNoSignersNotaryRepository(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (client.Repository, error) { 502 return LoadedWithNoSignersNotaryRepository{}, nil 503 } 504 505 // LoadedWithNoSignersNotaryRepository is a mock Notary repository that is loaded with targets but no delegations 506 // it only contains the green target 507 type LoadedWithNoSignersNotaryRepository struct { 508 LoadedNotaryRepository 509 } 510 511 // ListTargets lists all targets for the current repository. The list of 512 // roles should be passed in order from highest to lowest priority. 513 func (l LoadedWithNoSignersNotaryRepository) ListTargets(roles ...data.RoleName) ([]*client.TargetWithRole, error) { 514 filteredTargets := []*client.TargetWithRole{} 515 for _, tgt := range loadedTargets { 516 if len(roles) == 0 || (len(roles) > 0 && roles[0] == tgt.Role.Name) { 517 filteredTargets = append(filteredTargets, &client.TargetWithRole{Target: tgt.Target, Role: tgt.Role.Name}) 518 } 519 } 520 return filteredTargets, nil 521 } 522 523 // GetTargetByName returns a target by the given name. 524 func (l LoadedWithNoSignersNotaryRepository) GetTargetByName(name string, roles ...data.RoleName) (*client.TargetWithRole, error) { 525 if name == "" || name == loadedGreenTarget.Name { 526 return &client.TargetWithRole{Target: loadedGreenTarget, Role: data.CanonicalTargetsRole}, nil 527 } 528 return nil, client.ErrNoSuchTarget(name) 529 } 530 531 // GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all 532 // roles, and returns a list of TargetSignedStructs for each time it finds the specified target. 533 func (l LoadedWithNoSignersNotaryRepository) GetAllTargetMetadataByName(name string) ([]client.TargetSignedStruct, error) { 534 if name == "" || name == loadedGreenTarget.Name { 535 return []client.TargetSignedStruct{{Target: loadedGreenTarget, Role: loadedTargetsRole}}, nil 536 } 537 return nil, client.ErrNoSuchTarget(name) 538 } 539 540 // GetDelegationRoles returns the keys and roles of the repository's delegations 541 func (l LoadedWithNoSignersNotaryRepository) GetDelegationRoles() ([]data.Role, error) { 542 return []data.Role{}, nil 543 }