Example #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
}
Example #2
0
func encrypt(me *kindi.Identity, recipientEmails, filename, server string) error {
	certs, missing, err := fetchCertificates(server, recipientEmails)
	if err != nil {
		return err
	}

	if len(certs) == 0 {
		fmt.Fprintf(os.Stderr, "----------------------------------------------------\n")
		fmt.Fprintf(os.Stderr, "Warning: Couldn't find certificates for the following recipients: [%v]\n", recipientEmails)
		fmt.Fprintf(os.Stderr, "Those recipients will not be able to decrypt the file.\n")
		fmt.Fprintf(os.Stderr, "Please go to https://kindimonster.appspot.com/invite and invite them to join kindi.\n")
		fmt.Fprintf(os.Stderr, "----------------------------------------------------\n")

		return errors.New("no certificates fetched")
	}

	if len(missing) > 0 {
		fmt.Fprintf(os.Stderr, "----------------------------------------------------\n")
		fmt.Fprintf(os.Stderr, "Warning: Couldn't find certificates for the following recipients: %v\n", missing)
		fmt.Fprintf(os.Stderr, "Those recipients will not be able to decrypt the file.\n")
		fmt.Fprintf(os.Stderr, "Please go to https://kindimonster.appspot.com/invite and invite them to join kindi.\n")
		fmt.Fprintf(os.Stderr, "----------------------------------------------------\n")
	}

	r, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer r.Close()

	w, err := os.OpenFile(filename+".kindi", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}
	defer w.Close()

	_, err = w.Write([]byte(fileIdentifier))
	if err != nil {
		return err
	}

	sig, err := me.Sign()
	if err != nil {
		return err
	}

	metadata := KindiMetadata{
		Filename:        filepath.Base(filename),
		SenderEmail:     me.Email,
		SenderSignature: sig,
	}
	jsonMetadata, err := json.Marshal(metadata)
	if err != nil {
		return err
	}

	return me.Encrypt(w, jsonMetadata, r, certs)
}