Example #1
0
func getRole(ctx context.Context, store storage.MetaStore, gun, role, checksum string) (*time.Time, []byte, error) {
	var (
		lastModified *time.Time
		out          []byte
		err          error
	)
	if checksum == "" {
		// the timestamp and snapshot might be server signed so are
		// handled specially
		switch role {
		case data.CanonicalTimestampRole, data.CanonicalSnapshotRole:
			return getMaybeServerSigned(ctx, store, gun, role)
		}
		lastModified, out, err = store.GetCurrent(gun, role)
	} else {
		lastModified, out, err = store.GetChecksum(gun, role, checksum)
	}

	if err != nil {
		if _, ok := err.(storage.ErrNotFound); ok {
			return nil, nil, errors.ErrMetadataNotFound.WithDetail(err)
		}
		return nil, nil, errors.ErrUnknown.WithDetail(err)
	}
	if out == nil {
		return nil, nil, errors.ErrMetadataNotFound.WithDetail(nil)
	}

	return lastModified, out, nil
}
Example #2
0
// getMaybeServerSigned writes the current snapshot or timestamp (based on the
// role passed) to the provided writer or returns an error. In retrieving
// the timestamp and snapshot, based on the keys held by the server, a new one
// might be generated and signed due to expiry of the previous one or updates
// to other roles.
func getMaybeServerSigned(ctx context.Context, store storage.MetaStore, gun, role string) (*time.Time, []byte, error) {
	cryptoServiceVal := ctx.Value(notary.CtxKeyCryptoSvc)
	cryptoService, ok := cryptoServiceVal.(signed.CryptoService)
	if !ok {
		return nil, nil, errors.ErrNoCryptoService.WithDetail(nil)
	}

	var (
		lastModified *time.Time
		out          []byte
		err          error
	)
	if role != data.CanonicalTimestampRole && role != data.CanonicalSnapshotRole {
		return nil, nil, fmt.Errorf("role %s cannot be server signed", role)
	}
	lastModified, out, err = timestamp.GetOrCreateTimestamp(gun, store, cryptoService)
	if err != nil {
		switch err.(type) {
		case *storage.ErrNoKey, storage.ErrNotFound:
			return nil, nil, errors.ErrMetadataNotFound.WithDetail(err)
		default:
			return nil, nil, errors.ErrUnknown.WithDetail(err)
		}
	}

	// If we wanted the snapshot, get it by checksum from the timestamp data
	if role == data.CanonicalSnapshotRole {
		ts := new(data.SignedTimestamp)
		if err := json.Unmarshal(out, ts); err != nil {
			return nil, nil, err
		}
		snapshotChecksums, err := ts.GetSnapshot()
		if err != nil || snapshotChecksums == nil {
			return nil, nil, fmt.Errorf("could not retrieve latest snapshot checksum")
		}
		if snapshotSHA256Bytes, ok := snapshotChecksums.Hashes[notary.SHA256]; ok {
			snapshotSHA256Hex := hex.EncodeToString(snapshotSHA256Bytes[:])
			return store.GetChecksum(gun, role, snapshotSHA256Hex)
		}
		return nil, nil, fmt.Errorf("could not retrieve sha256 snapshot checksum")
	}

	return lastModified, out, nil
}
Example #3
0
// GetOrCreateSnapshot either returns the existing latest snapshot, or uses
// whatever the most recent snapshot is to generate the next one, only updating
// the expiry time and version.  Note that this function does not write generated
// snapshots to the underlying data store, and will either return the latest snapshot time
// or nil as the time modified
func GetOrCreateSnapshot(gun, checksum string, store storage.MetaStore, cryptoService signed.CryptoService) (
	*time.Time, []byte, error) {

	lastModified, currentJSON, err := store.GetChecksum(gun, data.CanonicalSnapshotRole, checksum)
	if err != nil {
		return nil, nil, err
	}

	prev := new(data.SignedSnapshot)
	if err := json.Unmarshal(currentJSON, prev); err != nil {
		logrus.Error("Failed to unmarshal existing snapshot for GUN ", gun)
		return nil, nil, err
	}

	if !snapshotExpired(prev) {
		return lastModified, currentJSON, nil
	}

	builder := tuf.NewRepoBuilder(gun, cryptoService, trustpinning.TrustPinConfig{})

	// load the current root to ensure we use the correct snapshot key.
	_, rootJSON, err := store.GetCurrent(gun, data.CanonicalRootRole)
	if err != nil {
		logrus.Debug("Previous snapshot, but no root for GUN ", gun)
		return nil, nil, err
	}
	if err := builder.Load(data.CanonicalRootRole, rootJSON, 1, false); err != nil {
		logrus.Debug("Could not load valid previous root for GUN ", gun)
		return nil, nil, err
	}

	meta, _, err := builder.GenerateSnapshot(prev)
	if err != nil {
		return nil, nil, err
	}

	return nil, meta, nil
}