mirror of
https://github.com/cloudflare/redoctober.git
synced 2026-01-05 13:07:10 +00:00
Removed AES user type and reformatted more code.
This commit is contained in:
@@ -92,8 +92,6 @@ func encryptKey(nameInner, nameOuter string, clearKey []byte, pubKeys map[string
|
|||||||
err = errors.New("Missing user in file")
|
err = errors.New("Missing user in file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case passvault.AESRecord:
|
|
||||||
break
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return out, errors.New("Unknown record type inner")
|
return out, errors.New("Unknown record type inner")
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type ActiveUser struct {
|
|||||||
Admin bool
|
Admin bool
|
||||||
Type string
|
Type string
|
||||||
|
|
||||||
aesKey []byte
|
|
||||||
rsaKey rsa.PrivateKey
|
rsaKey rsa.PrivateKey
|
||||||
eccKey *ecdsa.PrivateKey
|
eccKey *ecdsa.PrivateKey
|
||||||
}
|
}
|
||||||
@@ -68,7 +67,7 @@ func (usage Usage) matchesLabel(labels []string) bool {
|
|||||||
if len(labels) == 0 {
|
if len(labels) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
//
|
|
||||||
for _, validLabel := range usage.Labels {
|
for _, validLabel := range usage.Labels {
|
||||||
for _, label := range labels {
|
for _, label := range labels {
|
||||||
if label == validLabel {
|
if label == validLabel {
|
||||||
@@ -146,8 +145,6 @@ func AddKeyFromRecord(record passvault.PasswordRecord, name, password string, us
|
|||||||
|
|
||||||
// get decryption keys
|
// get decryption keys
|
||||||
switch record.Type {
|
switch record.Type {
|
||||||
case passvault.AESRecord:
|
|
||||||
current.aesKey, err = record.GetKeyAES(password)
|
|
||||||
case passvault.RSARecord:
|
case passvault.RSARecord:
|
||||||
current.rsaKey, err = record.GetKeyRSA(password)
|
current.rsaKey, err = record.GetKeyRSA(password)
|
||||||
case passvault.ECCRecord:
|
case passvault.ECCRecord:
|
||||||
@@ -171,32 +168,9 @@ func AddKeyFromRecord(record passvault.PasswordRecord, name, password string, us
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptKey encrypts a 16 byte key using the cached key corresponding to name.
|
// EncryptKey encrypts a 16 byte key using the cached key corresponding to name.
|
||||||
// For AES keys, use the cached key.
|
func EncryptKey(in []byte, name string, aesKey []byte) (out []byte, err error) {
|
||||||
// For RSA and EC keys, the cache is not necessary; use the override
|
|
||||||
// key instead.
|
|
||||||
func EncryptKey(in []byte, name string, override []byte) (out []byte, err error) {
|
|
||||||
Refresh()
|
Refresh()
|
||||||
|
|
||||||
aesKey := override
|
|
||||||
|
|
||||||
// if the override key is not set, extract from the cache
|
|
||||||
if aesKey == nil {
|
|
||||||
encryptKey, ok := matchUser(name, name, []string{})
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("Key not delegated")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch encryptKey.Type {
|
|
||||||
case passvault.AESRecord:
|
|
||||||
aesKey = encryptKey.aesKey
|
|
||||||
|
|
||||||
default:
|
|
||||||
return out, errors.New("Require override for key")
|
|
||||||
}
|
|
||||||
|
|
||||||
useKey(name, name, []string{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// encrypt
|
// encrypt
|
||||||
aesSession, err := aes.NewCipher(aesKey)
|
aesSession, err := aes.NewCipher(aesKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -209,8 +183,7 @@ func EncryptKey(in []byte, name string, override []byte) (out []byte, err error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptKey decrypts a 16 byte key using the key corresponding to the name parameter
|
// DecryptKey decrypts a 16 byte key using the key corresponding to the name parameter
|
||||||
// for AES keys, the cached AES key is used directly to decrypt in
|
// For RSA and EC keys, the cached RSA/EC key is used to decrypt
|
||||||
// for RSA and EC keys, the cached RSA/EC key is used to decrypt
|
|
||||||
// the pubEncryptedKey which is then used to decrypt the input
|
// the pubEncryptedKey which is then used to decrypt the input
|
||||||
// buffer.
|
// buffer.
|
||||||
func DecryptKey(in []byte, name, user string, labels []string, pubEncryptedKey []byte) (out []byte, err error) {
|
func DecryptKey(in []byte, name, user string, labels []string, pubEncryptedKey []byte) (out []byte, err error) {
|
||||||
@@ -225,9 +198,6 @@ func DecryptKey(in []byte, name, user string, labels []string, pubEncryptedKey [
|
|||||||
|
|
||||||
// pick the aesKey to use for decryption
|
// pick the aesKey to use for decryption
|
||||||
switch decryptKey.Type {
|
switch decryptKey.Type {
|
||||||
case passvault.AESRecord:
|
|
||||||
aesKey = decryptKey.aesKey
|
|
||||||
|
|
||||||
case passvault.RSARecord:
|
case passvault.RSARecord:
|
||||||
// extract the aes key from the pubEncryptedKey
|
// extract the aes key from the pubEncryptedKey
|
||||||
aesKey, err = rsa.DecryptOAEP(sha1.New(), rand.Reader, &decryptKey.rsaKey, pubEncryptedKey, nil)
|
aesKey, err = rsa.DecryptOAEP(sha1.New(), rand.Reader, &decryptKey.rsaKey, pubEncryptedKey, nil)
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import (
|
|||||||
|
|
||||||
// Constants for record type
|
// Constants for record type
|
||||||
const (
|
const (
|
||||||
AESRecord = "AES"
|
|
||||||
RSARecord = "RSA"
|
RSARecord = "RSA"
|
||||||
ECCRecord = "ECC"
|
ECCRecord = "ECC"
|
||||||
)
|
)
|
||||||
@@ -74,7 +73,6 @@ type PasswordRecord struct {
|
|||||||
PasswordSalt []byte
|
PasswordSalt []byte
|
||||||
HashedPassword []byte
|
HashedPassword []byte
|
||||||
KeySalt []byte
|
KeySalt []byte
|
||||||
AESKey []byte
|
|
||||||
RSAKey struct {
|
RSAKey struct {
|
||||||
RSAExp []byte
|
RSAExp []byte
|
||||||
RSAExpIV []byte
|
RSAExpIV []byte
|
||||||
@@ -221,16 +219,6 @@ func createPasswordRec(password string, admin bool) (newRec PasswordRecord, err
|
|||||||
newRec.ECKey.ECPublic.Y = ecPriv.PublicKey.Y
|
newRec.ECKey.ECPublic.Y = ecPriv.PublicKey.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt AES key with password key
|
|
||||||
aesKey, err := symcrypt.MakeRandom(16)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if newRec.AESKey, err = encryptECB(aesKey, passKey); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
newRec.Admin = admin
|
newRec.Admin = admin
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -301,11 +289,6 @@ func InitFromDisk(path string) error {
|
|||||||
if len(rec.KeySalt) != 16 {
|
if len(rec.KeySalt) != 16 {
|
||||||
return formatErr
|
return formatErr
|
||||||
}
|
}
|
||||||
if rec.Type == AESRecord {
|
|
||||||
if len(rec.AESKey) != 16 {
|
|
||||||
return formatErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if rec.Type == RSARecord {
|
if rec.Type == RSARecord {
|
||||||
if len(rec.RSAKey.RSAExp) == 0 || len(rec.RSAKey.RSAExp)%16 != 0 {
|
if len(rec.RSAKey.RSAExp) == 0 || len(rec.RSAKey.RSAExp)%16 != 0 {
|
||||||
return formatErr
|
return formatErr
|
||||||
@@ -327,7 +310,10 @@ func InitFromDisk(path string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if rec.Type == ECCRecord {
|
if rec.Type == ECCRecord {
|
||||||
if len(rec.ECKey.ECPriv) == 0 {
|
if len(rec.ECKey.ECPriv) == 0 || len(rec.ECKey.ECPriv)%16 != 0 {
|
||||||
|
return formatErr
|
||||||
|
}
|
||||||
|
if len(rec.ECKey.ECPrivIV) != 16 {
|
||||||
return formatErr
|
return formatErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,30 +371,6 @@ func ChangePassword(name, password, newPassword string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrypt key
|
|
||||||
var key []byte
|
|
||||||
var rsaKey rsa.PrivateKey
|
|
||||||
var ecKey *ecdsa.PrivateKey
|
|
||||||
if pr.Type == AESRecord {
|
|
||||||
key, err = pr.GetKeyAES(password)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if pr.Type == RSARecord {
|
|
||||||
rsaKey, err = pr.GetKeyRSA(password)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if pr.Type == ECCRecord {
|
|
||||||
ecKey, err = pr.GetKeyECC(password)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = errors.New("Unkown record type")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the password salt and hash
|
// add the password salt and hash
|
||||||
if pr.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
|
if pr.PasswordSalt, err = symcrypt.MakeRandom(16); err != nil {
|
||||||
return
|
return
|
||||||
@@ -425,19 +387,26 @@ func ChangePassword(name, password, newPassword string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt original key with new password
|
// decrypt with old password and re-encrypt original key with new password
|
||||||
if pr.Type == AESRecord {
|
if pr.Type == RSARecord {
|
||||||
pr.AESKey, err = encryptECB(key, newPassKey)
|
var rsaKey rsa.PrivateKey
|
||||||
|
rsaKey, err = pr.GetKeyRSA(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if pr.Type == RSARecord {
|
|
||||||
// encrypt RSA key with password key
|
// encrypt RSA key with password key
|
||||||
err = encryptRSARecord(&pr, &rsaKey, newPassKey)
|
err = encryptRSARecord(&pr, &rsaKey, newPassKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if pr.Type == ECCRecord {
|
} else if pr.Type == ECCRecord {
|
||||||
|
var ecKey *ecdsa.PrivateKey
|
||||||
|
ecKey, err = pr.GetKeyECC(password)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// encrypt ECDSA key with password key
|
// encrypt ECDSA key with password key
|
||||||
err = encryptECCRecord(&pr, ecKey, newPassKey)
|
err = encryptECCRecord(&pr, ecKey, newPassKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -458,9 +427,9 @@ func DeleteRecord(name string) error {
|
|||||||
if _, ok := GetRecord(name); ok {
|
if _, ok := GetRecord(name); ok {
|
||||||
delete(records.Passwords, name)
|
delete(records.Passwords, name)
|
||||||
return WriteRecordsToDisk()
|
return WriteRecordsToDisk()
|
||||||
|
} else {
|
||||||
|
return errors.New("Record missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("Record missing")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevokeRecord removes admin status from a record.
|
// RevokeRecord removes admin status from a record.
|
||||||
@@ -469,9 +438,9 @@ func RevokeRecord(name string) error {
|
|||||||
rec.Admin = false
|
rec.Admin = false
|
||||||
SetRecord(rec, name)
|
SetRecord(rec, name)
|
||||||
return WriteRecordsToDisk()
|
return WriteRecordsToDisk()
|
||||||
|
} else {
|
||||||
|
return errors.New("Record missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("Record missing")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeAdmin adds admin status to a given record.
|
// MakeAdmin adds admin status to a given record.
|
||||||
@@ -480,9 +449,9 @@ func MakeAdmin(name string) error {
|
|||||||
rec.Admin = true
|
rec.Admin = true
|
||||||
SetRecord(rec, name)
|
SetRecord(rec, name)
|
||||||
return WriteRecordsToDisk()
|
return WriteRecordsToDisk()
|
||||||
|
} else {
|
||||||
|
return errors.New("Record missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("Record missing")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRecord puts a record into the global status.
|
// SetRecord puts a record into the global status.
|
||||||
@@ -500,18 +469,18 @@ func GetRecord(name string) (PasswordRecord, bool) {
|
|||||||
func GetVaultId() (id int, err error) {
|
func GetVaultId() (id int, err error) {
|
||||||
if !IsInitialized() {
|
if !IsInitialized() {
|
||||||
return 0, errors.New("Path not initialized")
|
return 0, errors.New("Path not initialized")
|
||||||
|
} else {
|
||||||
|
return records.VaultId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return records.VaultId, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHmacKey returns the hmac key of the current vault.
|
// GetHmacKey returns the hmac key of the current vault.
|
||||||
func GetHmacKey() (key []byte, err error) {
|
func GetHmacKey() (key []byte, err error) {
|
||||||
if !IsInitialized() {
|
if !IsInitialized() {
|
||||||
return nil, errors.New("Path not initialized")
|
return nil, errors.New("Path not initialized")
|
||||||
|
} else {
|
||||||
|
return records.HmacKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return records.HmacKey, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsInitialized returns true if the disk vault has been loaded.
|
// IsInitialized returns true if the disk vault has been loaded.
|
||||||
@@ -554,39 +523,22 @@ func (pr PasswordRecord) EncryptKey(in []byte) (out []byte, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKeyAES returns the 16-byte key of the record.
|
|
||||||
func (pr PasswordRecord) GetKeyAES(password string) (key []byte, err error) {
|
|
||||||
if pr.Type != AESRecord {
|
|
||||||
return nil, errors.New("Invalid function for record type")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = pr.ValidatePassword(password)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
passKey, err := derivePasswordKey(password, pr.KeySalt)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return decryptECB(pr.AESKey, passKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetKeyRSAPub returns the RSA public key of the record.
|
// GetKeyRSAPub returns the RSA public key of the record.
|
||||||
func (pr PasswordRecord) GetKeyRSAPub() (out *rsa.PublicKey, err error) {
|
func (pr PasswordRecord) GetKeyRSAPub() (out *rsa.PublicKey, err error) {
|
||||||
if pr.Type != RSARecord {
|
if pr.Type != RSARecord {
|
||||||
return out, errors.New("Invalid function for record type")
|
return out, errors.New("Invalid function for record type")
|
||||||
|
} else {
|
||||||
|
return &pr.RSAKey.RSAPublic, err
|
||||||
}
|
}
|
||||||
return &pr.RSAKey.RSAPublic, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKeyECCPub returns the ECDSA public key out of the record.
|
// GetKeyECCPub returns the ECDSA public key out of the record.
|
||||||
func (pr PasswordRecord) GetKeyECCPub() (out *ecdsa.PublicKey, err error) {
|
func (pr PasswordRecord) GetKeyECCPub() (out *ecdsa.PublicKey, err error) {
|
||||||
if pr.Type != ECCRecord {
|
if pr.Type != ECCRecord {
|
||||||
return out, errors.New("Invalid function for record type")
|
return out, errors.New("Invalid function for record type")
|
||||||
|
} else {
|
||||||
|
return pr.ECKey.ECPublic.toECDSA(), err
|
||||||
}
|
}
|
||||||
return pr.ECKey.ECPublic.toECDSA(), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKeyECC returns the ECDSA private key of the record given the correct password.
|
// GetKeyECC returns the ECDSA private key of the record given the correct password.
|
||||||
@@ -675,13 +627,14 @@ func (pr PasswordRecord) GetKeyRSA(password string) (key rsa.PrivateKey, err err
|
|||||||
|
|
||||||
// ValidatePassword returns an error if the password is incorrect.
|
// ValidatePassword returns an error if the password is incorrect.
|
||||||
func (pr PasswordRecord) ValidatePassword(password string) error {
|
func (pr PasswordRecord) ValidatePassword(password string) error {
|
||||||
if h, err := hashPassword(password, pr.PasswordSalt); err != nil {
|
h, err := hashPassword(password, pr.PasswordSalt)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
if bytes.Compare(h, pr.HashedPassword) != 0 {
|
|
||||||
return errors.New("Wrong Password")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if bytes.Compare(h, pr.HashedPassword) != 0 {
|
||||||
|
return errors.New("Wrong Password")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user