vey

package module
v0.0.0-...-9d56a58 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2022 License: BSD-3-Clause Imports: 16 Imported by: 0

README

Vey - Email Verifying Keyserver

Vey is an Email Verifying Keyserver. It is an HTTP API server that provides APIs to get, delete and put public keys for verified email addresses.

Saving a public key requires access to the email address and the private key. You prove that you have access to the email address and the private key by receiving a challenge in email and signing it with the private key.

Deleting a key requires access to the email address. You have to be able to receive an email that includes a token.

Goals

  • Do not store emails
  • Realistic authentication to put and delete your keys

Interface

The rough idea of Vey's interface.

// Vey represent the public API of Email Verifying Keyserver.
// Structs that implement Vey interface may use Cache, Verifier, Store interface to implement the API.
type Vey interface {
	GetKeys(email string) ([]PublicKey, error)
	BeginDelete(email string, publicKey PublicKey) (token []byte, err error)
	CommitDelete(token []byte) error
	BeginPut(email string, publicKey PublicKey) (challenge []byte, err error)
	CommitPut(challenge, signature []byte) error
}

// Cache is a short-term key value store.
type Cache interface {
	Set([]byte, Cached) error
	Get([]byte) (Cached, error)
	Del([]byte) error
}

type Cached struct {
	EmailDigest
	PublicKey
}

// Verifier verifies the signature with the public key.
type Verifier interface {
	Verify(publicKey PublicKey, signature, challenge []byte) bool
}

// Store stores the public keys for a given email address hash.
// We do not have to store the email. The hash of it is enough.
type Store interface {
	Get(EmailDigest) ([]PublicKey, error)
	Delete(EmailDigest, PublicKey) error
	Put(EmailDigest, PublicKey) error
}

type PublicKeyType int

const (
	SSHEd25519 PublicKeyType = iota
)

type PublicKey struct {
	PublicKey []byte
	Type      PublicKeyType
}

// EmailDigest is a hash of an email address.
type EmailDigest string

// Digester takes an email and returns a hash of it.
type Digester interface {
	Of(email string) EmailDigest
}

Vey?

From "Verify Email keYserver". Pronounce like "Hey" replacing H with V.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound indicates that the token or challenge is not found in the cache, or it has expired.
	ErrNotFound = errors.New("not found")
	// ErrVerifyFailed indicates that the signature is invalid.
	ErrVerifyFailed = errors.New("verify failed")
	ErrInvalidEmail = errors.New("invalid email")
)

Functions

func IsNotFound

func IsNotFound(err error) bool

func NewChallenge

func NewChallenge() ([]byte, error)

func NewToken

func NewToken() ([]byte, error)

func VeyTest

func VeyTest(t *testing.T, v Vey)

VeyTest tests the Vey interface. v's cache should be configured to expire in a second. VeyTest includes expiry tests.

Types

type Cache

type Cache interface {
	Set([]byte, Cached) error
	Get([]byte) (Cached, error)
	Del([]byte) error
}

Cache is a short-term key value store.

func NewDynamoDbCache

func NewDynamoDbCache(tableName string, svc *dynamodb.DynamoDB, expiresIn time.Duration) Cache

NewDynamoDbCache creates a new Cache implementation that is backed by DynamoDB. expiresIn is the duration after which the item expires, using DynamoDB TTL.

func NewMemCache

func NewMemCache(expiresIn time.Duration) Cache

type Cached

type Cached struct {
	EmailDigest
	PublicKey
}

type Digest

type Digest struct {
	// contains filtered or unexported fields
}

Digest implements Digester interface.

func (Digest) Of

func (d Digest) Of(email string) EmailDigest

type Digester

type Digester interface {
	Of(email string) EmailDigest
}

Digester takes an email and returns a hash of it.

func NewDigester

func NewDigester(salt []byte) Digester

type DynamoDbCache

type DynamoDbCache struct {
	TableName string
	D         *dynamodb.DynamoDB
	// contains filtered or unexported fields
}

func (*DynamoDbCache) Del

func (s *DynamoDbCache) Del(b []byte) error

func (*DynamoDbCache) Get

func (s *DynamoDbCache) Get(b []byte) (Cached, error)

func (*DynamoDbCache) Set

func (s *DynamoDbCache) Set(b []byte, cached Cached) error

Set caches the value for the key.

type DynamoDbCacheItem

type DynamoDbCacheItem struct {
	ID     []byte
	Cached Cached
	// ExpiresAt is used by DynamoDB TTL to expire the item after DynamoDbCache.expiresIn duration.
	ExpiresAt time.Time `dynamodbav:",unixtime"`
}

