Пример #1
0
func decrypt(me *kindi.Identity, filename, server string) (string, string, error) {
	r, err := os.Open(filename)
	if err != nil {
		return "", "", err
	}
	defer r.Close()

	fid := make([]byte, len([]byte(fileIdentifier)))
	_, err = io.ReadFull(r, fid)
	if err != nil {
		return "", "", err
	}

	if string(fid) != fileIdentifier {
		return "", "", fmt.Errorf("file identifier mismatch for file %s. expected %s but got %s", filename, fileIdentifier, string(fid))
	}

	cs, err := me.DecryptCipherStream(r)
	if err != nil {
		return "", "", err
	}

	abtr := util.NewAllButTailReader(r, cs.Hash.Size(), 65536)

	jsonMetadata, err := cs.DecryptMetadata(abtr)
	if err != nil {
		return "", "", err
	}

	var metadata KindiMetadata
	err = json.Unmarshal(jsonMetadata, &metadata)
	if err != nil {
		return "", "", err
	}

	outfilename := filepath.Join(filepath.Dir(filename), metadata.Filename)
	w, err := os.OpenFile(outfilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return "", "", err
	}
	defer w.Close()

	err = cs.DecryptPayload(w, abtr)
	if err != nil {
		return "", "", err
	}

	if !bytes.Equal(abtr.Tail(), cs.Hash.Sum(nil)) {
		return "", "", fmt.Errorf("hash mismatch. kindi file %s has been modified.", filename)
	}

	senderCerts, _, err := fetchCertificates(server, metadata.SenderEmail)
	err = kindi.VerifySignature(metadata.SenderEmail, metadata.SenderSignature, senderCerts)
	if err != nil {
		return "", "", fmt.Errorf("sender signature for %s did not verify.", metadata.SenderEmail)
	}

	return outfilename, metadata.SenderEmail, nil
}