func (r *NotaryRepository) initializeRoles(rootKeys []data.PublicKey, localRoles, remoteRoles []string) ( root, targets, snapshot, timestamp data.BaseRole, err error) { root = data.NewBaseRole( data.CanonicalRootRole, notary.MinThreshold, rootKeys..., ) // we want to create all the local keys first so we don't have to // make unnecessary network calls for _, role := range localRoles { // This is currently hardcoding the keys to ECDSA. var key data.PublicKey key, err = r.CryptoService.Create(role, r.gun, data.ECDSAKey) if err != nil { return } switch role { case data.CanonicalSnapshotRole: snapshot = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTargetsRole: targets = data.NewBaseRole( role, notary.MinThreshold, key, ) } } for _, role := range remoteRoles { // This key is generated by the remote server. var key data.PublicKey key, err = getRemoteKey(r.baseURL, r.gun, role, r.roundTrip) if err != nil { return } logrus.Debugf("got remote %s %s key with keyID: %s", role, key.Algorithm(), key.ID()) switch role { case data.CanonicalSnapshotRole: snapshot = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTimestampRole: timestamp = data.NewBaseRole( role, notary.MinThreshold, key, ) } } return root, targets, snapshot, timestamp, nil }
func initRepo(t *testing.T, cryptoService signed.CryptoService) *Repo { rootKey, err := cryptoService.Create("root", data.ED25519Key) assert.NoError(t, err) targetsKey, err := cryptoService.Create("targets", data.ED25519Key) assert.NoError(t, err) snapshotKey, err := cryptoService.Create("snapshot", data.ED25519Key) assert.NoError(t, err) timestampKey, err := cryptoService.Create("timestamp", data.ED25519Key) assert.NoError(t, err) rootRole := data.NewBaseRole( data.CanonicalRootRole, 1, rootKey, ) targetsRole := data.NewBaseRole( data.CanonicalTargetsRole, 1, targetsKey, ) snapshotRole := data.NewBaseRole( data.CanonicalSnapshotRole, 1, snapshotKey, ) timestampRole := data.NewBaseRole( data.CanonicalTimestampRole, 1, timestampKey, ) repo := NewRepo(cryptoService) err = repo.InitRoot(rootRole, timestampRole, snapshotRole, targetsRole, false) assert.NoError(t, err) _, err = repo.InitTargets(data.CanonicalTargetsRole) assert.NoError(t, err) err = repo.InitSnapshot() assert.NoError(t, err) err = repo.InitTimestamp() assert.NoError(t, err) return repo }
// EmptyRepo creates an in memory crypto service // and initializes a repo with no targets. Delegations are only created // if delegation roles are passed in. func EmptyRepo(gun string, delegationRoles ...string) (*tuf.Repo, signed.CryptoService, error) { cs := cryptoservice.NewCryptoService( gun, trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever(""))) r := tuf.NewRepo(cs) baseRoles := map[string]data.BaseRole{} for _, role := range data.BaseRoles { key, err := createKey(cs, gun, role) if err != nil { return nil, nil, err } baseRoles[role] = data.NewBaseRole( role, 1, key, ) } r.InitRoot( baseRoles[data.CanonicalRootRole], baseRoles[data.CanonicalTimestampRole], baseRoles[data.CanonicalSnapshotRole], baseRoles[data.CanonicalTargetsRole], false, ) r.InitTargets(data.CanonicalTargetsRole) r.InitSnapshot() r.InitTimestamp() // sort the delegation roles so that we make sure to create the parents // first sort.Strings(delegationRoles) for _, delgName := range delegationRoles { // create a delegations key and a delegation in the tuf repo delgKey, err := createKey(cs, gun, delgName) if err != nil { return nil, nil, err } role, err := data.NewRole(delgName, 1, []string{}, []string{""}) if err != nil { return nil, nil, err } if err := r.UpdateDelegations(role, []data.PublicKey{delgKey}); err != nil { return nil, nil, err } } return r, cs, nil }
// Initialize creates a new repository by using rootKey as the root Key for the // TUF repository. The server must be reachable (and is asked to generate a // timestamp key and possibly other serverManagedRoles), but the created repository // result is only stored on local disk, not published to the server. To do that, // use r.Publish() eventually. func (r *NotaryRepository) Initialize(rootKeyID string, serverManagedRoles ...string) error { privKey, _, err := r.CryptoService.GetPrivateKey(rootKeyID) if err != nil { return err } // currently we only support server managing timestamps and snapshots, and // nothing else - timestamps are always managed by the server, and implicit // (do not have to be passed in as part of `serverManagedRoles`, so that // the API of Initialize doesn't change). var serverManagesSnapshot bool locallyManagedKeys := []string{ data.CanonicalTargetsRole, data.CanonicalSnapshotRole, // root is also locally managed, but that should have been created // already } remotelyManagedKeys := []string{data.CanonicalTimestampRole} for _, role := range serverManagedRoles { switch role { case data.CanonicalTimestampRole: continue // timestamp is already in the right place case data.CanonicalSnapshotRole: // because we put Snapshot last locallyManagedKeys = []string{data.CanonicalTargetsRole} remotelyManagedKeys = append( remotelyManagedKeys, data.CanonicalSnapshotRole) serverManagesSnapshot = true default: return ErrInvalidRemoteRole{Role: role} } } rootKey, err := rootCertKey(r.gun, privKey) if err != nil { return err } var ( rootRole = data.NewBaseRole( data.CanonicalRootRole, notary.MinThreshold, rootKey, ) timestampRole data.BaseRole snapshotRole data.BaseRole targetsRole data.BaseRole ) // we want to create all the local keys first so we don't have to // make unnecessary network calls for _, role := range locallyManagedKeys { // This is currently hardcoding the keys to ECDSA. key, err := r.CryptoService.Create(role, r.gun, data.ECDSAKey) if err != nil { return err } switch role { case data.CanonicalSnapshotRole: snapshotRole = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTargetsRole: targetsRole = data.NewBaseRole( role, notary.MinThreshold, key, ) } } for _, role := range remotelyManagedKeys { // This key is generated by the remote server. key, err := getRemoteKey(r.baseURL, r.gun, role, r.roundTrip) if err != nil { return err } logrus.Debugf("got remote %s %s key with keyID: %s", role, key.Algorithm(), key.ID()) switch role { case data.CanonicalSnapshotRole: snapshotRole = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTimestampRole: timestampRole = data.NewBaseRole( role, notary.MinThreshold, key, ) } } r.tufRepo = tuf.NewRepo(r.CryptoService) err = r.tufRepo.InitRoot( rootRole, timestampRole, snapshotRole, targetsRole, false, ) if err != nil { logrus.Debug("Error on InitRoot: ", err.Error()) return err } _, err = r.tufRepo.InitTargets(data.CanonicalTargetsRole) if err != nil { logrus.Debug("Error on InitTargets: ", err.Error()) return err } err = r.tufRepo.InitSnapshot() if err != nil { logrus.Debug("Error on InitSnapshot: ", err.Error()) return err } return r.saveMetadata(serverManagesSnapshot) }
// Initialize creates a new repository by using rootKey as the root Key for the // TUF repository. func (r *NotaryRepository) Initialize(rootKeyID string, serverManagedRoles ...string) error { privKey, _, err := r.CryptoService.GetPrivateKey(rootKeyID) if err != nil { return err } // currently we only support server managing timestamps and snapshots, and // nothing else - timestamps are always managed by the server, and implicit // (do not have to be passed in as part of `serverManagedRoles`, so that // the API of Initialize doesn't change). var serverManagesSnapshot bool locallyManagedKeys := []string{ data.CanonicalTargetsRole, data.CanonicalSnapshotRole, // root is also locally managed, but that should have been created // already } remotelyManagedKeys := []string{data.CanonicalTimestampRole} for _, role := range serverManagedRoles { switch role { case data.CanonicalTimestampRole: continue // timestamp is already in the right place case data.CanonicalSnapshotRole: // because we put Snapshot last locallyManagedKeys = []string{data.CanonicalTargetsRole} remotelyManagedKeys = append( remotelyManagedKeys, data.CanonicalSnapshotRole) serverManagesSnapshot = true default: return ErrInvalidRemoteRole{Role: role} } } // Hard-coded policy: the generated certificate expires in 10 years. startTime := time.Now() rootCert, err := cryptoservice.GenerateCertificate( privKey, r.gun, startTime, startTime.AddDate(10, 0, 0)) if err != nil { return err } r.CertStore.AddCert(rootCert) // The root key gets stored in the TUF metadata X509 encoded, linking // the tuf root.json to our X509 PKI. // If the key is RSA, we store it as type RSAx509, if it is ECDSA we store it // as ECDSAx509 to allow the gotuf verifiers to correctly decode the // key on verification of signatures. var rootKey data.PublicKey switch privKey.Algorithm() { case data.RSAKey: rootKey = data.NewRSAx509PublicKey(trustmanager.CertToPEM(rootCert)) case data.ECDSAKey: rootKey = data.NewECDSAx509PublicKey(trustmanager.CertToPEM(rootCert)) default: return fmt.Errorf("invalid format for root key: %s", privKey.Algorithm()) } var ( rootRole = data.NewBaseRole( data.CanonicalRootRole, notary.MinThreshold, rootKey, ) timestampRole data.BaseRole snapshotRole data.BaseRole targetsRole data.BaseRole ) // we want to create all the local keys first so we don't have to // make unnecessary network calls for _, role := range locallyManagedKeys { // This is currently hardcoding the keys to ECDSA. key, err := r.CryptoService.Create(role, data.ECDSAKey) if err != nil { return err } switch role { case data.CanonicalSnapshotRole: snapshotRole = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTargetsRole: targetsRole = data.NewBaseRole( role, notary.MinThreshold, key, ) } } for _, role := range remotelyManagedKeys { // This key is generated by the remote server. key, err := getRemoteKey(r.baseURL, r.gun, role, r.roundTrip) if err != nil { return err } logrus.Debugf("got remote %s %s key with keyID: %s", role, key.Algorithm(), key.ID()) switch role { case data.CanonicalSnapshotRole: snapshotRole = data.NewBaseRole( role, notary.MinThreshold, key, ) case data.CanonicalTimestampRole: timestampRole = data.NewBaseRole( role, notary.MinThreshold, key, ) } } r.tufRepo = tuf.NewRepo(r.CryptoService) err = r.tufRepo.InitRoot( rootRole, timestampRole, snapshotRole, targetsRole, false, ) if err != nil { logrus.Debug("Error on InitRoot: ", err.Error()) return err } _, err = r.tufRepo.InitTargets(data.CanonicalTargetsRole) if err != nil { logrus.Debug("Error on InitTargets: ", err.Error()) return err } err = r.tufRepo.InitSnapshot() if err != nil { logrus.Debug("Error on InitSnapshot: ", err.Error()) return err } return r.saveMetadata(serverManagesSnapshot) }