2023-05-24 13:22:00 +03:00
|
|
|
package webauthn
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/descope/virtualwebauthn"
|
2023-06-07 17:28:42 +02:00
|
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
|
|
"google.golang.org/protobuf/types/known/structpb"
|
2023-05-24 13:22:00 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type Client struct {
|
2023-08-11 18:36:18 +03:00
|
|
|
rp virtualwebauthn.RelyingParty
|
|
|
|
auth virtualwebauthn.Authenticator
|
|
|
|
authVerifyUser virtualwebauthn.Authenticator
|
|
|
|
credential virtualwebauthn.Credential
|
2023-05-24 13:22:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewClient(name, domain, origin string) *Client {
|
|
|
|
rp := virtualwebauthn.RelyingParty{
|
|
|
|
Name: name,
|
|
|
|
ID: domain,
|
|
|
|
Origin: origin,
|
|
|
|
}
|
|
|
|
return &Client{
|
2023-08-11 18:36:18 +03:00
|
|
|
rp: rp,
|
|
|
|
auth: virtualwebauthn.NewAuthenticatorWithOptions(virtualwebauthn.AuthenticatorOptions{
|
|
|
|
UserNotVerified: true,
|
|
|
|
}),
|
|
|
|
authVerifyUser: virtualwebauthn.NewAuthenticator(),
|
|
|
|
credential: virtualwebauthn.NewCredential(virtualwebauthn.KeyTypeEC2),
|
2023-05-24 13:22:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-07 17:28:42 +02:00
|
|
|
func (c *Client) CreateAttestationResponse(optionsPb *structpb.Struct) (*structpb.Struct, error) {
|
|
|
|
options, err := protojson.Marshal(optionsPb)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAttestationResponse: %w", err)
|
|
|
|
}
|
2023-05-24 13:22:00 +03:00
|
|
|
parsedAttestationOptions, err := virtualwebauthn.ParseAttestationOptions(string(options))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAttestationResponse: %w", err)
|
|
|
|
}
|
2023-06-07 17:28:42 +02:00
|
|
|
resp := new(structpb.Struct)
|
|
|
|
err = protojson.Unmarshal([]byte(virtualwebauthn.CreateAttestationResponse(
|
2023-05-24 13:22:00 +03:00
|
|
|
c.rp, c.auth, c.credential, *parsedAttestationOptions,
|
2023-06-07 17:28:42 +02:00
|
|
|
)), resp)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAttestationResponse: %w", err)
|
|
|
|
}
|
|
|
|
return resp, nil
|
|
|
|
}
|
|
|
|
|
2023-08-11 18:36:18 +03:00
|
|
|
func (c *Client) CreateAssertionResponse(optionsPb *structpb.Struct, verifyUser bool) (*structpb.Struct, error) {
|
2023-06-07 17:28:42 +02:00
|
|
|
options, err := protojson.Marshal(optionsPb)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAssertionResponse: %w", err)
|
|
|
|
}
|
|
|
|
parsedAssertionOptions, err := virtualwebauthn.ParseAssertionOptions(string(options))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAssertionResponse: %w", err)
|
|
|
|
}
|
2023-08-11 18:36:18 +03:00
|
|
|
authenticator := c.auth
|
|
|
|
if verifyUser {
|
|
|
|
authenticator = c.authVerifyUser
|
|
|
|
}
|
2023-06-07 17:28:42 +02:00
|
|
|
resp := new(structpb.Struct)
|
|
|
|
err = protojson.Unmarshal([]byte(virtualwebauthn.CreateAssertionResponse(
|
2023-08-11 18:36:18 +03:00
|
|
|
c.rp, authenticator, c.credential, *parsedAssertionOptions,
|
2023-06-07 17:28:42 +02:00
|
|
|
)), resp)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("webauthn.Client.CreateAssertionResponse: %w", err)
|
|
|
|
}
|
|
|
|
return resp, nil
|
2023-05-24 13:22:00 +03:00
|
|
|
}
|