Documentation
¶
Index ¶
- Constants
- Variables
- func SetGhostifyer(gh Ghostifyer) error
- type GhostString
- func (gs *GhostString) Equal(other *GhostString) bool
- func (gs *GhostString) GoString() string
- func (gs *GhostString) IsValid() bool
- func (gs *GhostString) MarshalBinary() ([]byte, error)
- func (gs *GhostString) MarshalJSON() ([]byte, error)
- func (gs *GhostString) MarshalText() ([]byte, error)
- func (gs *GhostString) String() string
- func (gs *GhostString) UnmarshalBinary(b []byte) error
- func (gs *GhostString) UnmarshalJSON(b []byte) error
- func (gs *GhostString) UnmarshalText(b []byte) error
- type Ghostifyer
- type KeyStore
- type TimestampedKey
Examples ¶
Constants ¶
const ( NamespaceMatchRegexp = "^[a-zA-Z][-\\._a-zA-Z0-9]{1,254}[a-zA-Z0-9]$" NamespaceSeparator = "::" Prefix = "👻:" Nonce = 12 )
const (
EnvKeyStoreKeyPrefix = "GHOSTSTRING_KEY_{{.Namespace}}_"
)
Variables ¶
var (
Err = errors.New("ghoststring error")
)
Functions ¶
func SetGhostifyer ¶
func SetGhostifyer(gh Ghostifyer) error
Types ¶
type GhostString ¶
GhostString wraps a string with a JSON marshaller that uses a namespace-scoped encrypting Ghostifyer registered via SetGhostifyer
Example ¶
package main
import (
"encoding/json"
"fmt"
"regexp"
"strings"
"time"
"github.com/rstudio/ghoststring"
)
func main() {
gh, err := ghoststring.NewAES256GCMSingleKeyGhostifyer(
"example",
"correct horse battery staple",
)
if err != nil {
panic(err)
}
if err := ghoststring.SetGhostifyer(gh); err != nil {
panic(err)
}
type DiaryEntry struct {
Timestamp time.Time `json:"timestamp"`
Text ghoststring.GhostString `json:"text"`
}
type Diary struct {
Author string `json:"author"`
Entries []DiaryEntry `json:"entries"`
}
enc, err := json.MarshalIndent(
&Diary{
Author: "Eagerly Anticipated",
Entries: []DiaryEntry{
{
Timestamp: time.UnixMicro(4),
Text: ghoststring.GhostString{
Namespace: "example",
Str: "Nights without you are so dark. I pray that someday you will return my flashlight.",
},
},
{
Timestamp: time.UnixMicro(-8001),
Text: ghoststring.GhostString{
Namespace: "unknown",
Str: "We may never know.",
},
},
},
},
"",
" ",
)
if err != nil {
panic(err)
}
encString := string(enc)
if strings.Contains(encString, "We may never know.") || strings.Contains(encString, "Nights without you") {
panic("not ghostly enough: contains cleartext")
}
if !strings.Contains(encString, `"text": ""`) {
panic("not ghostly enough: lacking empty ghoststring")
}
if matched, err := regexp.MatchString(`.+"text": "👻:[^"]+"`, encString); !matched || err != nil {
panic("not ghostly enough: lacking non-empty ghoststring")
}
fmt.Println("no peeking")
}
Output: no peeking
func (*GhostString) Equal ¶
func (gs *GhostString) Equal(other *GhostString) bool
Equal compares this GhostString to another
func (*GhostString) GoString ¶ added in v0.3.0
func (gs *GhostString) GoString() string
func (*GhostString) IsValid ¶
func (gs *GhostString) IsValid() bool
IsValid checks that the wrapped string value is non-empty and the namespace is valid
func (*GhostString) MarshalBinary ¶ added in v0.3.0
func (gs *GhostString) MarshalBinary() ([]byte, error)
MarshalBinary allows GhostString to fulfill the encoding.BinaryMarshaler interface
func (*GhostString) MarshalJSON ¶
func (gs *GhostString) MarshalJSON() ([]byte, error)
MarshalJSON allows GhostString to fulfill the json.Marshaler interface. The lack of a namespace is considered an error.
func (*GhostString) MarshalText ¶ added in v0.3.0
func (gs *GhostString) MarshalText() ([]byte, error)
MarshalText allows GhostString to fulfill the encoding.TextMarshaler interface
func (*GhostString) String ¶
func (gs *GhostString) String() string
func (*GhostString) UnmarshalBinary ¶ added in v0.3.0
func (gs *GhostString) UnmarshalBinary(b []byte) error
UnmarshalBinary allows GhostString to fulfill the encoding.BinaryUnmarshaler interface
func (*GhostString) UnmarshalJSON ¶
func (gs *GhostString) UnmarshalJSON(b []byte) error
UnmarshalJSON allows GhostString to fulfill the json.Unmarshaler interface. The bytes are first unmarshaled as a string and then if non-empty are passed through an "unghostify" step. The expected structure of a marshalled GhostString is:
"{Prefix}base64({nonce}{namespace}{NamespaceSeparator}{opaque-value})"
where {nonce} has the length specified as Nonce.
func (*GhostString) UnmarshalText ¶ added in v0.3.0
func (gs *GhostString) UnmarshalText(b []byte) error
UnmarshalText allows GhostString to fulfill the encoding.TextUnmarshaler interface
type Ghostifyer ¶
type Ghostifyer interface {
Namespace() string
Ghostify(*GhostString) (string, error)
Unghostify(string) (*GhostString, error)
}
Ghostifyer encodes a GhostString into a string representation.
func NewAES256GCMMultiKeyGhostifyer ¶ added in v0.5.0
func NewAES256GCMMultiKeyGhostifyer(namespace string, keys KeyStore) Ghostifyer
NewAES256GCMMultiKeyGhostifyer creates a Ghostifyer with multiple timestamped keys that uses AES-256-GCM encryption with nonce assigned at the individual string level. The keystore.Latest will be used for encryption and any key in keystore.All may be used for decryption.
func NewAES256GCMSingleKeyGhostifyer ¶ added in v0.3.0
func NewAES256GCMSingleKeyGhostifyer(namespace, key string) (Ghostifyer, error)
NewAES256GCMSingleKeyGhostifyer creates a Ghostifyer with a single key that uses AES-256-GCM encryption with nonce assigned at the individual string level.
type KeyStore ¶ added in v0.5.0
type KeyStore interface {
Latest(ctx context.Context) ([]byte, error)
All(ctx context.Context) ([][]byte, error)
}
func NewKeyStore ¶ added in v0.5.0
func NewKeyStore(namespace string, keys []*TimestampedKey) (KeyStore, error)
type TimestampedKey ¶ added in v0.5.0
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
ghoststring
command
|
|
|
internal
|
|
|
cmd/myths
command
|
|
|
cmd/rectangles
command
|