Documentation
¶
Overview ¶
Package apiclient/verification implements the interaction model described in https://github.com/veraison/veraison/tree/main/docs/api/challenge-response
Challenge-Response, atomic operation ¶
Using this mode of operation the whole API client exchange is handled atomically through a single invocation of the Run() method.
The user provides the Evidence generation logics by implementing the EvidenceBuilder interface:
type MyEvidenceBuilder struct {
// build context (e.g., signing key material, claims template, etc.)
}
func (eb MyEvidenceBuilder) BuildEvidence(nonce []byte, accept []string) ([]byte, string, error) {
for _, ct := range accept {
if ct == "application/my-evidence-media-type" {
evidence, err := buildEvidence(nonce, eb)
if err != nil { ... }
return evidence, ct, nil
}
}
return nil, "", errors.New("no match on accepted media types")
}
The user then creates a ChallengeResponseConfig object supplying the callback and either an explicit nonce:
cfg := ChallengeResponseConfig{
Nonce: []byte{0xde, 0xad, 0xbe, 0xef},
EvidenceBuilder: MyEvidenceBuilder{...},
NewSessionURI: "http://veraison.example/challenge-response/v1/newSession",
}
or just the size of a nonce to be provided by the server side:
cfg := ChallengeResponseConfig{
NonceSz: 32,
EvidenceBuilder: MyEvidenceBuilder{...},
NewSessionURI: "http://veraison.example/challenge-response/v1/newSession",
}
The user can also supply a custom Client object, for example to appropriately configure the underlying TLS transport:
cfg.Client = &Client{
HTTPClient: http.Client{
Transport: myTLSConfig,
}
}
The user can also request to explicitly delete the session resource at the server instead of letting it expire:
cfg.DeleteSession = true
Then the Run method is invoked on the instantiated ChallengeReponseConfig object to trigger the protocol FSM, hiding any details about the synchronus / async nature of the underlying exchange:
attestationResult, err := cfg.Run()
On success, the Attestation Result, is returned as a JSON string:
if err == nil {
fmt.Println(string(attestationResult))
}
Challenge-Response, split operation ¶
Using this mode of operation the client is responsible for dealing with each API call separately, invoking the right API method at the right time and place.
In this mode, users does not provide the Evidence generation logics through the EvidenceBuilder interface. Instead, they will need to plug in their Evidence building logics between the call to NewSession() and the subsequent ChallengeResponse().
Similarly to the atomic operation case, users create a ChallengeResponseConfig object supplying either an explicit nonce or the requested nonce size, and any other applicable configuration parameter, e.g., a custom Client:
cfg := ChallengeResponseConfig{
Nonce: []byte{0xde, 0xad, 0xbe, 0xef},
NewSessionURI: "http://veraison.example/challenge-response/v1/newSession",
Client: &Client{
HTTPClient: http.Client{
Transport: myTLSConfig,
},
},
}
Same as the atomic model, users can also request to explicitly delete the session resource on the server instead of letting it expire by setting the DeleteSession configuration parameter to true.
The NewSession() method is then invoked on the instantiated ChallengeReponseConfig object to trigger the creation of a new session resource on the server:
newSessionCtx, sessionURI, err := cfg.NewSession()
Users need to use the nonce returned in newSessionCtx.Nonce to trigger a challenge-response session with the Attester and obtain the Evidence. Users will typically make use of the acceptable Evidence formats advertised by the server in newSessionCtx.Accept as an additional input to the protocol with the Attester.
When the Evidence has been obtained, the ChallengeResponse() method can be invoked to submit it to the allocated session with the Verifier that, on success, will return the Attestation Result:
attestationResult, err := cfg.ChallengeResponse(evidence, mediaType, sessionURI)
Discovery ¶
The discovery document retrieval process is encapsulated in the DiscoveryConfig object.
Users create a DiscoveryConfig object supplying the Discovery URI:
cfg := DiscoveryConfig{}
err := cfg.SetDiscoveryURI("http://veraison.example/.well-known/veraison/verification")
if err != nil {
// handle error
}
The user can also supply a custom Client object, for example to appropriately configure the underlying TLS transport:
err = cfg.SetClient(&common.Client{
HTTPClient: http.Client{
Transport: myTLSConfig,
}
})
if err != nil {
// handle error
}
Then the Run method is invoked on the instantiated DiscoveryConfig object to trigger the retrieval of the discovery document:
discoveryObject, err := cfg.Run()
if err != nil {
// handle error
}
On success, the decoded discovery document is returned as a DiscoveryObject structure:
fmt.Printf("%+v\n", discoveryObject)
The discovery document contains various pieces of information, including the URI of the "new session" challenge-response endpoint. This URI can be used to instantiate a ChallengeResponseConfig object, as described above. It also contains details of the Evidence media types supported by the Verifier and the Verifier's public key. The latter can be used to verify the signature on the Attestation Result returned by the challenge-response protocol.
Index ¶
- type Blob
- type ChallengeResponseConfig
- func (cfg ChallengeResponseConfig) ChallengeResponse(evidence []byte, mediaType string, uri string) ([]byte, error)
- func (cfg ChallengeResponseConfig) NewSession() (*ChallengeResponseSession, string, error)
- func (cfg *ChallengeResponseConfig) Run() ([]byte, error)
- func (cfg *ChallengeResponseConfig) SetCerts(paths []string)
- func (cfg *ChallengeResponseConfig) SetClient(client *common.Client) error
- func (cfg *ChallengeResponseConfig) SetDeleteSession(val bool)
- func (cfg *ChallengeResponseConfig) SetEvidenceBuilder(evidenceBuilder EvidenceBuilder) error
- func (cfg *ChallengeResponseConfig) SetIsInsecure(val bool)
- func (cfg *ChallengeResponseConfig) SetNonce(nonce []byte) error
- func (cfg *ChallengeResponseConfig) SetNonceSz(nonceSz uint) error
- func (cfg *ChallengeResponseConfig) SetSessionURI(uri string) error
- func (cfg *ChallengeResponseConfig) SetWrap(val CmwWrap) error
- type ChallengeResponseSession
- type CmwWrap
- type DiscoveryConfig
- type DiscoveryObject
- type EvidenceBuilder
- type StaticEvidenceBuilder
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Blob ¶
Blob wraps a base64 encoded value together with its media type (used for evidence in rats-challenge-response-session+json)
type ChallengeResponseConfig ¶
type ChallengeResponseConfig struct {
Nonce []byte // an explicit nonce supplied by the user
CACerts []string // paths to CA certs to be used in addition to system certs for TLS connections
NonceSz uint // the size of a nonce to be provided by server
EvidenceBuilder EvidenceBuilder // Evidence generation logics supplied by the user
NewSessionURI string // URI of the "/newSession" endpoint
Client *common.Client // HTTP(s) client connection configuration
Wrap CmwWrap // when set, wrap the supplied evidence as a Conceptual Message Wrapper(CMW)
Auth auth.IAuthenticator // when set, Auth supplies the Authorization header for requests
DeleteSession bool // explicitly DELETE the session object after we are done
UseTLS bool // use TLS for server connections
IsInsecure bool // allow insecure server connections (only matters when UseTLS is true)
}
ChallengeResponseConfig holds the configuration for one or more challenge-response exchanges
func (ChallengeResponseConfig) ChallengeResponse ¶
func (cfg ChallengeResponseConfig) ChallengeResponse( evidence []byte, mediaType string, uri string, ) ([]byte, error)
ChallengeResponse runs the second portion of the interaction protocol that deals with Evidence submission and retrieval of the associated Attestation Result. On success, the Attestation result in JSON format is returned.
func (ChallengeResponseConfig) NewSession ¶
func (cfg ChallengeResponseConfig) NewSession() (*ChallengeResponseSession, string, error)
NewSession runs the first part of the interaction which deals with session creation, nonce and token format negotiation. On success, the session object is returned together with the URI of the new session endpoint
func (*ChallengeResponseConfig) Run ¶
func (cfg *ChallengeResponseConfig) Run() ([]byte, error)
Run implements the challenge-response protocol FSM invoking the user callback. On success, the received Attestation Result is returned.
func (*ChallengeResponseConfig) SetCerts ¶ added in v0.3.0
func (cfg *ChallengeResponseConfig) SetCerts(paths []string)
SetCerts sets the CACerts parameter to the specified paths
func (*ChallengeResponseConfig) SetClient ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetClient(client *common.Client) error
SetClient sets the HTTP(s) client connection configuration
func (*ChallengeResponseConfig) SetDeleteSession ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetDeleteSession(val bool)
SetDeleteSession sets the DeleteSession parameter using the supplied val
func (*ChallengeResponseConfig) SetEvidenceBuilder ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetEvidenceBuilder(evidenceBuilder EvidenceBuilder) error
SetEvidenceBuilder sets the Evidence Builder callback supplied by the user
func (*ChallengeResponseConfig) SetIsInsecure ¶ added in v0.3.0
func (cfg *ChallengeResponseConfig) SetIsInsecure(val bool)
SetIsInsecure sets the IsInsecure parameter using the supplied val
func (*ChallengeResponseConfig) SetNonce ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetNonce(nonce []byte) error
SetNonce sets the Nonce supplied by the user
func (*ChallengeResponseConfig) SetNonceSz ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetNonceSz(nonceSz uint) error
SetNonceSz sets the nonce size supplied by the user
func (*ChallengeResponseConfig) SetSessionURI ¶ added in v0.0.3
func (cfg *ChallengeResponseConfig) SetSessionURI(uri string) error
SetSessionURI sets the New Session URI supplied by the user
func (*ChallengeResponseConfig) SetWrap ¶ added in v0.0.5
func (cfg *ChallengeResponseConfig) SetWrap(val CmwWrap) error
SetWrap sets the Wrap parameter using the supplied val
type ChallengeResponseSession ¶
type ChallengeResponseSession struct {
Nonce []byte `json:"nonce"`
Expiry string `json:"expiry"`
Accept []string `json:"accept"`
Status string `json:"status"`
Evidence Blob `json:"evidence"`
Result json.RawMessage `json:"result"`
}
ChallengeResponseSession models the rats-challenge-response-session+json media type, i.e., the representation of the session resource server-side
type DiscoveryConfig ¶ added in v0.4.0
type DiscoveryConfig struct {
// contains filtered or unexported fields
}
DiscoveryConfig holds the configuration for one or more retrievals from the discovery endpoint.
func (*DiscoveryConfig) Run ¶ added in v0.4.0
func (cfg *DiscoveryConfig) Run() (*DiscoveryObject, error)
Run retrieves the discovery document from the configured endpoint. On success, the decoded discovery document is returned.
func (*DiscoveryConfig) SetCerts ¶ added in v0.4.0
func (cfg *DiscoveryConfig) SetCerts(paths []string) error
SetCerts sets the CA certificates to the specified paths
func (*DiscoveryConfig) SetClient ¶ added in v0.4.0
func (cfg *DiscoveryConfig) SetClient(client *common.Client) error
SetClient sets the HTTP(s) client connection configuration
func (*DiscoveryConfig) SetDiscoveryURI ¶ added in v0.4.0
func (cfg *DiscoveryConfig) SetDiscoveryURI(uri string) error
SetDiscoveryURI sets the discovery URI supplied by the user
func (*DiscoveryConfig) SetIsInsecure ¶ added in v0.4.0
func (cfg *DiscoveryConfig) SetIsInsecure()
SetIsInsecure sets the flag to allow insecure server connections
type DiscoveryObject ¶ added in v0.4.0
type DiscoveryObject struct {
PublicKey json.RawMessage `json:"ear-verification-key,omitempty"`
MediaTypes []string `json:"media-types,omitempty"`
Schemes []string `json:"attestation-schemes,omitempty"`
Version string `json:"version"`
ServiceState string `json:"service-state"`
ApiEndpoints map[string]string `json:"api-endpoints"`
}
type EvidenceBuilder ¶
type EvidenceBuilder interface {
BuildEvidence(nonce []byte, accept []string) (evidence []byte, mediaType string, err error)
}
EvidenceBuilder is the interface between the challenge-response protocol FSM and the user. The user is given a nonce and the list of acceptable Evidence formats and is asked to return the serialized Evidence as a byte array together with its media type - or an error if anything goes wrong.
func NewStaticEvidenceBuilder ¶ added in v0.4.0
func NewStaticEvidenceBuilder(evidence []byte, mediaType string) EvidenceBuilder
NewStaticEvidenceBuilder creates a new StaticEvidenceBuilder with the specified evidence and media type.
type StaticEvidenceBuilder ¶ added in v0.4.0
type StaticEvidenceBuilder struct {
// contains filtered or unexported fields
}
StaticEvidenceBuilder is a simple EvidenceBuilder that always returns the same static evidence and media type. This is can be used when the evidence is already available and does not need to be dynamically generated (RP mode) or for testing purposes.
func (StaticEvidenceBuilder) BuildEvidence ¶ added in v0.4.0
BuildEvidence returns the static evidence if the media type is in the list of accepted media types; otherwise, it returns an error. Note that the nonce parameter is ignored.