Skip to content

Commit

Permalink
Merge pull request #8 from 42wim/master
Browse files Browse the repository at this point in the history
Add support for entropy
  • Loading branch information
billgraziano committed Oct 18, 2020
2 parents d54791e + a6aaeb7 commit 41a2012
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 15 deletions.
72 changes: 59 additions & 13 deletions dpapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@ func (b *dataBlob) free() error {

// Encrypt a string value to a base64 string
func Encrypt(secret string) (string, error) {
return encrypt(secret, cryptProtectUIForbidden)
return encrypt(secret, "", cryptProtectUIForbidden)
}

func encrypt(secret string, cf cryptProtect) (string, error) {
func EncryptEntropy(secret, entropy string) (string, error) {
return encrypt(secret, entropy, cryptProtectUIForbidden)
}

func encrypt(secret, entropy string, cf cryptProtect) (string, error) {
var result string
var b []byte
b, err := encryptBytes([]byte(secret), cf)
b, err := encryptBytes([]byte(secret), []byte(entropy), cf)
if err != nil {
return result, errors.Wrap(err, "encryptbytes")
}
Expand All @@ -75,12 +79,25 @@ func encrypt(secret string, cf cryptProtect) (string, error) {

// EncryptBytes encrypts a byte array and returns a byte array
func EncryptBytes(data []byte) ([]byte, error) {
return encryptBytes(data, cryptProtectUIForbidden)
return encryptBytes(data, nil, cryptProtectUIForbidden)
}

func encryptBytes(data []byte, cf cryptProtect) ([]byte, error) {
var outblob dataBlob
r, _, err := procEncryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, uintptr(cf), uintptr(unsafe.Pointer(&outblob)))
func EncryptBytesEntropy(data, entropy []byte) ([]byte, error) {
return encryptBytes(data, entropy, cryptProtectUIForbidden)
}

func encryptBytes(data []byte, entropy []byte, cf cryptProtect) ([]byte, error) {
var (
outblob dataBlob
r uintptr
err error
)

if len(entropy) > 0 {
r, _, err = procEncryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, uintptr(unsafe.Pointer(newBlob(entropy))), 0, 0, uintptr(cf), uintptr(unsafe.Pointer(&outblob)))
} else {
r, _, err = procEncryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, uintptr(cf), uintptr(unsafe.Pointer(&outblob)))
}
if r == 0 {
return nil, errors.Wrap(err, "procencryptdata")
}
Expand All @@ -92,19 +109,35 @@ func encryptBytes(data []byte, cf cryptProtect) ([]byte, error) {
// EncryptBytesMachineLocal encrypts a byte array and returns a byte array and associates the data
// encrypted with the current computer instead of with an individual user.
func EncryptBytesMachineLocal(data []byte) ([]byte, error) {
return encryptBytes(data, cryptProtectUIForbidden|cryptProtectLocalMachine)
return encryptBytes(data, nil, cryptProtectUIForbidden|cryptProtectLocalMachine)
}

func EncryptBytesMachineLocalEntropy(data, entropy []byte) ([]byte, error) {
return encryptBytes(data, entropy, cryptProtectUIForbidden|cryptProtectLocalMachine)
}

// EncryptMachineLocal a string value to a base64 string and associates the data encrypted with the
// current computer instead of with an individual user.
func EncryptMachineLocal(secret string) (string, error) {
return encrypt(secret, cryptProtectUIForbidden|cryptProtectLocalMachine)
return encrypt(secret, "", cryptProtectUIForbidden|cryptProtectLocalMachine)
}

func EncryptMachineLocalEntropy(secret, entropy string) (string, error) {
return encrypt(secret, entropy, cryptProtectUIForbidden|cryptProtectLocalMachine)
}

// DecryptBytes decrypts a byte array returning a byte array
func DecryptBytes(data []byte) ([]byte, error) {
var outblob dataBlob
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, uintptr(cryptProtectUIForbidden), uintptr(unsafe.Pointer(&outblob)))
func decryptBytes(data, entropy []byte, cf cryptProtect) ([]byte, error) {
var (
outblob dataBlob
r uintptr
err error
)
if len(entropy) > 0 {
r, _, err = procDecryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, uintptr(unsafe.Pointer(newBlob(entropy))), 0, 0, uintptr(cf), uintptr(unsafe.Pointer(&outblob)))
} else {
r, _, err = procDecryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, uintptr(cf), uintptr(unsafe.Pointer(&outblob)))
}
if r == 0 {
return nil, errors.Wrap(err, "procdecryptdata")
}
Expand All @@ -116,12 +149,25 @@ func DecryptBytes(data []byte) ([]byte, error) {

// Decrypt a string to a string
func Decrypt(data string) (string, error) {
return DecryptEntropy(data, "")
}

// EncryptBytes encrypts a byte array and returns a byte array
func DecryptBytes(data []byte) ([]byte, error) {
return decryptBytes(data, nil, cryptProtectUIForbidden)
}

func DecryptBytesEntropy(data, entropy []byte) ([]byte, error) {
return decryptBytes(data, entropy, cryptProtectUIForbidden)
}

func DecryptEntropy(data, entropy string) (string, error) {
raw, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return "", errors.Wrap(err, "decodestring")
}

b, err := DecryptBytes(raw)
b, err := decryptBytes(raw, []byte(entropy), cryptProtectUIForbidden)
if err != nil {
return "", errors.Wrap(err, "decryptbytes")
}
Expand Down
59 changes: 57 additions & 2 deletions dpapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
func TestString(t *testing.T) {

secret := "Hello World!;"
entropy := "something"

enc, err := Encrypt(secret)
if err != nil {
t.Error("err from Encrypt: ", err)
Expand All @@ -20,11 +22,24 @@ func TestString(t *testing.T) {
if dec != secret {
t.Errorf("expected: '%s' got: '%s'", secret, dec)
}

enc, err = EncryptEntropy(secret, entropy)
if err != nil {
t.Error("err from EncryptEntropy: ", err)
}
dec, err = DecryptEntropy(enc, entropy)
if err != nil {
t.Error("err from DecryptEntropy: ", err)
}
if dec != secret {
t.Errorf("expected: '%s' got: '%s'", secret, dec)
}
}

func TestBytes(t *testing.T) {

secret := []byte("Hello World!;")
entropy := []byte("something")
enc, err := EncryptBytes(secret)
if err != nil {
t.Error("err from EncryptBytes: ", err)
Expand All @@ -37,11 +52,25 @@ func TestBytes(t *testing.T) {
if c != 0 {
t.Errorf("expected: '%s' got: '%s'", hex.EncodeToString(secret), hex.EncodeToString(dec))
}

enc, err = EncryptBytesEntropy(secret, entropy)
if err != nil {
t.Error("err from EncryptBytesEntropy: ", err)
}
dec, err = DecryptBytesEntropy(enc, entropy)
if err != nil {
t.Error("err from DecryptBytesEntropy: ", err)
}
c = bytes.Compare(dec, secret)
if c != 0 {
t.Errorf("expected: '%s' got: '%s'", hex.EncodeToString(secret), hex.EncodeToString(dec))
}
}

func TestMachineLocalString(t *testing.T) {

secret := "Hello World!;"
entropy := "something"
enc, err := EncryptMachineLocal(secret)
if err != nil {
t.Error("err from Encrypt: ", err)
Expand All @@ -53,11 +82,24 @@ func TestMachineLocalString(t *testing.T) {
if dec != secret {
t.Errorf("expected: '%s' got: '%s'", secret, dec)
}

enc, err = EncryptMachineLocalEntropy(secret, entropy)
if err != nil {
t.Error("err from EncryptMachineLocaleEntropy: ", err)
}
dec, err = DecryptEntropy(enc, entropy)
if err != nil {
t.Error("err from DecryptEntropy: ", err)
}
if dec != secret {
t.Errorf("expected: '%s' got: '%s'", secret, dec)
}
}

func TestMachineLocalBytes(t *testing.T) {

secret := []byte("Hello World!;")
entropy := []byte("something")
enc, err := EncryptBytesMachineLocal(secret)
if err != nil {
t.Error("err from EncryptBytesMachineLocal: ", err)
Expand All @@ -70,4 +112,17 @@ func TestMachineLocalBytes(t *testing.T) {
if c != 0 {
t.Errorf("expected: '%s' got: '%s'", hex.EncodeToString(secret), hex.EncodeToString(dec))
}
}

enc, err = EncryptBytesMachineLocalEntropy(secret, entropy)
if err != nil {
t.Error("err from EncryptBytesMachineLocalEntropy: ", err)
}
dec, err = DecryptBytesEntropy(enc, entropy)
if err != nil {
t.Error("err from DecryptBytesEntropy: ", err)
}
c = bytes.Compare(dec, secret)
if c != 0 {
t.Errorf("expected: '%s' got: '%s'", hex.EncodeToString(secret), hex.EncodeToString(dec))
}
}

0 comments on commit 41a2012

Please sign in to comment.