@openeudi/openid4vp 0.9.3 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -11
- package/dist/index.cjs +27 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +27 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -16,7 +16,8 @@ interface AuthorizationRequest {
|
|
|
16
16
|
state: string;
|
|
17
17
|
}
|
|
18
18
|
interface SignedAuthorizationRequestInput {
|
|
19
|
-
|
|
19
|
+
clientIdPrefix?: 'x509_san_dns' | 'x509_hash';
|
|
20
|
+
hostname?: string;
|
|
20
21
|
requestUri: string;
|
|
21
22
|
responseUri: string;
|
|
22
23
|
nonce: string;
|
|
@@ -54,7 +55,10 @@ declare function createAuthorizationRequest(input: AuthorizationRequestInput, qu
|
|
|
54
55
|
* carrying only `client_id` + `request_uri`, plus the JWS string the caller
|
|
55
56
|
* must host at `requestUri` with Content-Type `application/oauth-authz-req+jwt`.
|
|
56
57
|
*
|
|
57
|
-
* Client Identifier Prefix
|
|
58
|
+
* Client Identifier Prefix defaults to `x509_san_dns`; pass
|
|
59
|
+
* `clientIdPrefix: 'x509_hash'` to use the leaf certificate's SHA-256 hash
|
|
60
|
+
* instead (OpenID4VP 1.0 §5.9.3). `hostname` is required only for
|
|
61
|
+
* `x509_san_dns`.
|
|
58
62
|
*/
|
|
59
63
|
declare function createSignedAuthorizationRequest(input: SignedAuthorizationRequestInput, query: DcqlQuery): Promise<SignedAuthorizationRequest>;
|
|
60
64
|
|
|
@@ -611,7 +615,7 @@ declare class LotlFetchError extends OpenID4VPError {
|
|
|
611
615
|
declare class LotlSignatureError extends OpenID4VPError {
|
|
612
616
|
readonly code: "lotl_signature_invalid";
|
|
613
617
|
}
|
|
614
|
-
type SignedRequestBuildErrorCode = 'empty_cert_chain' | 'hostname_cert_mismatch' | 'signing_key_cert_mismatch' | 'missing_encryption_jwk' | 'missing_encryption_alg' | 'missing_vp_formats' | 'unsupported_signing_alg' | 'empty_supported_enc_values';
|
|
618
|
+
type SignedRequestBuildErrorCode = 'empty_cert_chain' | 'hostname_cert_mismatch' | 'signing_key_cert_mismatch' | 'missing_encryption_jwk' | 'missing_encryption_alg' | 'missing_vp_formats' | 'unsupported_signing_alg' | 'empty_supported_enc_values' | 'missing_hostname';
|
|
615
619
|
declare class SignedRequestBuildError extends OpenID4VPError {
|
|
616
620
|
readonly code: SignedRequestBuildErrorCode;
|
|
617
621
|
constructor(code: SignedRequestBuildErrorCode, message: string);
|
|
@@ -680,6 +684,6 @@ declare class LotlTrustStore implements TrustStore {
|
|
|
680
684
|
private refresh;
|
|
681
685
|
}
|
|
682
686
|
|
|
683
|
-
declare const VERSION = "0.
|
|
687
|
+
declare const VERSION = "0.10.1";
|
|
684
688
|
|
|
685
689
|
export { type AuthorizationRequest, type AuthorizationRequestInput, type AuthorizationResponse, type Cache, CertificateChainError, type ChainErrorReason, CompositeTrustStore, type CredentialClaims, type CredentialFormat, DecryptionFailedError, type EncryptedResponse, ExpiredCredentialError, type Fetcher, HAIP_DOCTYPE_NAMESPACES, type HaipQueryInput, type HaipValidationCode, HaipValidationError, type ICredentialParser, InMemoryCache, InvalidSignatureError, type IssuerInfo, type LotlAnchorMetadata, LotlFetchError, LotlSignatureError, LotlTrustStore, type LotlTrustStoreOptions, MalformedCredentialError, MdocParser, MissingDecryptionKeyError, MissingVerifierEncryptionKeyError, MultipleCredentialsNotSupportedError, NonceValidationError, OpenID4VPError, type ParseOptions, type PresentationResult, RevocationCheckFailedError, RevokedCertificateError, SdJwtParser, type SignedAuthorizationRequest, type SignedAuthorizationRequestInput, SignedRequestBuildError, type SignedRequestBuildErrorCode, StaticTrustStore, type TrustAnchor, TrustAnchorNotFoundError, type TrustStore, type TrustStoreHint, type TrustStoreInput, UnsupportedFormatError, UnsupportedJweError, VERSION, type VerifyAuthorizationResponseOptions, type VerifyOptions, type VerifyResult, buildHaipQuery, buildOid4vpSessionTranscript, buildOpenID4VPHandoverSessionTranscript, createAuthorizationRequest, createSignedAuthorizationRequest, decryptAuthorizationResponse, isHaipQuery, parsePresentation, validateHaipQuery, verifyAuthorizationResponse, verifyPresentation };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,8 @@ interface AuthorizationRequest {
|
|
|
16
16
|
state: string;
|
|
17
17
|
}
|
|
18
18
|
interface SignedAuthorizationRequestInput {
|
|
19
|
-
|
|
19
|
+
clientIdPrefix?: 'x509_san_dns' | 'x509_hash';
|
|
20
|
+
hostname?: string;
|
|
20
21
|
requestUri: string;
|
|
21
22
|
responseUri: string;
|
|
22
23
|
nonce: string;
|
|
@@ -54,7 +55,10 @@ declare function createAuthorizationRequest(input: AuthorizationRequestInput, qu
|
|
|
54
55
|
* carrying only `client_id` + `request_uri`, plus the JWS string the caller
|
|
55
56
|
* must host at `requestUri` with Content-Type `application/oauth-authz-req+jwt`.
|
|
56
57
|
*
|
|
57
|
-
* Client Identifier Prefix
|
|
58
|
+
* Client Identifier Prefix defaults to `x509_san_dns`; pass
|
|
59
|
+
* `clientIdPrefix: 'x509_hash'` to use the leaf certificate's SHA-256 hash
|
|
60
|
+
* instead (OpenID4VP 1.0 §5.9.3). `hostname` is required only for
|
|
61
|
+
* `x509_san_dns`.
|
|
58
62
|
*/
|
|
59
63
|
declare function createSignedAuthorizationRequest(input: SignedAuthorizationRequestInput, query: DcqlQuery): Promise<SignedAuthorizationRequest>;
|
|
60
64
|
|
|
@@ -611,7 +615,7 @@ declare class LotlFetchError extends OpenID4VPError {
|
|
|
611
615
|
declare class LotlSignatureError extends OpenID4VPError {
|
|
612
616
|
readonly code: "lotl_signature_invalid";
|
|
613
617
|
}
|
|
614
|
-
type SignedRequestBuildErrorCode = 'empty_cert_chain' | 'hostname_cert_mismatch' | 'signing_key_cert_mismatch' | 'missing_encryption_jwk' | 'missing_encryption_alg' | 'missing_vp_formats' | 'unsupported_signing_alg' | 'empty_supported_enc_values';
|
|
618
|
+
type SignedRequestBuildErrorCode = 'empty_cert_chain' | 'hostname_cert_mismatch' | 'signing_key_cert_mismatch' | 'missing_encryption_jwk' | 'missing_encryption_alg' | 'missing_vp_formats' | 'unsupported_signing_alg' | 'empty_supported_enc_values' | 'missing_hostname';
|
|
615
619
|
declare class SignedRequestBuildError extends OpenID4VPError {
|
|
616
620
|
readonly code: SignedRequestBuildErrorCode;
|
|
617
621
|
constructor(code: SignedRequestBuildErrorCode, message: string);
|
|
@@ -680,6 +684,6 @@ declare class LotlTrustStore implements TrustStore {
|
|
|
680
684
|
private refresh;
|
|
681
685
|
}
|
|
682
686
|
|
|
683
|
-
declare const VERSION = "0.
|
|
687
|
+
declare const VERSION = "0.10.1";
|
|
684
688
|
|
|
685
689
|
export { type AuthorizationRequest, type AuthorizationRequestInput, type AuthorizationResponse, type Cache, CertificateChainError, type ChainErrorReason, CompositeTrustStore, type CredentialClaims, type CredentialFormat, DecryptionFailedError, type EncryptedResponse, ExpiredCredentialError, type Fetcher, HAIP_DOCTYPE_NAMESPACES, type HaipQueryInput, type HaipValidationCode, HaipValidationError, type ICredentialParser, InMemoryCache, InvalidSignatureError, type IssuerInfo, type LotlAnchorMetadata, LotlFetchError, LotlSignatureError, LotlTrustStore, type LotlTrustStoreOptions, MalformedCredentialError, MdocParser, MissingDecryptionKeyError, MissingVerifierEncryptionKeyError, MultipleCredentialsNotSupportedError, NonceValidationError, OpenID4VPError, type ParseOptions, type PresentationResult, RevocationCheckFailedError, RevokedCertificateError, SdJwtParser, type SignedAuthorizationRequest, type SignedAuthorizationRequestInput, SignedRequestBuildError, type SignedRequestBuildErrorCode, StaticTrustStore, type TrustAnchor, TrustAnchorNotFoundError, type TrustStore, type TrustStoreHint, type TrustStoreInput, UnsupportedFormatError, UnsupportedJweError, VERSION, type VerifyAuthorizationResponseOptions, type VerifyOptions, type VerifyResult, buildHaipQuery, buildOid4vpSessionTranscript, buildOpenID4VPHandoverSessionTranscript, createAuthorizationRequest, createSignedAuthorizationRequest, decryptAuthorizationResponse, isHaipQuery, parsePresentation, validateHaipQuery, verifyAuthorizationResponse, verifyPresentation };
|
package/dist/index.js
CHANGED
|
@@ -8247,14 +8247,23 @@ async function createSignedAuthorizationRequest(input, query) {
|
|
|
8247
8247
|
"vpFormatsSupported is required and must be non-empty"
|
|
8248
8248
|
);
|
|
8249
8249
|
}
|
|
8250
|
+
const clientIdPrefix = input.clientIdPrefix ?? "x509_san_dns";
|
|
8250
8251
|
const leafCert = new X509Certificate(toArrayBuffer(input.certificateChain[0]));
|
|
8251
|
-
|
|
8252
|
-
if (!sanDnsNames.includes(input.hostname)) {
|
|
8252
|
+
if (clientIdPrefix === "x509_san_dns" && !input.hostname) {
|
|
8253
8253
|
throw new SignedRequestBuildError(
|
|
8254
|
-
"
|
|
8255
|
-
|
|
8254
|
+
"missing_hostname",
|
|
8255
|
+
'hostname is required for clientIdPrefix "x509_san_dns"'
|
|
8256
8256
|
);
|
|
8257
8257
|
}
|
|
8258
|
+
if (input.hostname) {
|
|
8259
|
+
const sanDnsNames = extractDnsNames(leafCert);
|
|
8260
|
+
if (!sanDnsNames.includes(input.hostname)) {
|
|
8261
|
+
throw new SignedRequestBuildError(
|
|
8262
|
+
"hostname_cert_mismatch",
|
|
8263
|
+
`leaf cert SAN DNSName values [${sanDnsNames.join(", ")}] do not include hostname "${input.hostname}"`
|
|
8264
|
+
);
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8258
8267
|
const signerPublicSpki = new Uint8Array(
|
|
8259
8268
|
await crypto.subtle.exportKey("spki", input.signer.publicKey)
|
|
8260
8269
|
);
|
|
@@ -8281,7 +8290,7 @@ async function createSignedAuthorizationRequest(input, query) {
|
|
|
8281
8290
|
}
|
|
8282
8291
|
}
|
|
8283
8292
|
const state = input.state ?? v4();
|
|
8284
|
-
const clientId = `x509_san_dns:${input.hostname}`;
|
|
8293
|
+
const clientId = clientIdPrefix === "x509_hash" ? `x509_hash:${await sha256Base64Url(input.certificateChain[0])}` : `x509_san_dns:${input.hostname}`;
|
|
8285
8294
|
const now = Math.floor(Date.now() / 1e3);
|
|
8286
8295
|
const clientMetadata = {
|
|
8287
8296
|
vp_formats_supported: input.vpFormatsSupported
|
|
@@ -8298,8 +8307,6 @@ async function createSignedAuthorizationRequest(input, query) {
|
|
|
8298
8307
|
clientMetadata.jwks = { keys: [jwk] };
|
|
8299
8308
|
const encValues = enc3 ?? [...DEFAULT_SUPPORTED_ENC_VALUES];
|
|
8300
8309
|
clientMetadata.encrypted_response_enc_values_supported = encValues;
|
|
8301
|
-
clientMetadata.authorization_encrypted_response_alg = "ECDH-ES";
|
|
8302
|
-
clientMetadata.authorization_encrypted_response_enc = encValues[0];
|
|
8303
8310
|
}
|
|
8304
8311
|
const payload = {
|
|
8305
8312
|
iss: clientId,
|
|
@@ -8344,6 +8351,10 @@ function bytesEqual(a, b) {
|
|
|
8344
8351
|
}
|
|
8345
8352
|
return true;
|
|
8346
8353
|
}
|
|
8354
|
+
async function sha256Base64Url(derCert) {
|
|
8355
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", toArrayBuffer(derCert)));
|
|
8356
|
+
return bytesToBase64(digest).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
8357
|
+
}
|
|
8347
8358
|
function bytesToBase64(bytes) {
|
|
8348
8359
|
let s = "";
|
|
8349
8360
|
for (let i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);
|
|
@@ -9663,8 +9674,9 @@ async function verifyPresentation(vpToken, query, options) {
|
|
|
9663
9674
|
const parsed = await parsePresentation(vpToken, options);
|
|
9664
9675
|
const dcqlFormat = INTERNAL_TO_DCQL_FORMAT[parsed.format] ?? parsed.format;
|
|
9665
9676
|
const decodedClaims = parsed.format === "mdoc" && parsed.namespacedClaims !== void 0 ? parsed.namespacedClaims : parsed.claims;
|
|
9677
|
+
const presentedCredentialQuery = query.credentials.find((c) => c.format === dcqlFormat) ?? query.credentials[0];
|
|
9666
9678
|
const decoded = {
|
|
9667
|
-
id:
|
|
9679
|
+
id: presentedCredentialQuery?.id ?? "presented",
|
|
9668
9680
|
format: dcqlFormat,
|
|
9669
9681
|
claims: decodedClaims
|
|
9670
9682
|
};
|
|
@@ -9785,8 +9797,12 @@ async function verifyAuthorizationResponse(envelope, query, options) {
|
|
|
9785
9797
|
if (queryIds.length > 1 || presentationCount > 1) {
|
|
9786
9798
|
throw new MultipleCredentialsNotSupportedError(queryIds.length, presentationCount);
|
|
9787
9799
|
}
|
|
9788
|
-
const
|
|
9789
|
-
const
|
|
9800
|
+
const presentedQueryId = queryIds[0];
|
|
9801
|
+
const presentation = vpToken[presentedQueryId][0];
|
|
9802
|
+
const presentedCredentialQuery = query.credentials.find(
|
|
9803
|
+
(c) => c.id === presentedQueryId
|
|
9804
|
+
);
|
|
9805
|
+
const decodedPresentation = presentedCredentialQuery?.format === "mso_mdoc" && typeof presentation === "string" ? base64UrlToBytes(presentation) : presentation;
|
|
9790
9806
|
return verifyPresentation(decodedPresentation, query, options);
|
|
9791
9807
|
}
|
|
9792
9808
|
|
|
@@ -10419,7 +10435,7 @@ function equalBytes(a, b) {
|
|
|
10419
10435
|
|
|
10420
10436
|
// src/index.ts
|
|
10421
10437
|
init_errors();
|
|
10422
|
-
var VERSION = "0.
|
|
10438
|
+
var VERSION = "0.10.1";
|
|
10423
10439
|
/*! Bundled license information:
|
|
10424
10440
|
|
|
10425
10441
|
pvtsutils/build/index.es.js:
|