-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathencrypted_bytes.go
More file actions
128 lines (104 loc) · 2.4 KB
/
Copy pathencrypted_bytes.go
File metadata and controls
128 lines (104 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package sqlcrypter
import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
func NewEncryptedBytes(s string) EncryptedBytes {
e := &EncryptedBytes{}
if s == "" {
return []byte(nil)
}
*e = []byte(s)
return *e
}
type EncryptedBytes []byte
func (e *EncryptedBytes) GormDataType() string {
return "encryptedbytes"
}
func (e *EncryptedBytes) GormDBDataType(db *gorm.DB, field *schema.Field) string {
switch db.Name() {
case "mysql":
return "binary"
case "postgres":
return "bytea"
case "sqlite":
return "blob"
case "sqlserver":
return "varbinary"
default:
return ""
}
}
// String intentionally returns a redacted placeholder to
// safeguard the plaintext from being inadventerly leaked
// in logs, stack traces, etc.
//
// To deliberately access the plaintext, call Plaintext() or Bytes().
func (e EncryptedBytes) String() string {
return "[REDACTED]"
}
// Plaintext returns the decrypted contents as a string.
//
// It is the caller's responsibility to ensure this value is
// not logged or otherwise exposed.
func (e EncryptedBytes) Plaintext() string {
return string(e)
}
func (e EncryptedBytes) Bytes() []byte {
return e[:]
}
// Scan implements the scanner interface
func (e *EncryptedBytes) Scan(value any) error {
b, ok := value.([]byte)
if !ok {
return errors.New("failed to read value as bytes")
}
// Dont attempt to decrypt if value is nil
if b == nil {
return nil
}
// Decrypt value to e
pt, err := decryptCiphertextBytes(b)
if err != nil {
return err
}
*e = pt
return nil
}
// Value implements the valuer interface
func (e EncryptedBytes) Value() (driver.Value, error) {
// nil will be stored as null in the database
if len(e) == 0 {
var b []byte
return b, nil
}
return encryptPlaintextBytes(e)
}
// MarshalJSON implements json.Marshaler interface
func (e EncryptedBytes) MarshalJSON() ([]byte, error) {
v, err := e.Value()
if err != nil {
return nil, err
}
return json.Marshal(v)
}
// UnmarshalJSON implements json.Unmarshaler interface
func (e *EncryptedBytes) UnmarshalJSON(data []byte) error {
var b []byte
if err := json.Unmarshal(data, &b); err != nil {
return err
}
return e.Scan(b)
}
var (
_ driver.Valuer = &EncryptedBytes{}
_ sql.Scanner = &EncryptedBytes{}
_ json.Marshaler = &EncryptedBytes{}
_ json.Unmarshaler = &EncryptedBytes{}
_ fmt.Stringer = &EncryptedBytes{}
)