Skip to content

Commit 089780e

Browse files
committed
WIP
1 parent eb44e29 commit 089780e

File tree

1 file changed

+49
-44
lines changed

1 file changed

+49
-44
lines changed

src/Controllers/VerifiableCredentials/CredentialIssuerCredentialController.php

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
use SimpleSAML\OpenID\Exceptions\OpenId4VciProofException;
2626
use SimpleSAML\OpenID\Jwk;
2727
use SimpleSAML\OpenID\VerifiableCredentials;
28+
use SimpleSAML\OpenID\VerifiableCredentials\OpenId4VciProof;
2829
use Symfony\Component\HttpFoundation\Request;
2930
use Symfony\Component\HttpFoundation\Response;
3031

3132
class CredentialIssuerCredentialController
3233
{
33-
3434
public const SD_JWT_FORMAT_IDS = [
3535
CredentialFormatIdentifiersEnum::DcSdJwt->value,
3636
CredentialFormatIdentifiersEnum::VcSdJwt->value,
@@ -88,22 +88,48 @@ public function credential(Request $request): Response
8888

8989
// TODO mivanci Validate credential request
9090

91+
$credentialFormatId = $requestData[ClaimsEnum::Format->value] ?? null;
92+
93+
if (is_null($credentialFormatId)) {
94+
throw OidcServerException::serverError('Credential format missing in request.');
95+
}
96+
97+
if (
98+
!in_array($credentialFormatId, [
99+
CredentialFormatIdentifiersEnum::JwtVcJson->value,
100+
CredentialFormatIdentifiersEnum::DcSdJwt->value,
101+
CredentialFormatIdentifiersEnum::VcSdJwt->value, // Deprecated value, but let's support it for now.
102+
])
103+
) {
104+
return $this->routes->newJsonErrorResponse(
105+
'unsupported_credential_type',
106+
sprintf('Credential format ID "%s" is not supported.', $credentialFormatId),
107+
);
108+
}
109+
91110
// TODO mivanci Check / handle credential_identifier parameter.
92111

93112
$credentialConfigurationId = $requestData[ClaimsEnum::CredentialConfigurationId->value] ?? null;
94113

95114
if (is_null($credentialConfigurationId)) {
96-
// Check per draft 14
115+
// TODO mivanci Update this to newest draft.
116+
// Check per draft 14 (Sphereon wallet case).
97117
if (
118+
$credentialFormatId === CredentialFormatIdentifiersEnum::JwtVcJson->value &&
98119
is_array(
99120
$credentialDefinitionType =
100-
$requestData[ClaimsEnum::CredentialDefinition->value][ClaimsEnum::Type->value],
121+
$requestData[ClaimsEnum::CredentialDefinition->value][ClaimsEnum::Type->value] ?? null,
101122
)
102123
) {
103124
$credentialConfigurationId =
104125
$this->moduleConfig->getCredentialConfigurationIdForCredentialDefinitionType(
105126
$credentialDefinitionType,
106127
);
128+
} elseif (
129+
in_array($credentialFormatId, self::SD_JWT_FORMAT_IDS, true) &&
130+
is_string($vct = $requestData[ClaimsEnum::Vct->value] ?? null)
131+
) {
132+
$credentialConfigurationId = $vct;
107133
}
108134
}
109135

@@ -114,38 +140,13 @@ public function credential(Request $request): Response
114140
);
115141
}
116142

117-
if (
118-
!is_array(
119-
$credentialConfiguration = $this->moduleConfig->getCredentialConfiguration($credentialConfigurationId),
120-
)
121-
) {
143+
if (!is_array($this->moduleConfig->getCredentialConfiguration($credentialConfigurationId))) {
122144
return $this->routes->newJsonErrorResponse(
123145
'unsupported_credential_type',
124146
sprintf('Credential configuration ID "%s" is not supported.', $credentialConfigurationId),
125147
);
126148
}
127149

128-
$credentialFormatId = $credentialConfiguration[ClaimsEnum::Format->value] ?? null;
129-
130-
if (is_null($credentialFormatId)) {
131-
throw OidcServerException::serverError(
132-
'Credential format not specified for configuration ID: ' . $credentialConfigurationId,
133-
);
134-
}
135-
136-
if (
137-
!in_array($credentialFormatId, [
138-
CredentialFormatIdentifiersEnum::JwtVcJson->value,
139-
CredentialFormatIdentifiersEnum::DcSdJwt->value,
140-
CredentialFormatIdentifiersEnum::VcSdJwt->value, // Deprecated value, but let's support it for now.
141-
])
142-
) {
143-
return $this->routes->newJsonErrorResponse(
144-
'unsupported_credential_type',
145-
sprintf('Credential format ID "%s" is not supported.', $credentialFormatId),
146-
);
147-
}
148-
149150
$userId = $accessToken->getUserIdentifier();
150151
$userEntity = $this->userRepository->getUserEntityByIdentifier($userId);
151152
if ($userEntity === null) {
@@ -155,6 +156,7 @@ public function credential(Request $request): Response
155156
// Placeholder sub identifier. Will do if proof is not provided.
156157
$sub = $this->moduleConfig->getIssuer() . '/sub/' . $userId;
157158

159+
$proof = null;
158160
// Validate proof, if provided.
159161
// TODO mivanci consider making proof mandatory (in issuer metadata).
160162
if (
@@ -284,12 +286,11 @@ public function credential(Request $request): Response
284286
saltBlacklist: $disclosureBag->salts(),
285287
);
286288

287-
$disclosureBag->add($disclosure);;
289+
$disclosureBag->add($disclosure);
288290
}
289291
}
290292

