85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
|
package crypto
|
||
|
|
||
|
import (
|
||
|
"crypto/sha256"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
|
||
|
"github.com/awnumar/memguard"
|
||
|
"golang.org/x/crypto/hkdf"
|
||
|
)
|
||
|
|
||
|
func InitKeyringFromMasterPassword(keyring *Keyring, accountKey EncString, accountPrivateKey EncString, orgKeys map[string]string, password memguard.LockedBuffer, email string, kdfConfig KDFConfig) error {
|
||
|
masterKey, err := DeriveMasterKey(password, email, kdfConfig)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return InitKeyringFromMasterKey(keyring, accountKey, accountPrivateKey, orgKeys, masterKey)
|
||
|
}
|
||
|
|
||
|
func InitKeyringFromMasterKey(keyring *Keyring, accountKey EncString, accountPrivateKey EncString, orgKeys map[string]string, masterKey MasterKey) error {
|
||
|
var accountSymmetricKeyByteArray []byte
|
||
|
|
||
|
switch accountKey.Type {
|
||
|
case AesCbc256_HmacSha256_B64:
|
||
|
stretchedMasterKey, err := stretchKey(masterKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
accountSymmetricKeyByteArray, err = DecryptWith(accountKey, stretchedMasterKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
default:
|
||
|
return fmt.Errorf("unsupported account key type: %d", accountKey.Type)
|
||
|
}
|
||
|
|
||
|
accountSymmetricKey, err := SymmetricEncryptionKeyFromBytes(accountSymmetricKeyByteArray)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
keyring.AccountKey = &accountSymmetricKey
|
||
|
|
||
|
pkcs8PrivateKey, err := DecryptWith(accountPrivateKey, accountSymmetricKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
keyring.AsymmetricEncyryptionKey = AsymmetricEncryptionKey{memguard.NewEnclave(pkcs8PrivateKey)}
|
||
|
keyring.OrganizationKeys = orgKeys
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func InitKeyringFromUserSymmetricKey(keyring *Keyring, accountSymmetricKey SymmetricEncryptionKey, accountPrivateKey EncString, orgKeys map[string]string) error {
|
||
|
keyring.AccountKey = &accountSymmetricKey
|
||
|
|
||
|
pkcs8PrivateKey, err := DecryptWith(accountPrivateKey, accountSymmetricKey)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
keyring.AsymmetricEncyryptionKey = AsymmetricEncryptionKey{memguard.NewEnclave(pkcs8PrivateKey)}
|
||
|
keyring.OrganizationKeys = orgKeys
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func stretchKey(masterKey MasterKey) (SymmetricEncryptionKey, error) {
|
||
|
key := make([]byte, 32)
|
||
|
macKey := make([]byte, 32)
|
||
|
|
||
|
buffer, err := masterKey.encKey.Open()
|
||
|
if err != nil {
|
||
|
return SymmetricEncryptionKey{}, err
|
||
|
}
|
||
|
|
||
|
var r io.Reader
|
||
|
r = hkdf.Expand(sha256.New, buffer.Data(), []byte("enc"))
|
||
|
r.Read(key)
|
||
|
r = hkdf.Expand(sha256.New, buffer.Data(), []byte("mac"))
|
||
|
r.Read(macKey)
|
||
|
return SymmetricEncryptionKey{memguard.NewEnclave(key), memguard.NewEnclave(macKey)}, nil
|
||
|
}
|