Documentation
¶
Index ¶
- Constants
- func SetConfig(c EnvConfig)
- type ApiKey
- func (k *ApiKey) Activate() error
- func (k *ApiKey) DecryptData(ciphertext []byte) ([]byte, error)
- func (k *ApiKey) DecryptLegacy(ciphertext string) (string, error)
- func (k *ApiKey) EncryptData(plaintext []byte) ([]byte, error)
- func (k *ApiKey) EncryptLegacy(plaintext string) (string, error)
- func (k *ApiKey) Hash() error
- func (k *ApiKey) IsCorrect(given string) error
- func (k *ApiKey) Load() error
- func (k *ApiKey) ReEncrypt(oldKey ApiKey, v *[]byte) error
- func (k *ApiKey) ReEncryptLegacy(oldKey ApiKey, v *string) error
- func (k *ApiKey) ReEncryptTOTPs(storage *Storage, oldKey ApiKey) (complete, incomplete int, err error)
- func (k *ApiKey) ReEncryptWebAuthnUser(storage *Storage, user WebauthnUser) error
- func (k *ApiKey) ReEncryptWebAuthnUsers(storage *Storage, oldKey ApiKey) (complete, incomplete int, err error)
- func (k *ApiKey) Save() error
- type App
- func (a *App) ActivateApiKey(w http.ResponseWriter, r *http.Request)
- func (a *App) BeginLogin(w http.ResponseWriter, r *http.Request)
- func (a *App) BeginRegistration(w http.ResponseWriter, r *http.Request)
- func (a *App) CreateApiKey(w http.ResponseWriter, r *http.Request)
- func (a *App) DeleteCredential(w http.ResponseWriter, r *http.Request)
- func (a *App) DeleteUser(w http.ResponseWriter, r *http.Request)
- func (a *App) FinishLogin(w http.ResponseWriter, r *http.Request)
- func (a *App) FinishRegistration(w http.ResponseWriter, r *http.Request)
- func (a *App) GetConfig() EnvConfig
- func (a *App) GetDB() *Storage
- func (a *App) RotateApiKey(w http.ResponseWriter, r *http.Request)
- type EnvConfig
- type Storage
- type TOTP
- type User
- type WebauthnMeta
- type WebauthnUser
- func (u *WebauthnUser) BeginLogin() (*protocol.CredentialAssertion, error)
- func (u *WebauthnUser) BeginRegistration() (*protocol.CredentialCreation, error)
- func (u *WebauthnUser) Delete() error
- func (u *WebauthnUser) DeleteCredential(credIDHash string) (int, error)
- func (u *WebauthnUser) FinishLogin(r *http.Request) (*webauthn.Credential, error)
- func (u *WebauthnUser) FinishRegistration(r *http.Request) (string, error)
- func (u *WebauthnUser) Load() error
- func (u *WebauthnUser) RemoveU2F()
- func (u *WebauthnUser) WebAuthnCredentials() []webauthn.Credential
- func (u *WebauthnUser) WebAuthnDisplayName() string
- func (u *WebauthnUser) WebAuthnID() []byte
- func (u *WebauthnUser) WebAuthnIcon() string
- func (u *WebauthnUser) WebAuthnName() string
Constants ¶
const ApiKeyTablePK = "value"
ApiKeyTablePK is the primary key in the ApiKey DynamoDB table
const IDParam = "id"
const LegacyU2FCredID = "u2f"
LegacyU2FCredID is a special case credential ID for legacy U2F support. At most one credential for each user may have this in its ID field.
const UserContextKey = "user"
UserContextKey is the context key that points to the authenticated user
const WebAuthnTablePK = "uuid"
WebAuthnTablePK is the primary key in the WebAuthn DynamoDB table
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ApiKey ¶
type ApiKey struct { Key string `dynamodbav:"value" json:"value"` Secret string `dynamodbav:"-" json:"-"` HashedSecret string `dynamodbav:"hashedApiSecret" json:"hashedApiSecret"` Email string `dynamodbav:"email" json:"email"` CreatedAt int `dynamodbav:"createdAt" json:"createdAt"` ActivatedAt int `dynamodbav:"activatedAt" json:"activatedAt"` Store *Storage `dynamodbav:"-" json:"-"` }
ApiKey holds API key data from DynamoDB
func (*ApiKey) Activate ¶
Activate an ApiKey. Creates a random string for the key secret and updates the Secret, HashedSecret, and ActivatedAt fields.
func (*ApiKey) DecryptData ¶
DecryptData uses the Secret to AES decrypt an arbitrary data block. It does not decrypt the key itself.
func (*ApiKey) DecryptLegacy ¶
DecryptLegacy uses the Secret to AES decrypt an arbitrary data block. This is intended only for legacy data such as U2F keys.
func (*ApiKey) EncryptData ¶
EncryptData uses the Secret to AES encrypt an arbitrary data block. It does not encrypt the key itself.
func (*ApiKey) EncryptLegacy ¶
EncryptLegacy uses the Secret to AES encrypt an arbitrary data block. This is intended only for legacy data such as U2F keys. The returned data is the Base64-encoded IV and the Base64-encoded cipher text separated by a colon.
func (*ApiKey) Hash ¶
Hash generates a bcrypt hash from the Secret field and stores it in HashedSecret
func (*ApiKey) IsCorrect ¶
IsCorrect returns true if and only if the key is active and the given string is a match for HashedSecret
func (*ApiKey) ReEncrypt ¶
ReEncrypt decrypts a data block with an old key, then encrypts the resulting plaintext with a new key
func (*ApiKey) ReEncryptLegacy ¶
ReEncryptLegacy decrypts a data block with an old key, then encrypts the resulting plaintext with a new key. This uses a legacy ciphertext format that is stored as Base64 strings.
func (*ApiKey) ReEncryptTOTPs ¶
func (k *ApiKey) ReEncryptTOTPs(storage *Storage, oldKey ApiKey) (complete, incomplete int, err error)
ReEncryptTOTPs loads each TOTP record that was encrypted using the old key, re-encrypts it using the new key, and writes the updated data back to the database.
func (*ApiKey) ReEncryptWebAuthnUser ¶
func (k *ApiKey) ReEncryptWebAuthnUser(storage *Storage, user WebauthnUser) error
ReEncryptWebAuthnUser re-encrypts a WebAuthnUser using the new key, and writes the updated data back to the database.
func (*ApiKey) ReEncryptWebAuthnUsers ¶
func (k *ApiKey) ReEncryptWebAuthnUsers(storage *Storage, oldKey ApiKey) (complete, incomplete int, err error)
ReEncryptWebAuthnUsers loads each WebAuthn record that was encrypted using the old key, re-encrypts it using the new key, and writes the updated data back to the database.
type App ¶
type App struct {
// contains filtered or unexported fields
}
func (*App) ActivateApiKey ¶
func (a *App) ActivateApiKey(w http.ResponseWriter, r *http.Request)
ActivateApiKey is the handler for the POST /api-key/activate endpoint. It creates the key secret and updates the database record.
func (*App) BeginLogin ¶
func (a *App) BeginLogin(w http.ResponseWriter, r *http.Request)
BeginLogin processes the first half of the Webauthn Authentication flow. It is the handler for the "POST /webauthn/login" endpoint, initiated by the client at the beginning of a login request.
func (*App) BeginRegistration ¶
func (a *App) BeginRegistration(w http.ResponseWriter, r *http.Request)
BeginRegistration processes the first half of the Webauthn Registration flow. It is the handler for the "POST /webauthn/register" endpoint, initiated by the client when creation of a new passkey is requested.
func (*App) CreateApiKey ¶
func (a *App) CreateApiKey(w http.ResponseWriter, r *http.Request)
CreateApiKey is the handler for the POST /api-key endpoint. It creates a new API Key and saves it to the database.
func (*App) DeleteCredential ¶
func (a *App) DeleteCredential(w http.ResponseWriter, r *http.Request)
DeleteCredential is the handler for the "DELETE /webauthn/credential/{credID}" endpoint. It removes a single passkey identified by "credID", which is the key_handle_hash returned by the FinishRegistration endpoint, or "u2f" if it is a legacy U2F credential.
func (*App) DeleteUser ¶
func (a *App) DeleteUser(w http.ResponseWriter, r *http.Request)
DeleteUser is the handler for the "DELETE /webauthn/user" endpoint. It removes a user and any stored passkeys owned by the user.
func (*App) FinishLogin ¶
func (a *App) FinishLogin(w http.ResponseWriter, r *http.Request)
FinishLogin processes the second half of the Webauthn Authentication flow. It is the handler for the "PUT /webauthn/login" endpoint, initiated by the client with login data signed with the private key.
func (*App) FinishRegistration ¶
func (a *App) FinishRegistration(w http.ResponseWriter, r *http.Request)
FinishRegistration processes the last half of the Webauthn Registration flow. It is the handler for the "PUT /webauthn/register" endpoint, initiated by the client with information encrypted by the new private key.
func (*App) RotateApiKey ¶
func (a *App) RotateApiKey(w http.ResponseWriter, r *http.Request)
RotateApiKey facilitates the rotation of API Keys. All data in webauthn and totp tables that is encrypted by the old key will be re-encrypted using the new key. If the process does not run to completion, this endpoint can be called any number of times to continue the process. A status of 200 does not indicate that all keys were encrypted using the new key. Check the response data to determine if the rotation process is complete.
type EnvConfig ¶
type EnvConfig struct { ApiKeyTable string `required:"true" split_words:"true"` TotpTable string `required:"true" split_words:"true"` WebauthnTable string `required:"true" split_words:"true"` AwsEndpoint string `default:"" split_words:"true"` AwsDefaultRegion string `default:"" split_words:"true"` AWSConfig aws.Config `json:"-"` }
EnvConfig holds environment specific configurations and is populated on init
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage provides wrapper methods for interacting with DynamoDB
func NewStorage ¶
NewStorage creates a new Storage service, which includes a new DynamoDB Client
func (*Storage) ScanApiKey ¶
ScanApiKey a table using apiKey-index
type WebauthnMeta ¶
type WebauthnMeta struct { RPDisplayName string `json:"RPDisplayName"` // Display Name for your site RPID string `json:"RPID"` // Generally the FQDN for your site RPOrigin string `json:"RPOrigin"` // The origin URL for WebAuthn requests RPIcon string `json:"RPIcon"` // Optional icon URL for your site UserUUID string `json:"UserUUID"` Username string `json:"Username"` UserDisplayName string `json:"UserDisplayName"` UserIcon string `json:"UserIcon"` }
WebauthnMeta holds metadata about the calling service for use in WebAuthn responses. Since this service/api is consumed by multiple sources this information cannot be stored in the envConfig
type WebauthnUser ¶
type WebauthnUser struct { // Shared fields between U2F and WebAuthn ID string `dynamodbav:"uuid" json:"uuid"` ApiKeyValue string `dynamodbav:"apiKey" json:"apiKey"` ApiKey ApiKey `dynamodbav:"-" json:"-"` Store *Storage `dynamodbav:"-" json:"-"` // U2F fields AppId string `dynamodbav:"-" json:"-"` EncryptedAppId string `dynamodbav:"encryptedAppId" json:"encryptedAppId,omitempty"` KeyHandle string `dynamodbav:"-" json:"-"` EncryptedKeyHandle string `dynamodbav:"encryptedKeyHandle" json:"encryptedKeyHandle,omitempty"` PublicKey string `dynamodbav:"-" json:"-"` EncryptedPublicKey string `dynamodbav:"encryptedPublicKey" json:"encryptedPublicKey,omitempty"` // WebAuthn fields SessionData webauthn.SessionData `dynamodbav:"-" json:"-"` EncryptedSessionData []byte `dynamodbav:"EncryptedSessionData" json:"EncryptedSessionData,omitempty"` // These can be multiple Yubikeys or other WebAuthn entries Credentials []webauthn.Credential `dynamodbav:"-" json:"-"` EncryptedCredentials []byte `dynamodbav:"EncryptedCredentials" json:"EncryptedCredentials,omitempty"` WebAuthnClient *webauthn.WebAuthn `dynamodbav:"-" json:"-"` Name string `dynamodbav:"-" json:"-"` DisplayName string `dynamodbav:"-" json:"-"` Icon string `dynamodbav:"-" json:"-"` }
WebauthnUser holds user data from DynamoDB, in both encrypted and unencrypted form. It also holds a Webauthn client and Webauthn API data.
func NewWebauthnUser ¶
func NewWebauthnUser(apiConfig WebauthnMeta, storage *Storage, apiKey ApiKey, webAuthnClient *webauthn.WebAuthn) WebauthnUser
NewWebauthnUser creates a new WebauthnUser from API input data, a storage client and a Webauthn client.
func (*WebauthnUser) BeginLogin ¶
func (u *WebauthnUser) BeginLogin() (*protocol.CredentialAssertion, error)
BeginLogin processes the first half of the Webauthn Authentication flow for the user and returns the CredentialAssertion data to pass back to the client. User session data is saved in the database.
func (*WebauthnUser) BeginRegistration ¶
func (u *WebauthnUser) BeginRegistration() (*protocol.CredentialCreation, error)
BeginRegistration processes the first half of the Webauthn Registration flow for the user and returns the CredentialCreation data to pass back to the client. User session data is saved in the database.
func (*WebauthnUser) Delete ¶
func (u *WebauthnUser) Delete() error
Delete removes the user from the database
func (*WebauthnUser) DeleteCredential ¶
func (u *WebauthnUser) DeleteCredential(credIDHash string) (int, error)
DeleteCredential expects a hashed-encoded credential id. It finds a matching credential for that user and saves the user without that credential included. Alternatively, if the given credential id indicates that a legacy U2F key should be removed (i.e. by matching the string "u2f") then that user is saved with all of its legacy u2f fields blanked out. CAUTION: user data is refreshed from the database by this function. Any unsaved data will be lost.
func (*WebauthnUser) FinishLogin ¶
func (u *WebauthnUser) FinishLogin(r *http.Request) (*webauthn.Credential, error)
FinishLogin processes the last half of the Webauthn Authentication flow for the user and returns the Credential data to pass back to the client. User session data is untouched by this function.
func (*WebauthnUser) FinishRegistration ¶
func (u *WebauthnUser) FinishRegistration(r *http.Request) (string, error)
FinishRegistration processes the last half of the Webauthn Registration flow for the user and returns the key_handle_hash to pass back to the client. The client should store this value for later use. User session data is cleared from the database.
func (*WebauthnUser) Load ¶
func (u *WebauthnUser) Load() error
Load refreshes a user object from the database record and decrypts the session data and credential list
func (*WebauthnUser) RemoveU2F ¶
func (u *WebauthnUser) RemoveU2F()
RemoveU2F clears U2F fields in the user struct. To be used when a user has requested removal of their legacy U2F key. Should be followed by a database store operation.
func (*WebauthnUser) WebAuthnCredentials ¶
func (u *WebauthnUser) WebAuthnCredentials() []webauthn.Credential
WebAuthnCredentials returns an array of credentials (passkeys) plus a U2F credential if present
func (*WebauthnUser) WebAuthnDisplayName ¶
func (u *WebauthnUser) WebAuthnDisplayName() string
WebAuthnDisplayName returns the display name of the user
func (*WebauthnUser) WebAuthnID ¶
func (u *WebauthnUser) WebAuthnID() []byte
WebAuthnID returns the user's ID according to the Relying Party
func (*WebauthnUser) WebAuthnIcon ¶
func (u *WebauthnUser) WebAuthnIcon() string
WebAuthnIcon returns the user's icon URL
func (*WebauthnUser) WebAuthnName ¶
func (u *WebauthnUser) WebAuthnName() string
WebAuthnName returns the user's name according to the Relying Party