291-
dd($disclosureBag->all());
292-
// Also make sure that the subject identifier is in credentialSubject claim.
293+
// Make sure that the subject identifier is in credentialSubject claim.
293294
$this->setCredentialClaimValue(
294295
$credentialSubject,
295296
[ClaimsEnum::Credential_Subject->value, ClaimsEnum::Id->value],
@@ -336,15 +337,13 @@ public function credential(Request $request): Response
336337
],
337338
//ClaimsEnum::Issuer->value => $this->moduleConfig->getIssuer(),
338339
ClaimsEnum::Issuer->value => $issuerDid,
339-
//ClaimsEnum::Issuer->value => 'https://idp.mivanci.incubator.hexaa.eu/ssp/module.php/oidc/jwks',
340340
ClaimsEnum::Issuance_Date->value => $issuedAt->format(\DateTimeInterface::RFC3339),
341341
ClaimsEnum::Id->value => $vcId,
342342
ClaimsEnum::Credential_Subject->value =>
343343
$credentialSubject[ClaimsEnum::Credential_Subject->value] ?? [],
344344
],
345345
//ClaimsEnum::Iss->value => $this->moduleConfig->getIssuer(),
346346
ClaimsEnum::Iss->value => $issuerDid,
347-
//ClaimsEnum::Iss->value => 'https://idp.mivanci.incubator.hexaa.eu/ssp/module.php/oidc/jwks',
348347
ClaimsEnum::Iat->value => $issuedAt->getTimestamp(),
349348
ClaimsEnum::Nbf->value => $issuedAt->getTimestamp(),
350349
ClaimsEnum::Sub->value => $sub,
@@ -357,27 +356,33 @@ public function credential(Request $request): Response
357356
}
358357

359358
if (in_array($credentialFormatId, self::SD_JWT_FORMAT_IDS, true)) {
360-
// TODO selectiveDisclosureBag
359+
$sdJwtPayload = [
360+
ClaimsEnum::Iss->value => $issuerDid,
361+
ClaimsEnum::Iat->value => $issuedAt->getTimestamp(),
362+
ClaimsEnum::Nbf->value => $issuedAt->getTimestamp(),
363+
ClaimsEnum::Sub->value => $sub,
364+
ClaimsEnum::Jti->value => $vcId,
365+
ClaimsEnum::Vct->value => $credentialConfigurationId,
366+
];
367+
368+
if ($proof instanceof OpenId4VciProof) {
369+
$sdJwtPayload[ClaimsEnum::Cnf->value] = [
370+
ClaimsEnum::Kid->value => $proof->getKeyId(),
371+
];
372+
}
361373

362374
$verifiableCredential = $this->verifiableCredentials->sdJwtVcFactory()->fromData(
363375
$signingKey,
364376
$signatureAlgorithm,
365-
[
366-
ClaimsEnum::Iss->value => $issuerDid,
367-
ClaimsEnum::Iat->value => $issuedAt->getTimestamp(),
368-
ClaimsEnum::Nbf->value => $issuedAt->getTimestamp(),
369-
ClaimsEnum::Sub->value => $sub,
370-
ClaimsEnum::Jti->value => $vcId,
371-
],
377+
$sdJwtPayload,
372378
[
373379
ClaimsEnum::Kid->value => $issuerDid . '#0',
374380
],
381+
disclosureBag: $disclosureBag,
375382
jwtTypesEnum: JwtTypesEnum::VcSdJwt,
376383
);
377384
}
378385

379-
380-
381386
$this->loggerService->debug('response', [
382387
'credentials' => [
383388
['credential' => $verifiableCredential->getToken()],

0 commit comments

Comments
 (0)