DynamoDbCacheItem represents a single item in the DynamoDB cache table.

type DynamoDbStore

type DynamoDbStore struct {
	TableName string
	D         *dynamodb.DynamoDB
}

func (*DynamoDbStore) Delete

func (s *DynamoDbStore) Delete(d EmailDigest, publicKey PublicKey) error

Delete atomically deletes the public key from the set of public keys for the email digest.

func (*DynamoDbStore) Get

func (s *DynamoDbStore) Get(d EmailDigest) ([]PublicKey, error)

func (*DynamoDbStore) Put

func (s *DynamoDbStore) Put(d EmailDigest, publicKey PublicKey) error

Put atomically adds the public key in the set of public keys for the email digest.

type DynamoDbStoreItem

type DynamoDbStoreItem struct {
	ID []byte
	// PublicKeys is a set of PublicKeys marshalled into []byte.
	// The first byte is the PublicKey.Type and the rest is the PublicKey.Key .
	PublicKeys [][]byte `dynamodbav:"publickeys,omitempty,binaryset"`
}

DynamoDbStoreItem represents a single item in the DynamoDB store table.

func (DynamoDbStoreItem) Keys

func (item DynamoDbStoreItem) Keys() ([]PublicKey, error)

type EmailDigest

type EmailDigest []byte

EmailDigest is a hash of an email address. EmailDigest is a []byte, it cannot be used as a map key.

type Logger

type Logger interface {
	Error(err error)
}

Logger logs errors.

var Log Logger = NewLogger()

Log is package global variable that holds Logger.

func NewLogger

func NewLogger() Logger

NewLogger returns a new default Logger that logs to stderr.

type MemCache

type MemCache struct {
	// contains filtered or unexported fields
}

MemCache implements Cache interface. MemCache is for testing purposes only. MemCache lacks expiry.

func (*MemCache) Del

func (c *MemCache) Del(key []byte) error

func (*MemCache) Get

func (c *MemCache) Get(key []byte) (Cached, error)

func (*MemCache) Set

func (c *MemCache) Set(key []byte, val Cached) error

type MemStore

type MemStore struct {
	// contains filtered or unexported fields
}

func (*MemStore) Delete

func (s *MemStore) Delete(d EmailDigest, publicKey PublicKey) error

func (*MemStore) Get

func (s *MemStore) Get(d EmailDigest) ([]PublicKey, error)

func (*MemStore) Put

func (s *MemStore) Put(d EmailDigest, publicKey PublicKey) error

type PublicKey

type PublicKey struct {
	// Key is in OpenSSH authorized_keys format.
	// SSHEd25519 is only supported now, so Key should start with "ssh-ed25519 ".
	Key  []byte        `json:"key"`
	Type PublicKeyType `json:"type"`
}

func (PublicKey) Equal

func (pub PublicKey) Equal(x PublicKey) bool

Equal reports whether priv and x have the same value.

type PublicKeyType

type PublicKeyType int
const (
	SSHEd25519 PublicKeyType = iota
)

type SSHEd25519Verifier

type SSHEd25519Verifier struct{}

SSHEd25519Verifier implements Verifier interface.

func (SSHEd25519Verifier) Verify

func (v SSHEd25519Verifier) Verify(pub PublicKey, signature, challenge []byte) bool

type Store

type Store interface {
	Get(EmailDigest) ([]PublicKey, error)
	Delete(EmailDigest, PublicKey) error
	Put(EmailDigest, PublicKey) error
}

Store stores a unique set of public keys for a given email address hash. We do not have to store the email. The hash of it is enough.

func NewDynamoDbStore

func NewDynamoDbStore(tableName string, svc *dynamodb.DynamoDB) Store

func NewMemStore

func NewMemStore() Store

type Verifier

type Verifier interface {
	Verify(publicKey PublicKey, signature, challenge []byte) bool
}

Verifier verifies the signature with the public key.

func NewVerifier

func NewVerifier(t PublicKeyType) Verifier

type Vey

type Vey interface {
	GetKeys(email string) ([]PublicKey, error)
	BeginDelete(email string, publicKey PublicKey) (token []byte, err error)
	CommitDelete(token []byte) error
	BeginPut(email string, publicKey PublicKey) (challenge []byte, err error)
	CommitPut(challenge, signature []byte) error
}

Vey represent the public API of Email Verifying Keyserver. Structs that implement Vey interface may use Cache, Verifier, Store interface to implement the API.

func NewVey

func NewVey(digest Digester, cache Cache, store Store) Vey

Directories

Path Synopsis
cmd
vey

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL