protocol

package
v0.0.0-...-13fba11 Latest Latest
Warning

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

Go to latest
Published: Nov 19, 2024 License: Apache-2.0 Imports: 17 Imported by: 6

Documentation

Overview

Package protocol contains common protocol-related types and values.

Index

Constants

View Source
const (
	// JWT token is missing or invalid. Each token has its own validity period,
	// server rejects expired tokens. Server failed to parse JWT token or JWT
	// signature did not verify correctly. The JWT token refers to the token
	// mentioned in section 4.3 (which is not required by protocol to be a JWT
	// token). The error message applies to non-JWT tokens, as well.
	//
	// Messages: DI.SetHMAC, TO0.OwnerSign, TO1.ProveToRV, TO2.GetOVNextEntry,
	//           TO2.ProveDevice, TO2.NextDeviceServiceInfo, TO2.Done
	InvalidJwtTokenCode = 1

	// Ownership Voucher is invalid: One of Ownership Voucher verification
	// checks has failed. Precise information is not returned to the client but
	// saved only in service logs.
	//
	// Messages: TO0.OwnerSign
	InvalidOwnershipVoucherCode = 2

	// Verification of signature of owner message failed. TO0.OwnerSign message
	// is signed by the final owner (using key signed by the last Ownership
	// Voucher entry). This error is returned in case that signature is
	// invalid.
	//
	// Messages: TO0.OwnerSign
	InvalidOwnerSignBodyCode = 3

	// IP address is invalid. Bytes that are provided in the request do not
	// represent a valid IPv4/IPv6 address.
	//
	// Messages: TO0.OwnerSign
	InvalidIPAddrCode = 4

	// GUID is invalid. Bytes that are provided in the request do not represent
	// a proper GUID.
	//
	// Messages: TO0.OwnerSign
	InvalidGUID = 5

	// The owner connection info for GUID is not found. TO0 Protocol wasn’t
	// properly executed for the specified GUID or information that was stored
	// in database has expired and/or has been removed.
	//
	// Messages: TO1.HelloRV, TO2.HelloDevice
	ResourceNotFound = 6

	// Message Body is structurally unsound: JSON parse error, or valid JSON,
	// but is not mapping to the expected Secure Device Onboard type (see 4.6)
	//
	// Messages: DI.AppStart, DI.SetHMAC, TO0.Hello, TO0.OwnerSign,
	//           TO1.HelloRV, TO1.ProveToRV, TO2.HelloDevice,
	//           TO2.GetOVNextEntry, TO2.ProveDevice,
	//           TO2.DeviceServiceInfo, TO2.OwnerServiceInfo, TO2.Done
	MessageBodyErrCode = 100

	// Message structurally sound, but failed validation tests. The nonce
	// didn’t match, signature didn’t verify, hash, or mac didn’t verify, index
	// out of bounds, etc...
	//
	// Messages: TO0.OwnerSign, TO1.HelloRV, TO1.ProveToRV, TO2.HelloDevice,
	//           TO2.GetOVNextEntry, TO2.ProveDevice,
	//           TO2.DeviceServiceInfo, TO2.OwnerServiceInfo,
	InvalidMessageErrCode = 101

	// Credential reuse rejected.
	//
	// Messages: TO2.SetupDevice
	CredReuseErrCode = 102

	// Something went wrong which couldn’t be classified otherwise.  (This was
	// chosen to match the HTTP 500 error code.)
	//
	// Messages: DI.AppStart, DI.SetHMAC, TO0.Hello, TO0.OwnerSign,
	//           TO1.HelloRV, TO1.ProveToRV, TO2.HelloDevice,
	//           TO2.GetOVNextEntry, TO2.ProveDevice,
	//           TO2.DeviceServiceInfo, TO2.OwnerServiceInfo, TO2.Done
	InternalServerErrCode = 500
)

Error codes

View Source
const (
	DIAppStartMsgType       uint8 = 10
	DISetCredentialsMsgType uint8 = 11
	DISetHmacMsgType        uint8 = 12
	DIDoneMsgType           uint8 = 13
)

DI Message Types

View Source
const (
	TO0HelloMsgType       uint8 = 20
	TO0HelloAckMsgType    uint8 = 21
	TO0OwnerSignMsgType   uint8 = 22
	TO0AcceptOwnerMsgType uint8 = 23
)

TO0 Message Types

View Source
const (
	TO1HelloRVMsgType    uint8 = 30
	TO1HelloRVAckMsgType uint8 = 31
	TO1ProveToRVMsgType  uint8 = 32
	TO1RVRedirectMsgType uint8 = 33
)

TO1 Message Types

View Source
const (
	TO2HelloDeviceMsgType            uint8 = 60
	TO2ProveOVHdrMsgType             uint8 = 61
	TO2GetOVNextEntryMsgType         uint8 = 62
	TO2OVNextEntryMsgType            uint8 = 63
	TO2ProveDeviceMsgType            uint8 = 64
	TO2SetupDeviceMsgType            uint8 = 65
	TO2DeviceServiceInfoReadyMsgType uint8 = 66
	TO2OwnerServiceInfoReadyMsgType  uint8 = 67
	TO2DeviceServiceInfoMsgType      uint8 = 68
	TO2OwnerServiceInfoMsgType       uint8 = 69
	TO2DoneMsgType                   uint8 = 70
	TO2Done2MsgType                  uint8 = 71
)

TO2 Message Types

View Source
const (
	RVProtRest    uint8 = 0
	RVProtHTTP    uint8 = 1
	RVProtHTTPS   uint8 = 2
	RVProtTCP     uint8 = 3
	RVProtTLS     uint8 = 4
	RVProtCoapTCP uint8 = 5
	RVProtCoapUDP uint8 = 6
)

Rendezvous Protocols

View Source
const (
	RVMedEthAll  uint8 = 20
	RVMedWifiAll uint8 = 21
)

Rendezvous Media

View Source
const ErrorMsgType uint8 = 255

ErrorMsgType is the response type number associated with an ErrorMessage response.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrorMessage

type ErrorMessage struct {
	Code          uint16
	PrevMsgType   uint8
	ErrString     string
	Timestamp     int64 // Timestamp once the Java implementation is fixed
	CorrelationID *uint
}

ErrorMessage indicates that the previous protocol message could not be processed. The error message is a “catch-all” whenever processing cannot continue. This includes protocol errors and any trust or security violations.

The FIDO Device Onboard protocol is always terminated after an error message (and retries, automatically, as per RendezvousInfo), and all FIDO Device Onboard error conditions send an error message. However, security errors might not indicate the exact cause of the problem, if this would cause a security issue.

The contents of the error message are intended to help diagnose the error. The “EMErrorCode” is an error code, please see following section, Error Code Values, for detailed information. The “EMPrevMsgID” gives the message ID of the previous message, making it easier to put the error into context. The “EMErrorStr” tag gives a string suitable for logging about the error.

The string in the “EMErrorStr” tag must not include security details that are inappropriate for logging, such as a specific security condition, or any key or password information.

The values EMErrorTS and EMErrorCID are intended to expedite diagnosis of problems, especially between cloud-based entities where large logs must be searched. In a typical scenario, an endpoint generates a correlation ID for each request and includes it in column of each event or trace logged throughout processing for that request. The combination of correlation ID and the time of the transaction help to find the log item and its context.

EMErrorTS and EMErrorUuid may be CBOR Null if there is no appropriate value. This may occur in Device based implementations. In some Devices, a time value may exist that is not correlated to UTC time, but might still be useful. The TIMET choice is intended to remove the UTC restriction and allow a Device-local time value to be used.

ErrorMessage = [
    EMErrorCode: uint16,       ;; Error code
    EMPrevMsgID: uint8,        ;; Message ID of the previous message
    EMErrorStr:  tstr,         ;; Error string
    EMErrorTs:   timestamp,    ;; UTC timestamp
    EMErrorCID:  correlationId ;; Unique id associated with this request
]
correlationId = uint

func (ErrorMessage) Error

func (e ErrorMessage) Error() string

Error implements the standard error interface.

func (ErrorMessage) String

func (e ErrorMessage) String() string

String implements Stringer.

type GUID

type GUID [16]byte

GUID is implemented as a 128-bit cryptographically strong random number.

The GUID type identifies a Device during onboarding, and is replaced each time onboarding is successful in the Transfer Ownership 2 (TO2) protocol.

type Hash

type Hash struct {
	Algorithm HashAlg
	Value     []byte
}

Hash is a crypto hash, with length in bytes preceding. Hashes are computed in accordance with FIPS-180-4. See COSE assigned numbers for hash types.

Hash = [
    hashtype: int, ;; negative values possible
    hash: bstr
]

type HashAlg

type HashAlg int64

HashAlg is an FDO hashtype enum.

hashtype = (
    SHA256: -16,
    SHA384: -43,
    HMAC-SHA256: 5,
    HMAC-SHA384: 6
)
const (
	Sha256Hash     HashAlg = -16
	Sha384Hash     HashAlg = -43
	HmacSha256Hash HashAlg = 5
	HmacSha384Hash HashAlg = 6
)

Hash algorithms

func (HashAlg) HashFunc

func (alg HashAlg) HashFunc() crypto.Hash

HashFunc implements crypto.SignerOpts, but is mainly intended as a simple helper function.

func (HashAlg) String

func (alg HashAlg) String() string

type Hmac

type Hmac = Hash

Hmac - RFC2104 - is encoded as a hash.

HMac = Hash

type KeyEncoding

type KeyEncoding uint8

KeyEncoding is an FDO pkEnc enum.

pkEnc = (
    Crypto:       0      ;; applies to crypto with its own encoding (e.g., Intel® EPID)
    X509:         1,     ;; X509 DER encoding, applies to RSA and ECDSA
    X5CHAIN:      2,     ;; COSE x5chain, an ordered chain of X.509 certificates
    COSEKEY:      3      ;; COSE key encoding
)
const (
	// Applies to crypto with its own encoding (e.g., Intel® EPID)
	CryptoKeyEnc KeyEncoding = 0
	// X509 DER encoding, applies to RSA and ECDSA
	X509KeyEnc KeyEncoding = 1
	// COSE x5chain, an ordered chain of X.509 certificates
	X5ChainKeyEnc KeyEncoding = 2
	// COSE key encoding
	CoseKeyEnc KeyEncoding = 3
)

Public key encodings

func (KeyEncoding) String

func (enc KeyEncoding) String() string

type KeyType

type KeyType uint8

KeyType is an FDO pkType enum.

pkType = (
    RSA2048RESTR: 1, ;; RSA 2048 with restricted key/exponent (PKCS1 1.5 encoding)
    RSAPKCS:      5, ;; RSA key, PKCS1, v1.5
    RSAPSS:       6, ;; RSA key, PSS
    SECP256R1:    10, ;; ECDSA secp256r1 = NIST-P-256 = prime256v1
    SECP384R1:    11, ;; ECDSA secp384r1 = NIST-P-384
)
;; These are identical
SECP256R1 = (
    NIST-P-256,
    PRIME256V1
)
;; These are identical
SECP384R1 = (
    NIST-P-384
)
const (
	// RSA 2048 with restricted key/exponent (PKCS1 1.5 encoding)
	Rsa2048RestrKeyType KeyType = 1
	// RSA key, PKCS1, v1.5
	RsaPkcsKeyType KeyType = 5
	// RSA key, PSS
	RsaPssKeyType KeyType = 6
	// ECDSA secp256r1 = NIST-P-256 = prime256v1
	Secp256r1KeyType KeyType = 10
	// ECDSA secp384r1 = NIST-P-384
	Secp384r1KeyType KeyType = 11
)

Public key types

func ParseKeyType

func ParseKeyType(name string) (KeyType, error)

ParseKeyType parses names following the below convention:

RSA2048RESTR: 1, ;; RSA 2048 with restricted key/exponent (PKCS1 1.5 encoding)
RSAPKCS:      5, ;; RSA key, PKCS1, v1.5
RSAPSS:       6, ;; RSA key, PSS
SECP256R1:    10, ;; ECDSA secp256r1 = NIST-P-256 = prime256v1
SECP384R1:    11, ;; ECDSA secp384r1 = NIST-P-384

func (KeyType) String

func (typ KeyType) String() string

type Nonce

type Nonce [16]byte

Nonce is a byte array with length (16 bytes) 128-bit Random number.

Nonces are used within FIDO Device Onboard to ensure that signatures are create on demand and not replayed (i.e., to ensure the "freshness" of signatures). When asymmetric digital signatures are used to prove ownership of a private key, as in FIDO Device Onboard, an attacker may try to replay previously signed messages, to impersonate the true key owner. A secure protocol can detect and thwart a replay attack by attaching a unique value to the signed data. In this case, we use a nonce, which is a cryptographically secure random number chosen by the other party in the connection. Since FIDO Device Onboard contains several signatures, more than one nonce is used. The reader may use the number of the nonce type to track when a nonce is offered and then subsequently returned.

type Protocol

type Protocol uint8

Protocol is the FDO specification-defined protocol.

const (
	UnknownProtocol Protocol = iota
	DIProtocol
	TO0Protocol
	TO1Protocol
	TO2Protocol
	AnyProtocol // for error message types
)

Protocol enumeration values

func Of

func Of(msgType uint8) Protocol

Of returns the protocol a given message type belongs to.

func (Protocol) String

func (p Protocol) String() string

type PublicKey

type PublicKey struct {
	Type     KeyType
	Encoding KeyEncoding
	Body     cbor.RawBytes
	// contains filtered or unexported fields
}

PublicKey encodes public key information in FDO messages and vouchers.

func NewPublicKey

func NewPublicKey[T PublicKeyOrChain](typ KeyType, pub T, asCOSE bool) (*PublicKey, error)

NewPublicKey creates a public key structure encoded as X509, X5Chain, or a COSE Key, depending on the type of pub and the value of asCOSE.

func (*PublicKey) Chain

func (pub *PublicKey) Chain() ([]*x509.Certificate, error)

Chain returns the certificate chain of the public key. If the key encoding is not X5CHAIN then the certificate slice will be nil.

func (*PublicKey) Public

func (pub *PublicKey) Public() (crypto.PublicKey, error)

