Patched HMAC vulnerability.

This commit is contained in:
Brendan Mc
2015-05-01 16:06:49 -07:00
parent 9f0c4e9e28
commit 7e08548caf
4 changed files with 63 additions and 16 deletions

View File

@@ -94,6 +94,7 @@ type SummaryData struct {
type DecryptWithDelegates struct {
Data []byte
Secure bool
Delegates []string
}
@@ -299,7 +300,7 @@ func Decrypt(jsonIn []byte) ([]byte, error) {
return jsonStatusError(err)
}
data, names, err := crypt.Decrypt(s.Data, s.Name)
data, names, secure, err := crypt.Decrypt(s.Data, s.Name)
if err != nil {
log.Println("Error decrypting:", err)
return jsonStatusError(err)
@@ -307,6 +308,7 @@ func Decrypt(jsonIn []byte) ([]byte, error) {
resp := &DecryptWithDelegates{
Data: data,
Secure: secure,
Delegates: names,
}

View File

@@ -53,11 +53,11 @@ type SingleWrappedKey struct {
// keys necessary to decrypt it when delegated.
type EncryptedData struct {
Version int
VaultId int
Labels []string
KeySet []MultiWrappedKey
KeySetRSA map[string]SingleWrappedKey
IV []byte
VaultId int `json:",omitempty"`
Labels []string `json:",omitempty"`
KeySet []MultiWrappedKey `json:",omitempty"`
KeySetRSA map[string]SingleWrappedKey `json:",omitempty"`
IV []byte `json:",omitempty"`
Data []byte
Signature []byte
}
@@ -141,6 +141,42 @@ func (encrypted *EncryptedData) computeHmac(key []byte) []byte {
return mac.Sum(nil)
}
func (encrypted *EncryptedData) lock(key []byte) (err error) {
payload, err := json.Marshal(encrypted)
if err != nil {
return
}
mac := hmac.New(sha1.New, key)
mac.Write(payload)
sig := mac.Sum(nil)
*encrypted = EncryptedData{
Version: -1,
Data: payload,
Signature: sig,
}
return
}
func (encrypted *EncryptedData) unlock(key []byte) (err error) {
if encrypted.Version != -1 {
return
}
mac := hmac.New(sha1.New, key)
mac.Write(encrypted.Data)
sig := mac.Sum(nil)
if !hmac.Equal(encrypted.Signature, sig) {
err = errors.New("Signature mismatch")
return
}
return json.Unmarshal(encrypted.Data, encrypted)
}
// wrapKey encrypts the clear key such that a minimum number of delegated keys
// are required to decrypt. NOTE: Currently the max value for min is 2.
func (encrypted *EncryptedData) wrapKey(records *passvault.Records, clearKey []byte, names []string, min int) (err error) {
@@ -298,35 +334,44 @@ func (c *Cryptor) Encrypt(in []byte, labels, names []string, min int) (resp []by
return
}
encrypted.Signature = encrypted.computeHmac(hmacKey)
encrypted.lock(hmacKey)
return json.Marshal(encrypted)
}
// Decrypt decrypts a file using the keys in the key cache.
func (c *Cryptor) Decrypt(in []byte, user string) (resp []byte, names []string, err error) {
func (c *Cryptor) Decrypt(in []byte, user string) (resp []byte, names []string, secure bool, err error) {
// unwrap encrypted file
var encrypted EncryptedData
if err = json.Unmarshal(in, &encrypted); err != nil {
return
}
if encrypted.Version != DEFAULT_VERSION {
return nil, nil, errors.New("Unknown version")
if encrypted.Version != DEFAULT_VERSION && encrypted.Version != -1 {
return nil, nil, secure, errors.New("Unknown version")
}
secure = encrypted.Version == -1
hmacKey, err := c.records.GetHmacKey()
if err != nil {
return
}
if err = encrypted.unlock(hmacKey); err != nil {
return
}
// make sure file was encrypted with the active vault
vaultId, err := c.records.GetVaultId()
if err != nil {
return
}
if encrypted.VaultId != vaultId {
return nil, nil, errors.New("Wrong vault")
return nil, nil, secure, errors.New("Wrong vault")
}
// compute HMAC
hmacKey, err := c.records.GetHmacKey()
if err != nil {
return
}
expectedMAC := encrypted.computeHmac(hmacKey)
if !hmac.Equal(encrypted.Signature, expectedMAC) {
err = errors.New("Signature mismatch")

View File

@@ -485,7 +485,7 @@
data : data,
success : function(d){
d = JSON.parse(window.atob(d.Response));
$form.find('.feedback').empty().append( makeAlert({ type: 'success', message: '<p>Successfully decrypted data:</p><pre>'+ window.atob(d.Data)+'</pre><p>Delegates: '+d.Delegates.sort().join(', ')+'</p>' }) );
$form.find('.feedback').empty().append( makeAlert({ type: (d.Secure ? 'success' : 'warning'), message: '<p>Successfully decrypted data:</p><pre>'+ window.atob(d.Data)+'</pre><p>Delegates: '+d.Delegates.sort().join(', ')+'</p>' }) );
}
});
});

View File

@@ -732,7 +732,7 @@ var indexHtml = []byte(`<!DOCTYPE html>
data : data,
success : function(d){
d = JSON.parse(window.atob(d.Response));
$form.find('.feedback').empty().append( makeAlert({ type: 'success', message: '<p>Successfully decrypted data:</p><pre>'+ window.atob(d.Data)+'</pre><p>Delegates: '+d.Delegates.sort().join(', ')+'</p>' }) );
$form.find('.feedback').empty().append( makeAlert({ type: (d.Secure ? 'success' : 'warning'), message: '<p>Successfully decrypted data:</p><pre>'+ window.atob(d.Data)+'</pre><p>Delegates: '+d.Delegates.sort().join(', ')+'</p>' }) );
}
});
});