Beispiel #1
0
// Encrypt secures a message with the current timestamp.
func Encrypt(key *Key, plaintext []byte) *Box {
	if key == nil {
		return nil
	}

	now := uint64(time.Now().UnixNano())
	sbkey := cekdf(key, now)
	defer zero(sbkey)

	sbox, ok := strongbox.Seal(plaintext, sbkey)
	if !ok {
		return nil
	}

	var tagKey [sha512.Size]byte
	copy(tagKey[:], sbkey[sha512.Size:])
	defer zero(tagKey[:])
	tag := tagTimestamp(tagKey, now)

	return &Box{
		Data:      sbox,
		Timestamp: now,
		Tag:       tag,
	}
}
Beispiel #2
0
func sealBox(message []byte, peer PublicKey, boxtype byte) *bw {
	if message == nil {
		return nil
	} else if !KeyIsSuitable(nil, peer) {
		return nil
	}

	eph_key, eph_peer, ok := GenerateKey()
	if !ok {
		return nil
	}
	defer zero(eph_key)

	skey, ok := ecdh(eph_key, peer)
	if !ok {
		return nil
	}
	defer zero(skey)

	packer := newbw([]byte{boxtype})
	sbox, ok := strongbox.Seal(message, skey)
	if !ok {
		return nil
	}

	packer.Write(eph_peer)
	packer.Write(sbox)
	return packer
}
Beispiel #3
0
func boxForPeer(e_priv PrivateKey, peer PublicKey, key strongbox.Key) ([]byte, bool) {
	shared, ok := ecdh(e_priv, peer)
	if !ok {
		return nil, false
	}
	defer zero(shared)
	return strongbox.Seal(key, shared)

}
Beispiel #4
0
func buildSharedBox(message []byte, peers []PublicKey, btype byte) []byte {
	if message == nil {
		return nil
	}

	for _, peer := range peers {
		if peer == nil {
			return nil
		} else if !KeyIsSuitable(nil, peer) {
			return nil
		}
	}

	e_priv, e_pub, ok := GenerateKey()
	if !ok {
		return nil
	}

	shared, ok := strongbox.GenerateKey()
	if !ok {
		return nil
	}
	defer zero(shared)

	packPeers := newbw([]byte{peerList})
	packPeers.WriteUint32(uint32(len(peers)))
	for _, peer := range peers {
		packPeers.Write(peer)
		pbox, ok := boxForPeer(e_priv, peer, shared)
		if !ok {
			return nil
		}
		packPeers.Write(pbox)
	}
	plist := packPeers.Bytes()
	if plist == nil {
		return nil
	}

	packer := newbw([]byte{btype})
	packer.Write(e_pub)
	packer.Write(plist)
	sbox, ok := strongbox.Seal(message, shared)
	if !ok {
		return nil
	}
	packer.Write(sbox)
	return packer.Bytes()
}
Beispiel #5
0
// Sync secures and writes the vault to disk.
func (v *KeyVault) Sync() (err error) {
	if v == nil {
		return ErrVaultFailure
	}

	var logmeta = Metadata{
		"success": "false",
	}
	defer v.LogNow("sync", logmeta)

	v.metadata.WriteLock.Lock()
	defer v.metadata.WriteLock.Unlock()

	v.metadata.Locks.Secrets.Lock()
	v.metadata.Locks.Contexts.Lock()
	v.metadata.Locks.Revoked.Lock()
	v.metadata.Locks.Log.Lock()

	var jv = &vaultJSON{
		Secrets:      v.secrets,
		Contexts:     v.contexts,
		AdminContext: v.adminctx,
		Revoked:      v.revoked,
		Log:          v.log,
	}

	v.metadata.Locks.Log.Unlock()
	v.metadata.Locks.Revoked.Unlock()
	v.metadata.Locks.Contexts.Unlock()
	v.metadata.Locks.Secrets.Unlock()

	out, err := json.Marshal(jv)
	if err != nil {
		return
	}

	out, ok := strongbox.Seal(out, v.metadata.FileKey)
	if !ok {
		return ErrInvalidKey
	}

	var verBytes = make([]byte, 4)
	binary.BigEndian.PutUint32(verBytes, v.Version)
	h := hmac.New(sha512.New, v.metadata.TagKey)
	h.Write(verBytes)
	h.Write(v.Salt)
	var vf = &vaultFile{
		Version:  v.Version,
		Salt:     v.Salt,
		Tag:      h.Sum(nil),
		KeyVault: out,
	}
	file, err := json.Marshal(vf)
	if err != nil {
		return
	}

	// Write to a temporary file first; if this succeeds, move the
	// temporary file to the actual keystore file.
	tmpFile, err := ioutil.TempFile("", filepath.Base(v.metadata.Filename))
	if err != nil {
		return
	}
	tmpFileName := tmpFile.Name()
	tmpFile.Close()
	err = ioutil.WriteFile(tmpFileName, file, 0600)
	if err != nil {
		os.Remove(tmpFileName)
		return
	}
	err = os.Rename(tmpFileName, v.metadata.Filename)
	logmeta["success"] = "true"
	return
}