Public returns the public key parsed from the X509 or X5CHAIN encoding.

func (PublicKey) String

func (pub PublicKey) String() string

type PublicKeyOrChain

type PublicKeyOrChain interface {
	*ecdsa.PublicKey | *rsa.PublicKey | []*x509.Certificate
}

PublicKeyOrChain is a constraint for supported FDO PublicKey types.

type Responder

type Responder interface {
	// Respond validates a request and returns the appropriate response message.
	Respond(ctx context.Context, msgType uint8, msg io.Reader) (respType uint8, resp any)
}

Responder is implemented by *fdo.DIServer, *fdo.TO0Server, *fdo.TO1Server, and *fdo.TO2Server.

type RvDirective

type RvDirective struct {
	URLs   []*url.URL
	Bypass bool

	EthIface  *uint8 // 20 means try all
	WlanIface *uint8 // 21 means try all
	WlanSSID  string
	WlanPass  string

	Delay      time.Duration
	External   bool
	ServerCert *Hash
	ServerCA   *Hash
}

RvDirective is a fully parsed group of instructions.

func ParseDeviceRvInfo

func ParseDeviceRvInfo(rvInfo [][]RvInstruction) []RvDirective

ParseDeviceRvInfo parses all directives for a device.

func ParseOwnerRvInfo

func ParseOwnerRvInfo(rvInfo [][]RvInstruction) []RvDirective

ParseOwnerRvInfo parses all directives for an owner service.

type RvInstruction

type RvInstruction struct {
	Variable RvVar
	Value    []byte `cbor:",omitempty"`
}

RvInstruction contains a paired rendezvous variable identifier and value.

type RvTO2Addr

type RvTO2Addr struct {
	IPAddress         *net.IP // Can be null, unless DNSAddress is null
	DNSAddress        *string // Can be null, unless IPAddress is null
	Port              uint16
	TransportProtocol TransportProtocol
}

RvTO2Addr indicates to the device how to connect to the owner service.

func (RvTO2Addr) String

func (a RvTO2Addr) String() string

type RvVar

type RvVar uint8

RvVar is an FDO RVVariable.

const (
	RVDevOnly    RvVar = 0
	RVOwnerOnly  RvVar = 1
	RVIPAddress  RvVar = 2
	RVDevPort    RvVar = 3
	RVOwnerPort  RvVar = 4
	RVDns        RvVar = 5
	RVSvCertHash RvVar = 6
	RVClCertHash RvVar = 7
	RVUserInput  RvVar = 8
	RVWifiSsid   RvVar = 9
	RVWifiPw     RvVar = 10
	RVMedium     RvVar = 11
	RVProtocol   RvVar = 12
	RVDelaysec   RvVar = 13
	RVBypass     RvVar = 14
	RVExtRV      RvVar = 15
)

Rendezvous Variables

type To1d

type To1d struct {
	RV       []RvTO2Addr
	To0dHash Hash
}

To1d is a "blob" that indicates a network address (RVTO2Addr) where the Device can find a prospective Owner for the TO2 Protocol.

func (To1d) String

func (to1d To1d) String() string

type TokenService

type TokenService interface {
	// NewToken initializes state for a given protocol and return the
	// associated token.
	NewToken(context.Context, Protocol) (string, error)

	// InvalidateToken destroys the state associated with a given token.
	InvalidateToken(context.Context) error

	// TokenContext injects a context with a token value so that it may be used
	// for any of the XXXState interfaces.
	TokenContext(context.Context, string) context.Context

	// TokenFromContext gets the token value from a context. This is useful,
	// because some TokenServices may allow token mutation, such as in the case
	// of token-encoded state (i.e. JWTs/CWTs).
	TokenFromContext(context.Context) (string, bool)
}

TokenService maintains state related to the authorization header or similar token. The purpose of the token is to link API calls to their protocol context within the message stream defined by the FIDO Device Onboard Protocols. The handler for a subsequent message can find this stored state by looking it up using the token as a key.

type TransportProtocol

type TransportProtocol uint8

TransportProtocol is used to indicate which protocol to use in the Rendezvous blob.

const (
	TCPTransport   TransportProtocol = 1
	TLSTransport   TransportProtocol = 2
	HTTPTransport  TransportProtocol = 3
	CoAPTransport  TransportProtocol = 4
	HTTPSTransport TransportProtocol = 5
	CoAPSTransport TransportProtocol = 6
)

CDDL from spec:

TransportProtocol /= (
   ProtTCP:    1,     ;; bare TCP stream
   ProtTLS:    2,     ;; bare TLS stream
   ProtHTTP:   3,
   ProtCoAP:   4,
   ProtHTTPS:  5,
   ProtCoAPS:  6,
)

func (TransportProtocol) String

func (p TransportProtocol) String() string

Jump to

Keyboard shortcuts

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