Documentation
¶
Index ¶
- Variables
- func RandBytes(length int) []byte
- func SetLogger(l Logger)
- type Assertion
- type AssertionOpts
- type Attestation
- type BioTemplate
- type CredProtect
- type Credential
- type CredentialType
- type CredentialsInfo
- type Device
- func (d *Device) Assertion(rpID string, clientDataHash []byte, credentialIDs [][]byte, pin string, ...) (*Assertion, error)
- func (d *Device) BioDelete(pin, templateId string) error
- func (d *Device) BioEnroll(pin string) error
- func (d *Device) BioList(pin string) ([]BioTemplate, error)
- func (d *Device) BioSetTemplateName(pin, templateId, name string) error
- func (d *Device) CTAPHIDInfo() (*HIDInfo, error)
- func (d *Device) Cancel() error
- func (d *Device) Credentials(rpID string, pin string) ([]*Credential, error)
- func (d *Device) CredentialsInfo(pin string) (*CredentialsInfo, error)
- func (d *Device) DeleteCredential(credID []byte, pin string) error
- func (d *Device) Info() (*DeviceInfo, error)
- func (d *Device) IsFIDO2() (bool, error)
- func (d *Device) MakeCredential(clientDataHash []byte, rp RelyingParty, user User, typ CredentialType, ...) (*Attestation, error)
- func (d *Device) PublicKey(rp *RelyingParty, credential []byte, pin string) ([]byte, error)
- func (d *Device) RelyingParties(pin string) ([]*RelyingParty, error)
- func (d *Device) Reset() error
- func (d *Device) RetryCount() (int, error)
- func (d *Device) SetPIN(pin string, old string) error
- func (d *Device) Type() (DeviceType, error)
- type DeviceInfo
- type DeviceLocation
- type DeviceType
- type Error
- type Extension
- type HIDInfo
- type LogLevel
- type Logger
- type MakeCredentialOpts
- type Option
- type OptionValue
- type RelyingParty
- type User
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrActionTimeout = errors.New("action timed out")
ErrActionTimeout if action timed out.
var ErrInternal = errors.New("internal error")
ErrInternal internal error.
var ErrInvalidArgument = errors.New("invalid argument")
ErrInvalidArgument if arguments are invalid.
var ErrInvalidCommand = errors.New("invalid command")
ErrInvalidCommand if command is not supported.
var ErrInvalidCredential = errors.New("invalid credential")
ErrInvalidCredential if credential is invalid.
var ErrInvalidLength = errors.New("invalid length")
ErrInvalidLength if invalid length.
var ErrInvalidOption = errors.Errorf("invalid option")
ErrInvalidOption if option is invalid.
var ErrKeepaliveCancel = errors.Errorf("keep alive cancel")
ErrKeepaliveCancel if action was cancelled.
var ErrMissingParameter = errors.New("missing parameter")
ErrMissingParameter if missing parameter.
var ErrNoCredentials = errors.New("no credentials")
ErrNoCredentials if no credentials.
var ErrNotAllowed = errors.New("not allowed")
ErrNotAllowed if not allowed.
var ErrNotFIDO2 = errors.Errorf("not a FIDO2 device")
ErrNotFIDO2 if device is not a FIDO2 device.
var ErrOperationDenied = errors.New("operation denied")
ErrOperationDenied if operation denied.
var ErrOther = errors.Errorf("other error")
ErrOther if other error?
var ErrPinAuthBlocked = errors.New("pin auth blocked")
ErrPinAuthBlocked if too many PIN failures.
var ErrPinInvalid = errors.New("pin invalid")
ErrPinInvalid if pin is wrong.
var ErrPinNotSet = errors.New("pin not set")
ErrPinNotSet if PIN is not set and is required for command.
var ErrPinPolicyViolation = errors.New("pin policy violation")
ErrPinPolicyViolation if PIN policy violation.
var ErrPinRequired = errors.New("pin required")
ErrPinRequired if PIN is required.
var ErrRX = errors.New("rx error")
ErrRX if there was an error receiving.
var ErrRXInvalidCBOR = errors.New("rx invalid cbor")
ErrRXInvalidCBOR if receiving invalid CBOR.
var ErrRXNotCBOR = errors.New("rx not CBOR")
ErrRXNotCBOR rx not CBOR.
var ErrTX = errors.New("tx error")
ErrTX if there was an error transmitting.
var ErrUPRequired = errors.New("up required")
ErrUPRequired if user presence is required.
var ErrUnsupportedOption = errors.New("unsupported option")
ErrUnsupportedOption if option is unsupported.
var ErrUserPresenceRequired = errors.New("user presence required")
ErrUserPresenceRequired is user presence required.
Functions ¶
Types ¶
type Assertion ¶
type Assertion struct {
// AuthDataCBOR is CBOR encoded authdata.
// TODO: Include "raw" authdata if that is added to libfido2.
AuthDataCBOR []byte
Sig []byte
HMACSecret []byte
CredentialID []byte
User User
}
Assertion ...
type AssertionOpts ¶
type AssertionOpts struct {
Extensions []Extension
UV OptionValue
UP OptionValue
HMACSalt []byte
}
AssertionOpts ...
type Attestation ¶
type Attestation struct {
ClientDataHash []byte
AuthData []byte
CredentialID []byte
CredentialType CredentialType
PubKey []byte
Cert []byte
Sig []byte
Format string
}
Attestation from MakeCredential ...
type BioTemplate ¶
type CredProtect ¶
type CredProtect string
CredProtect option if extension is supported.
const ( // CredProtectNone if unset. CredProtectNone CredProtect = "" // CredProtectUVOptional UV optional CredProtectUVOptional CredProtect = "uv-optional" // CredProtectUVOptionalWithID UV optional with ID CredProtectUVOptionalWithID CredProtect = "uv-optional-with-id" // CredProtectUVRequired UV required CredProtectUVRequired CredProtect = "uv-required" )
type CredentialType ¶
type CredentialType int
CredentialType ...
const ( // ES256 ... ES256 CredentialType = -7 // EDDSA ... EDDSA CredentialType = -8 // RS256 ... RS256 CredentialType = -257 )
func (CredentialType) String ¶
func (c CredentialType) String() string
type CredentialsInfo ¶
CredentialsInfo ...
type Device ¶
Device ...
func SelectDevice ¶
SelectDevice returns the first device of the passed list that is touched by the user within the given timeout. It returns an error if no device was selected.
func (*Device) Assertion ¶
func (d *Device) Assertion( rpID string, clientDataHash []byte, credentialIDs [][]byte, pin string, opts *AssertionOpts) (*Assertion, error)
Assertion ...
Example ¶
package main
import (
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Println("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
cdh := libfido2.RandBytes(32)
userID := libfido2.RandBytes(32)
salt := libfido2.RandBytes(32)
pin := "12345"
attest, err := device.MakeCredential(
cdh,
libfido2.RelyingParty{
ID: "keys.pub",
},
libfido2.User{
ID: userID,
Name: "gabriel",
},
libfido2.ES256, // Algorithm
pin,
&libfido2.MakeCredentialOpts{
Extensions: []libfido2.Extension{libfido2.HMACSecretExtension},
RK: libfido2.True,
},
)
if err != nil {
log.Fatal(err)
}
log.Printf("Attestation:\n")
log.Printf("AuthData: %s\n", hex.EncodeToString(attest.AuthData))
log.Printf("ClientDataHash: %s\n", hex.EncodeToString(attest.ClientDataHash))
log.Printf("ID: %s\n", hex.EncodeToString(attest.CredentialID))
log.Printf("Type: %s\n", attest.CredentialType)
log.Printf("Sig: %s\n", hex.EncodeToString(attest.Sig))
assertion, err := device.Assertion(
"keys.pub",
cdh,
[][]byte{attest.CredentialID},
pin,
&libfido2.AssertionOpts{
Extensions: []libfido2.Extension{libfido2.HMACSecretExtension},
UP: libfido2.True,
HMACSalt: salt,
},
)
if err != nil {
log.Fatal(err)
}
log.Printf("Assertion:\n")
log.Printf("AuthDataCBOR: %s\n", hex.EncodeToString(assertion.AuthDataCBOR))
log.Printf("HMACSecret: %s\n", hex.EncodeToString(assertion.HMACSecret))
log.Printf("Sig: %s\n", hex.EncodeToString(assertion.Sig))
log.Printf("CredentialID: %s\n", hex.EncodeToString(assertion.CredentialID))
log.Printf("User.ID: %s\n", hex.EncodeToString(assertion.User.ID))
}
Output:
Example (HmacSecret) ¶
package main
import (
"bytes"
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
type testVector struct {
CredentialID string
Secret string
}
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatalf("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
name := locs[0].Product + "/" + locs[0].Manufacturer
cdh := bytes.Repeat([]byte{0x01}, 32)
rpID := "keys.pub"
pin := "12345"
testVectors := map[string]testVector{
"SoloKey 4.0/SoloKeys": testVector{
CredentialID: "91874f4c3d580370bf5b5301130ecc034f5927d955f5399ebad267f5666c78598942d489f10d4f4780fad392eb2962d065bdd3574375e80c42218dadd199ed3ffe7deb010000",
Secret: "dd67d3aa73b13b7bb71ad0fe13cf8a247632a3508d7c9906ef6dc823906c3103",
},
"Security Key by Yubico/Yubico": testVector{
CredentialID: "c4fe75012ed137a0afcaa59ab36f0722b9b05849b2203fc4ba4f304033015eaafdbee823ee42dce88b4ae4d943926de3cc93e797004d108ed2465c675ae568e6",
Secret: "f3d37d52ca7a12cf05c34bd3c13ddc3288b723018697347e6ac5ea79b7d3cc83",
},
}
testVector, ok := testVectors[name]
if !ok {
log.Fatalf("No test vector found for %s", name)
}
credentialID, err := hex.DecodeString(testVector.CredentialID)
if err != nil {
log.Fatal(err)
}
salt := bytes.Repeat([]byte{0x02}, 32)
assertion, err := device.Assertion(
rpID,
cdh,
[][]byte{credentialID},
pin,
&libfido2.AssertionOpts{
Extensions: []libfido2.Extension{libfido2.HMACSecretExtension},
// UP: libfido2.True, // Required for some devices
// UV: libfido2.True, // Required for some devices
HMACSalt: salt,
},
)
if err != nil {
log.Fatal(err)
}
if testVector.Secret != hex.EncodeToString(assertion.HMACSecret) {
log.Fatalf("Expected %s", testVector.Secret)
}
}
Output:
func (*Device) BioDelete ¶
BioDelete deletes a bio template.
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatal("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
templates, err := device.BioList(pin)
if err != nil {
log.Fatal(err)
}
for _, template := range templates {
err := device.BioDelete(pin, template.ID)
if err != nil {
log.Fatal(err)
}
}
}
Output:
func (*Device) BioList ¶
func (d *Device) BioList(pin string) ([]BioTemplate, error)
BioList lists all bio templates.
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatal("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
templates, err := device.BioList(pin)
if err != nil {
log.Fatal(err)
}
log.Println(templates)
}
Output:
func (*Device) BioSetTemplateName ¶
BioSetTemplateName sets the name of template with templateId.
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatal("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
templates, err := device.BioList(pin)
if err != nil {
log.Fatal(err)
}
if len(templates) == 0 {
log.Fatal("no bio template")
return
}
template := templates[0]
newName := "newName"
device.BioSetTemplateName(pin, template.ID, newName)
}
Output:
func (*Device) Credentials ¶
func (d *Device) Credentials(rpID string, pin string) ([]*Credential, error)
Credentials lists credentials (if credMgmt is supported).
Example ¶
package main
import (
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
libfido2.SetLogger(libfido2.NewLogger(libfido2.DebugLevel))
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Println("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
info, err := device.CredentialsInfo(pin)
if err != nil {
log.Fatal(err)
}
log.Printf("Info: %+v\n", info)
rps, err := device.RelyingParties(pin)
if err != nil {
log.Fatal(err)
}
for _, rp := range rps {
log.Printf("RP{ID: %s, Name: %s}\n", rp.ID, rp.Name)
creds, err := device.Credentials(rp.ID, pin)
if err != nil {
log.Fatal(err)
}
for _, cred := range creds {
log.Printf("User{ID: %s, Name: %s}\n", hex.EncodeToString(cred.User.ID), cred.User.Name)
log.Printf("ID: %s\n", hex.EncodeToString(cred.ID))
log.Printf("Type: %s\n", cred.Type)
log.Printf("\n")
}
}
}
Output:
func (*Device) CredentialsInfo ¶
func (d *Device) CredentialsInfo(pin string) (*CredentialsInfo, error)
CredentialsInfo ...
func (*Device) DeleteCredential ¶
DeleteCredential deletes a resident credential (if credMgmt is supported).
Example ¶
package main
import (
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatal("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
info, err := device.CredentialsInfo(pin)
if err != nil {
log.Fatal(err)
}
log.Printf("Info: %+v\n", info)
rps, err := device.RelyingParties(pin)
if err != nil {
log.Fatal(err)
}
for _, rp := range rps {
creds, err := device.Credentials(rp.ID, pin)
if err != nil {
log.Fatal(err)
}
for _, cred := range creds {
log.Printf("Deleting: %s\n", hex.EncodeToString(cred.ID))
if err := device.DeleteCredential(cred.ID, pin); err != nil {
log.Fatal(err)
}
}
}
}
Output:
func (*Device) Info ¶
func (d *Device) Info() (*DeviceInfo, error)
Info represents authenticatorGetInfo (0x04). https://fidoalliance.org/specs/fido2/fido-client-to-authenticator-protocol-v2.1-rd-20191217.html#authenticatorGetInfo
func (*Device) MakeCredential ¶
func (d *Device) MakeCredential( clientDataHash []byte, rp RelyingParty, user User, typ CredentialType, pin string, opts *MakeCredentialOpts) (*Attestation, error)
MakeCredential represents authenticatorMakeCredential (0x01). RP, User ID and name are required by some devices, so we return an error if missing.
Example ¶
package main
import (
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
libfido2.SetLogger(libfido2.NewLogger(libfido2.DebugLevel))
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Println("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
cdh := libfido2.RandBytes(32)
userID := libfido2.RandBytes(32)
pin := "12345"
attest, err := device.MakeCredential(
cdh,
libfido2.RelyingParty{
ID: "keys.pub",
Name: "keys.pub",
},
libfido2.User{
ID: userID,
Name: "gabriel",
DisplayName: "Gabriel",
},
libfido2.ES256, // Algorithm
pin,
nil,
)
if err != nil {
log.Fatal(err)
}
log.Printf("Attestation:\n")
log.Printf("AuthData: %s\n", hex.EncodeToString(attest.AuthData))
log.Printf("ClientDataHash: %s\n", hex.EncodeToString(attest.ClientDataHash))
log.Printf("ID: %s\n", hex.EncodeToString(attest.CredentialID))
log.Printf("Type: %d\n", attest.CredentialType)
log.Printf("Sig: %s\n", hex.EncodeToString(attest.Sig))
}
Output:
Example (HmacSecret) ¶
package main
import (
"bytes"
"encoding/hex"
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Fatal("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
cdh := bytes.Repeat([]byte{0x01}, 32)
rpID := "keys.pub"
pin := "12345"
attest, err := device.MakeCredential(
cdh,
libfido2.RelyingParty{
ID: rpID,
Name: "hmac-secret",
},
libfido2.User{
ID: libfido2.RandBytes(16),
Name: "hmac-secret",
},
libfido2.ES256, // Algorithm
pin,
&libfido2.MakeCredentialOpts{
Extensions: []libfido2.Extension{libfido2.HMACSecretExtension},
RK: libfido2.True,
// UV: libfido2.True,
// CredProtect: libfido2.CredProtectUVRequired,
},
)
if err != nil {
log.Fatal(err)
}
log.Printf("Credential ID: %s\n", hex.EncodeToString(attest.CredentialID))
}
Output:
func (*Device) RelyingParties ¶
func (d *Device) RelyingParties(pin string) ([]*RelyingParty, error)
RelyingParties ...
func (*Device) Reset ¶
Reset represents authenticatorReset. https://fidoalliance.org/specs/fido2/fido-client-to-authenticator-protocol-v2.1-rd-20191217.html#authenticatorReset The actual user-flow to perform a reset is outside the scope of the FIDO2 specification, and may therefore vary depending on the authenticator. Yubico authenticators will return ErrNotAllowed if a reset is issued later than 5 seconds after power-up, and ErrActionTimeout if the user fails to confirm the reset by touching the key within 30 seconds.
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
libfido2.SetLogger(libfido2.NewLogger(libfido2.DebugLevel))
if os.Getenv("FIDO2_EXAMPLES_RESET") != "1" {
log.Println("only runs if FIDO2_EXAMPLES_RESET=1")
return
}
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Println("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
log.Printf("Resetting: %+v\n", locs[0])
if err := device.Reset(); err != nil {
log.Fatal(err)
}
}
Output:
func (*Device) SetPIN ¶
SetPIN ...
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES_SET_PIN") != "1" {
return
}
libfido2.SetLogger(libfido2.NewLogger(libfido2.DebugLevel))
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
if len(locs) == 0 {
log.Println("No devices")
return
}
log.Printf("Using device: %+v\n", locs[0])
path := locs[0].Path
device, err := libfido2.NewDevice(path)
if err != nil {
log.Fatal(err)
}
pin := "12345"
if err := device.SetPIN(pin, ""); err != nil {
log.Fatal(err)
}
}
Output:
type DeviceInfo ¶
type DeviceInfo struct {
Versions []string
Extensions []string
AAGUID []byte
Options []Option
Protocols []byte
}
DeviceInfo ...
type DeviceLocation ¶
type DeviceLocation struct {
Path string
ProductID int16
VendorID int16
Manufacturer string
Product string
}
DeviceLocation ...
func DeviceLocations ¶
func DeviceLocations() ([]*DeviceLocation, error)
DeviceLocations lists found devices.
Example ¶
package main
import (
"log"
"os"
"github.com/keys-pub/go-libfido2"
)
func main() {
if os.Getenv("FIDO2_EXAMPLES") != "1" {
return
}
libfido2.SetLogger(libfido2.NewLogger(libfido2.DebugLevel))
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal(err)
}
for _, loc := range locs {
log.Printf("%+v\n", loc)
device, err := libfido2.NewDevice(loc.Path)
if err != nil {
log.Fatal(err)
}
hidInfo, err := device.CTAPHIDInfo()
if err != nil {
log.Fatal(err)
}
log.Printf("CTAPHIDInfo: %+v\n", hidInfo)
info, err := device.Info()
if err != nil {
log.Fatal(err)
}
log.Printf("Info: %+v\n", info)
}
}
Output:
type DeviceType ¶
type DeviceType string
DeviceType is latest type the device supports.
const ( // UnknownDevice ... UnknownDevice DeviceType = "" // FIDO2 ... FIDO2 DeviceType = "fido2" // U2F ... U2F DeviceType = "u2f" )
type Extension ¶
type Extension string
Extension ...
const ( // HMACSecretExtension for HMAC secret extension. // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension HMACSecretExtension Extension = "hmac-secret" // CredProtectExtension for credProtect extension. CredProtectExtension Extension = "credProtect" )
type Logger ¶
type Logger interface {
Debugf(format string, args ...interface{})
Infof(format string, args ...interface{})
Warningf(format string, args ...interface{})
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
Logger interface used in this package.
type MakeCredentialOpts ¶
type MakeCredentialOpts struct {
Extensions []Extension
RK OptionValue
UV OptionValue
CredProtect CredProtect
}
MakeCredentialOpts ...
type OptionValue ¶
type OptionValue string
OptionValue is value for option.
const ( // Default is device default (omitted). Default OptionValue = "" // True is enabled/yes/true option. True OptionValue = "true" // False is disabled/no/false option. False OptionValue = "false" )