Skip to content

Commit

Permalink
Merge pull request trustbloc#1669 from trustbloc/multiple_credentials…
Browse files Browse the repository at this point in the history
…_issuance

feat: Multiple credentials issuance
  • Loading branch information
fqutishat authored Mar 20, 2024
2 parents 5e58a22 + 272dde2 commit 2996ff9
Show file tree
Hide file tree
Showing 50 changed files with 9,740 additions and 2,336 deletions.
362 changes: 187 additions & 175 deletions api/spec/openapi.gen.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cmd/vc-rest/startcmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ func buildEchoHandler(
JSONSchemaValidator: jsonSchemaValidator,
TrustRegistry: trustRegistryService,
AckService: ackService,
Composer: oidc4ci.NewCredentialComposer(),
})
if err != nil {
return nil, fmt.Errorf("failed to instantiate new oidc4ci service: %w", err)
Expand Down
24 changes: 15 additions & 9 deletions component/wallet-cli/cmd/oidc4vci_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http"
"net/http/cookiejar"
"net/url"
"strings"

"github.com/henvic/httpretty"
"github.com/piprate/json-gold/ld"
Expand Down Expand Up @@ -44,7 +45,7 @@ type oidc4vciCommandFlags struct {
demoIssuerURL string
vcFormat string
credentialType string
oidcCredentialFormat vcsverifiable.OIDCFormat
oidcCredentialFormat string
walletDIDIndex int
clientID string
scopes []string
Expand Down Expand Up @@ -202,12 +203,21 @@ func NewOIDC4VCICommand() *cobra.Command {

var flow *oidc4vci.Flow

types := strings.Split(flags.credentialType, ",")
formats := strings.Split(flags.oidcCredentialFormat, ",")
if len(types) != len(formats) {
return fmt.Errorf(
"credential types and formats amount mismatch: types %d, formats %d", len(types), len(formats))
}

opts := []oidc4vci.Opt{
oidc4vci.WithCredentialType(flags.credentialType),
oidc4vci.WithOIDCCredentialFormat(flags.oidcCredentialFormat),
oidc4vci.WithClientID(flags.clientID),
}

for i, t := range types {
opts = append(opts, oidc4vci.WithCredentialFilter(t, vcsverifiable.OIDCFormat(formats[i])))
}

if walletInitiatedFlow {
opts = append(opts, oidc4vci.WithIssuerState(flags.issuerState))
} else {
Expand Down Expand Up @@ -281,17 +291,15 @@ func NewOIDC4VCICommand() *cobra.Command {
},
}

var oidcCredentialFormat string

cmd.Flags().StringVar(&flags.serviceFlags.levelDBPath, "leveldb-path", "", "leveldb path")
cmd.Flags().StringVar(&flags.serviceFlags.mongoDBConnectionString, "mongodb-connection-string", "", "mongodb connection string")

cmd.Flags().StringVar(&flags.grantType, "grant-type", "authorization_code", "supported grant types: authorization_code,urn:ietf:params:oauth:grant-type:pre-authorized_code")
cmd.Flags().StringVar(&flags.qrCodePath, "qr-code-path", "", "path to file with qr code")
cmd.Flags().StringVar(&flags.credentialOffer, "credential-offer", "", "openid credential offer")
cmd.Flags().StringVar(&flags.demoIssuerURL, "demo-issuer-url", "", "demo issuer url for downloading qr code automatically")
cmd.Flags().StringVar(&oidcCredentialFormat, "credential-format", "ldp_vc", "supported credential formats: ldp_vc,jwt_vc_json-ld")
cmd.Flags().StringVar(&flags.credentialType, "credential-type", "", "credential type")
cmd.Flags().StringVar(&flags.oidcCredentialFormat, "credential-format", "ldp_vc", "comma-separated supported OIDC credential formats: ldp_vc,jwt_vc_json-ld")
cmd.Flags().StringVar(&flags.credentialType, "credential-type", "", "comma-separated credential types")
cmd.Flags().StringVar(&flags.proofType, "proof-type", "", "proof-type. jwt or cwt. default jwt")
cmd.Flags().IntVar(&flags.walletDIDIndex, "wallet-did-index", -1, "index of wallet did, if not set the most recently created DID is used")
cmd.Flags().StringVar(&flags.clientID, "client-id", "", "vcs oauth2 client")
Expand All @@ -308,8 +316,6 @@ func NewOIDC4VCICommand() *cobra.Command {
cmd.Flags().BoolVar(&flags.enableTracing, "enable-tracing", false, "enables http tracing")
cmd.Flags().StringVar(&flags.proxyURL, "proxy-url", "", "proxy url for http client")

flags.oidcCredentialFormat = vcsverifiable.OIDCFormat(oidcCredentialFormat)

return cmd
}

Expand Down
60 changes: 57 additions & 3 deletions component/wallet-cli/pkg/oidc4vci/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,58 @@ type ProofClaims struct {
}

type CredentialRequest struct {
Format verifiable.OIDCFormat `json:"format,omitempty"`
Types []string `json:"types"`
Proof Proof `json:"proof,omitempty"`
Format verifiable.OIDCFormat `json:"format,omitempty"`
CredentialDefinition *CredentialDefinition `json:"credential_definition,omitempty"`
CredentialIdentifier *string `json:"credential_identifier,omitempty"`
Proof Proof `json:"proof,omitempty"`
CredentialResponseEncryption *CredentialResponseEncryption `json:"credential_response_encryption,omitempty"`
}

// CredentialDefinition contains the detailed description of the credential type.
type CredentialDefinition struct {
// For ldp_vc only. Array as defined in https://www.w3.org/TR/vc-data-model/#contexts.
Context *[]string `json:"@context,omitempty"`
// An object containing a list of name/value pairs, where each name identifies a claim offered in the Credential. The value can be another such object (nested data structures), or an array of such objects.
CredentialSubject *map[string]interface{} `json:"credentialSubject,omitempty"`
// Array designating the types a certain credential type supports
Type []string `json:"type"`
}

// CredentialResponseEncryption containing information for encrypting the Credential Response.
type CredentialResponseEncryption struct {
// JWE alg algorithm for encrypting the Credential Response.
Alg string `json:"alg"`

// JWE enc algorithm for encrypting the Credential Response.
Enc string `json:"enc"`

// Object containing a single public key as a JWK used for encrypting the Credential Response.
Jwk string `json:"jwk"`
}

type BatchCredentialRequest struct {
CredentialRequests []CredentialRequest `json:"credential_requests"`
}

// BatchCredentialResponse for OIDC Batch Credential response.
type BatchCredentialResponse struct {
// JSON string containing a nonce to be used to create a proof of possession of key material when requesting a Credential.
CNonce *string `json:"c_nonce,omitempty"`

// JSON integer denoting the lifetime in seconds of the c_nonce.
CNonceExpiresIn *int `json:"c_nonce_expires_in,omitempty"`
CredentialResponses []CredentialResponseBatchCredential `json:"credential_responses"`
}

type CredentialResponseBatchCredential struct {
// Contains issued Credential.
Credential interface{} `json:"credential"`

// String identifying an issued Credential that the Wallet includes in the acknowledgement request.
NotificationId *string `json:"notification_id,omitempty"`

// OPTIONAL. String identifying a Deferred Issuance transaction. This claim is contained in the response if the Credential Issuer was unable to immediately issue the Credential. The value is subsequently used to obtain the respective Credential with the Deferred Credential Endpoint.
TransactionId *string `json:"transaction_id,omitempty"`
}

type Proof struct {
Expand All @@ -47,3 +96,8 @@ type PerfInfo struct {
GetCredential time.Duration `json:"vci_get_credential"`
CredentialsAck time.Duration `json:"vci_credentials_ack"`
}

type parseCredentialResponseData struct {
credential interface{}
notificationID *string
}
Loading

0 comments on commit 2996ff9

Please sign in to comment.