Example #1
0
// Returns true if the MD5 and SHA256 checksums set on this file match the
// checksums of the file's contents. If a checksum is not provided, then it
// is not checked. If neither checksum is provided, then returns true.
func (f *file) Verify() bool {
	r := f.Open()
	defer r.Close()
	ok, _ := util.VerifyStreamHash(r, f.MD5, f.SHA256)
	return ok
}
Example #2
0
// Verify computes the checksum of each file in this bag, and checks it against
// the manifest files. Both payload ("data/") and tag files are checked.
// The file list is read from manifest files for MD5, SHA1, SHA256, and SHA512
// hashes, although only MD5 and SHA256 hashes are actually computed and verified.
// Files missing an entry in a manifest file, or manifest entires missing a
// corresponding file will cause a verification error. Tag files which are
// missing a manifest entry are the only execption to the verification error.
func (r *Reader) Verify() error {
	err := r.loadManifests()
	if err != nil {
		return err
	}

	// Check the quick stuff first, and do the time consuming checksum
	// verification last.
	var dataprefix = r.t.dirname + "data/"
	var npayload int

	// Does every payload ("data/") file in this zip appear in our manifest
	// map? tag files may also appear in the map, we don't care yet.
	//
	// We need to do some pathname manipulation since the zip directory
	// names have the form "bagname/data/blah/blah" but the manifest
	// has names of the form "data/blah/blah".
	for _, f := range r.z.File {
		if !strings.HasPrefix(f.Name, dataprefix) {
			continue
		}
		npayload++
		xname := strings.TrimPrefix(f.Name, r.t.dirname)
		if r.t.manifest[xname] == nil {
			return BagError{Err: ErrExtraFile, File: xname}
		}
	}

	// Does every file listed in the manifest exist in the zip file?
	//
	// The loop above ensures npayload <= nmanifest.
	// so if nmanifest != npayload, it must be because it contains files
	// not present in the zip file. The downside of this method is we do
	// not know the name of the missing file.
	var nmanifest int
	for k := range r.t.manifest {
		if strings.HasPrefix(k, "data/") {
			nmanifest++
		}
	}
	if npayload != nmanifest {
		return BagError{Err: ErrMissingFile}
	}

	// Do all the checksums match?
	// Since t.manifest includes both payload and data files, we will
	// verify more than nmanifest files here.
	for _, f := range r.z.File {
		xname := strings.TrimPrefix(f.Name, r.t.dirname)
		checksum := r.t.manifest[xname]
		if checksum == nil {
			// this file is not in the manifest. We don't care
			// since we have already verified all the payload
			// files are accounted for.
			continue
		}
		in, err := f.Open()
		if err != nil {
			return err
		}
		ok, err := util.VerifyStreamHash(in, checksum.MD5, checksum.SHA256)
		_ = in.Close()
		if err != nil {
			return err
		} else if !ok {
			// checksum error!
			return BagError{Err: ErrChecksum, File: xname}
		}
	}

	return nil
}