func queueFile(src string) error { // refuse huge files, this is for assertions fi, err := os.Stat(src) if err != nil { return err } // 640kb ought be to enough for anyone if fi.Size() > 640*1024 { msg := fmt.Errorf("cannot queue %s, file size too big: %v", src, fi.Size()) logger.Noticef("error: %v", msg) return msg } // ensure name is predictable, weak hash is ok hash, _, err := osutil.FileDigest(src, crypto.SHA3_384) if err != nil { return err } dst := filepath.Join(dirs.SnapAssertsSpoolDir, fmt.Sprintf("%s.assert", base64.URLEncoding.EncodeToString(hash))) if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { return err } return osutil.CopyFile(src, dst, osutil.CopyFlagOverwrite) }
// SnapFileSHA3_384 computes the SHA3-384 digest of the given snap file. // It also returns its size. func SnapFileSHA3_384(snapPath string) (digest string, size uint64, err error) { sha3_384Dgst, size, err := osutil.FileDigest(snapPath, crypto.SHA3_384) if err != nil { return "", 0, fmt.Errorf("cannot compute snap %q digest: %v", snapPath, err) } sha3_384, err := EncodeDigest(crypto.SHA3_384, sha3_384Dgst) if err != nil { return "", 0, fmt.Errorf("cannot encode snap %q digest: %v", snapPath, err) } return sha3_384, size, nil }
func (ts *FileDigestSuite) TestFileDigest(c *C) { exData := []byte("hashmeplease") tempdir := c.MkDir() fn := filepath.Join(tempdir, "ex.file") err := ioutil.WriteFile(fn, exData, 0644) c.Assert(err, IsNil) digest, size, err := osutil.FileDigest(fn, crypto.SHA512) c.Assert(err, IsNil) c.Check(size, Equals, uint64(len(exData))) h512 := sha512.Sum512(exData) c.Check(digest, DeepEquals, h512[:]) }
return fmt.Errorf("cannot apply unsupported delta format %q (only xdelta3 currently)", deltaInfo.Format) } partialTargetPath := targetPath + ".partial" xdelta3Args := []string{"-d", "-s", snapPath, deltaPath, partialTargetPath} cmd := exec.Command("xdelta3", xdelta3Args...) if err := cmd.Run(); err != nil { if err := os.Remove(partialTargetPath); err != nil { logger.Noticef("failed to remove partial delta target %q: %s", partialTargetPath, err) } return err } bsha3_384, _, err := osutil.FileDigest(partialTargetPath, crypto.SHA3_384) if err != nil { return err } sha3_384 := fmt.Sprintf("%x", bsha3_384) if targetSha3_384 != "" && sha3_384 != targetSha3_384 { if err := os.Remove(partialTargetPath); err != nil { logger.Noticef("failed to remove partial delta target %q: %s", partialTargetPath, err) } return HashError{name, sha3_384, targetSha3_384} } if err := os.Rename(partialTargetPath, targetPath); err != nil { return osutil.CopyFile(partialTargetPath, targetPath, 0) }