// NewDigestVerifier returns a verifier that compares the written bytes // against a passed in digest. func NewDigestVerifier(d Digest) (Verifier, error) { if err := d.Validate(); err != nil { return nil, err } alg := d.Algorithm() switch alg { case "sha256", "sha384", "sha512": return hashVerifier{ hash: alg.Hash(), digest: d, }, nil default: // Assume we have a tarsum. version, err := tarsum.GetVersionFromTarsum(string(d)) if err != nil { return nil, err } pr, pw := io.Pipe() // TODO(stevvooe): We may actually want to ban the earlier versions of // tarsum. That decision may not be the place of the verifier. ts, err := tarsum.NewTarSum(pr, true, version) if err != nil { return nil, err } // TODO(sday): Ick! A goroutine per digest verification? We'll have to // get the tarsum library to export an io.Writer variant. go func() { if _, err := io.Copy(ioutil.Discard, ts); err != nil { pr.CloseWithError(err) } else { pr.Close() } }() return &tarsumVerifier{ digest: d, ts: ts, pr: pr, pw: pw, }, nil } }
// ReadChecks takes the input and loads the hash/id to be checked func ReadChecks(input io.Reader) (Checks, error) { rdr := bufio.NewReader(input) checks := Checks{} for { line, err := rdr.ReadString('\n') if err != nil { if err == io.EOF { break } return checks, err } v, err := tarsum.GetVersionFromTarsum(line) if err != nil { continue } // tarsum+sha256:7b0ade22d5bba35d1e88389c005376f441e7d83bf5f363f2d7c70be9286163aa ./busybox.tar:120e218dd395ec314e7b6249f39d2853911b3d6def6ea164ae05722649f34b16 chunks := strings.SplitN(line, DefaultSpacer, 2) sum, source := chunks[0], chunks[1] i := strings.LastIndex(source, ":") checks = append(checks, Check{Hash: sum, Source: source[:i], Id: strings.TrimSpace(source[i+1:]), Version: v}) } return checks, nil }