@sphereon/ssi-types 0.30.1-unstable.4 → 0.30.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/LICENSE +201 -201
- package/README.md +49 -49
- package/dist/events/index.d.ts +1 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/logging/index.d.ts +1 -0
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/logging/index.js +2 -2
- package/dist/logging/index.js.map +1 -1
- package/dist/mapper/jsonld-language-values.d.ts.map +1 -1
- package/dist/types/mso_mdoc.js +5 -5
- package/dist/types/mso_mdoc.js.map +1 -1
- package/dist/types/sd-jwt-vc.js +5 -5
- package/dist/types/sd-jwt-vc.js.map +1 -1
- package/dist/types/w3c-vc.js +3 -3
- package/dist/types/w3c-vc.js.map +1 -1
- package/package.json +4 -4
- package/src/events/index.ts +206 -206
- package/src/index.ts +9 -9
- package/src/logging/index.ts +224 -224
- package/src/mapper/credential-mapper.ts +919 -919
- package/src/mapper/index.ts +2 -2
- package/src/mapper/jsonld-language-values.ts +91 -91
- package/src/types/cose.ts +69 -69
- package/src/types/did.ts +268 -268
- package/src/types/generic.ts +48 -48
- package/src/types/index.ts +9 -9
- package/src/types/jose.ts +115 -115
- package/src/types/mso_mdoc.ts +174 -174
- package/src/types/pex.ts +36 -36
- package/src/types/sd-jwt-vc.ts +369 -369
- package/src/types/vc.ts +87 -87
- package/src/types/w3c-vc.ts +306 -306
- package/src/utils/index.ts +1 -1
- package/src/utils/object.ts +28 -28
package/src/types/jose.ts
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Conversion functions to Cose available for TS in our @sphereon/ssi-sdk-ext.key-utils package
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface BaseJWK {
|
|
6
|
-
kty: JwkKeyType | JwkKeyTypeString
|
|
7
|
-
crv?: JoseCurve | JoseCurveString
|
|
8
|
-
alg?: JoseSignatureAlgorithm | JoseSignatureAlgorithmString
|
|
9
|
-
x?: string
|
|
10
|
-
y?: string
|
|
11
|
-
e?: string
|
|
12
|
-
n?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface JWK extends BaseJWK {
|
|
16
|
-
d?: string
|
|
17
|
-
dp?: string
|
|
18
|
-
dq?: string
|
|
19
|
-
ext?: boolean
|
|
20
|
-
k?: string
|
|
21
|
-
key_ops?: (JoseKeyOperation | JoseKeyOperationString)[]
|
|
22
|
-
kid?: string
|
|
23
|
-
oth?: Array<{
|
|
24
|
-
d?: string
|
|
25
|
-
r?: string
|
|
26
|
-
t?: string
|
|
27
|
-
}>
|
|
28
|
-
p?: string
|
|
29
|
-
q?: string
|
|
30
|
-
qi?: string
|
|
31
|
-
use?: string
|
|
32
|
-
/** JWK "x5c" (X.509 Certificate Chain) Parameter. */
|
|
33
|
-
x5c?: string[]
|
|
34
|
-
/** JWK "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter. */
|
|
35
|
-
x5t?: string
|
|
36
|
-
/** "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Parameter. */
|
|
37
|
-
'x5t#S256'?: string
|
|
38
|
-
/** JWK "x5u" (X.509 URL) Parameter. */
|
|
39
|
-
x5u?: string
|
|
40
|
-
|
|
41
|
-
iv?: string
|
|
42
|
-
|
|
43
|
-
[propName: string]: unknown
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export enum JwkKeyType {
|
|
47
|
-
EC = 'EC',
|
|
48
|
-
RSA = 'RSA',
|
|
49
|
-
oct = 'oct',
|
|
50
|
-
OKP = 'OKP',
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export type JwkKeyTypeString = 'EC' | 'RSA' | 'oct' | 'OKP'
|
|
54
|
-
|
|
55
|
-
export enum JoseSignatureAlgorithm {
|
|
56
|
-
RS256 = 'RS256',
|
|
57
|
-
RS384 = 'RS384',
|
|
58
|
-
RS512 = 'RS512',
|
|
59
|
-
ES256 = 'ES256',
|
|
60
|
-
ES256K = 'ES256K',
|
|
61
|
-
ES384 = 'ES384',
|
|
62
|
-
ES512 = 'ES512',
|
|
63
|
-
EdDSA = 'EdDSA',
|
|
64
|
-
HS256 = 'HS256',
|
|
65
|
-
HS384 = 'HS384',
|
|
66
|
-
HS512 = 'HS512',
|
|
67
|
-
PS256 = 'PS256',
|
|
68
|
-
PS384 = 'PS384',
|
|
69
|
-
PS512 = 'PS512',
|
|
70
|
-
none = 'none',
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export type JoseSignatureAlgorithmString =
|
|
74
|
-
| 'RS256'
|
|
75
|
-
| 'RS384'
|
|
76
|
-
| 'RS512'
|
|
77
|
-
| 'ES256'
|
|
78
|
-
| 'ES256K'
|
|
79
|
-
| 'ES384'
|
|
80
|
-
| 'ES512'
|
|
81
|
-
| 'EdDSA'
|
|
82
|
-
| 'HS256'
|
|
83
|
-
| 'HS384'
|
|
84
|
-
| 'HS512'
|
|
85
|
-
| 'PS256'
|
|
86
|
-
| 'PS384'
|
|
87
|
-
| 'PS512'
|
|
88
|
-
| 'none'
|
|
89
|
-
|
|
90
|
-
export enum JoseKeyOperation {
|
|
91
|
-
SIGN = 'sign',
|
|
92
|
-
VERIFY = 'verify',
|
|
93
|
-
ENCRYPT = 'encrypt',
|
|
94
|
-
DECRYPT = 'decrypt',
|
|
95
|
-
WRAP_KEY = 'wrapKey',
|
|
96
|
-
UNWRAP_KEY = 'unwrapKey',
|
|
97
|
-
DERIVE_KEY = 'deriveKey',
|
|
98
|
-
DERIVE_BITS = 'deriveBits',
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export type JoseKeyOperationString = 'sign' | 'verify' | 'encrypt' | 'decrypt' | 'wrapKey' | 'unwrapKey' | 'deriveKey' | 'deriveBits'
|
|
102
|
-
|
|
103
|
-
export enum JoseCurve {
|
|
104
|
-
P_256 = 'P-256',
|
|
105
|
-
P_384 = 'P-384',
|
|
106
|
-
P_521 = 'P-521',
|
|
107
|
-
X25519 = 'X25519',
|
|
108
|
-
X448 = 'X448',
|
|
109
|
-
EdDSA = 'EdDSA',
|
|
110
|
-
Ed25519 = 'Ed25519',
|
|
111
|
-
Ed448 = 'Ed448',
|
|
112
|
-
secp256k1 = 'secp256k1',
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export type JoseCurveString = 'P-256' | 'P-384' | 'P-521' | 'X25519' | 'X448' | 'EdDSA' | 'Ed25519' | 'Ed448' | 'secp256k1'
|
|
1
|
+
/**
|
|
2
|
+
* Conversion functions to Cose available for TS in our @sphereon/ssi-sdk-ext.key-utils package
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface BaseJWK {
|
|
6
|
+
kty: JwkKeyType | JwkKeyTypeString
|
|
7
|
+
crv?: JoseCurve | JoseCurveString
|
|
8
|
+
alg?: JoseSignatureAlgorithm | JoseSignatureAlgorithmString
|
|
9
|
+
x?: string
|
|
10
|
+
y?: string
|
|
11
|
+
e?: string
|
|
12
|
+
n?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface JWK extends BaseJWK {
|
|
16
|
+
d?: string
|
|
17
|
+
dp?: string
|
|
18
|
+
dq?: string
|
|
19
|
+
ext?: boolean
|
|
20
|
+
k?: string
|
|
21
|
+
key_ops?: (JoseKeyOperation | JoseKeyOperationString)[]
|
|
22
|
+
kid?: string
|
|
23
|
+
oth?: Array<{
|
|
24
|
+
d?: string
|
|
25
|
+
r?: string
|
|
26
|
+
t?: string
|
|
27
|
+
}>
|
|
28
|
+
p?: string
|
|
29
|
+
q?: string
|
|
30
|
+
qi?: string
|
|
31
|
+
use?: string
|
|
32
|
+
/** JWK "x5c" (X.509 Certificate Chain) Parameter. */
|
|
33
|
+
x5c?: string[]
|
|
34
|
+
/** JWK "x5t" (X.509 Certificate SHA-1 Thumbprint) Parameter. */
|
|
35
|
+
x5t?: string
|
|
36
|
+
/** "x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Parameter. */
|
|
37
|
+
'x5t#S256'?: string
|
|
38
|
+
/** JWK "x5u" (X.509 URL) Parameter. */
|
|
39
|
+
x5u?: string
|
|
40
|
+
|
|
41
|
+
iv?: string
|
|
42
|
+
|
|
43
|
+
[propName: string]: unknown
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export enum JwkKeyType {
|
|
47
|
+
EC = 'EC',
|
|
48
|
+
RSA = 'RSA',
|
|
49
|
+
oct = 'oct',
|
|
50
|
+
OKP = 'OKP',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type JwkKeyTypeString = 'EC' | 'RSA' | 'oct' | 'OKP'
|
|
54
|
+
|
|
55
|
+
export enum JoseSignatureAlgorithm {
|
|
56
|
+
RS256 = 'RS256',
|
|
57
|
+
RS384 = 'RS384',
|
|
58
|
+
RS512 = 'RS512',
|
|
59
|
+
ES256 = 'ES256',
|
|
60
|
+
ES256K = 'ES256K',
|
|
61
|
+
ES384 = 'ES384',
|
|
62
|
+
ES512 = 'ES512',
|
|
63
|
+
EdDSA = 'EdDSA',
|
|
64
|
+
HS256 = 'HS256',
|
|
65
|
+
HS384 = 'HS384',
|
|
66
|
+
HS512 = 'HS512',
|
|
67
|
+
PS256 = 'PS256',
|
|
68
|
+
PS384 = 'PS384',
|
|
69
|
+
PS512 = 'PS512',
|
|
70
|
+
none = 'none',
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type JoseSignatureAlgorithmString =
|
|
74
|
+
| 'RS256'
|
|
75
|
+
| 'RS384'
|
|
76
|
+
| 'RS512'
|
|
77
|
+
| 'ES256'
|
|
78
|
+
| 'ES256K'
|
|
79
|
+
| 'ES384'
|
|
80
|
+
| 'ES512'
|
|
81
|
+
| 'EdDSA'
|
|
82
|
+
| 'HS256'
|
|
83
|
+
| 'HS384'
|
|
84
|
+
| 'HS512'
|
|
85
|
+
| 'PS256'
|
|
86
|
+
| 'PS384'
|
|
87
|
+
| 'PS512'
|
|
88
|
+
| 'none'
|
|
89
|
+
|
|
90
|
+
export enum JoseKeyOperation {
|
|
91
|
+
SIGN = 'sign',
|
|
92
|
+
VERIFY = 'verify',
|
|
93
|
+
ENCRYPT = 'encrypt',
|
|
94
|
+
DECRYPT = 'decrypt',
|
|
95
|
+
WRAP_KEY = 'wrapKey',
|
|
96
|
+
UNWRAP_KEY = 'unwrapKey',
|
|
97
|
+
DERIVE_KEY = 'deriveKey',
|
|
98
|
+
DERIVE_BITS = 'deriveBits',
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export type JoseKeyOperationString = 'sign' | 'verify' | 'encrypt' | 'decrypt' | 'wrapKey' | 'unwrapKey' | 'deriveKey' | 'deriveBits'
|
|
102
|
+
|
|
103
|
+
export enum JoseCurve {
|
|
104
|
+
P_256 = 'P-256',
|
|
105
|
+
P_384 = 'P-384',
|
|
106
|
+
P_521 = 'P-521',
|
|
107
|
+
X25519 = 'X25519',
|
|
108
|
+
X448 = 'X448',
|
|
109
|
+
EdDSA = 'EdDSA',
|
|
110
|
+
Ed25519 = 'Ed25519',
|
|
111
|
+
Ed448 = 'Ed448',
|
|
112
|
+
secp256k1 = 'secp256k1',
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type JoseCurveString = 'P-256' | 'P-384' | 'P-521' | 'X25519' | 'X448' | 'EdDSA' | 'Ed25519' | 'Ed448' | 'secp256k1'
|
package/src/types/mso_mdoc.ts
CHANGED
|
@@ -1,174 +1,174 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create some interface below to do a the mapping of the KMP library.
|
|
3
|
-
* For now we are using the library directly, and thus do not need them,
|
|
4
|
-
* but it would be nice if we can remove the imports and just have some interfaces here we can then use, like done
|
|
5
|
-
* for sd-jwts
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { com } from '@sphereon/kmp-mdl-mdoc'
|
|
9
|
-
import { IProofPurpose, IProofType } from './did'
|
|
10
|
-
import { OriginalType, WrappedVerifiableCredential, WrappedVerifiablePresentation } from './vc'
|
|
11
|
-
import { IVerifiableCredential } from './w3c-vc'
|
|
12
|
-
import decodeFrom = com.sphereon.kmp.decodeFrom
|
|
13
|
-
import encodeTo = com.sphereon.kmp.encodeTo
|
|
14
|
-
import Encoding = com.sphereon.kmp.Encoding
|
|
15
|
-
import DeviceResponseCbor = com.sphereon.mdoc.data.device.DeviceResponseCbor
|
|
16
|
-
import DocumentJson = com.sphereon.mdoc.data.device.DocumentJson
|
|
17
|
-
import IssuerSignedCbor = com.sphereon.mdoc.data.device.IssuerSignedCbor
|
|
18
|
-
import IssuerSignedItemJson = com.sphereon.mdoc.data.device.IssuerSignedItemJson
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Represents a selective disclosure JWT vc in compact form.
|
|
22
|
-
*/
|
|
23
|
-
export type MdocOid4vpIssuerSigned = string
|
|
24
|
-
export type MdocOid4vpMdocVpToken = string
|
|
25
|
-
export type MdocIssuerSigned = com.sphereon.mdoc.data.device.IssuerSignedCbor
|
|
26
|
-
export type MdocDocument = com.sphereon.mdoc.data.device.DocumentCbor
|
|
27
|
-
export type MdocDocumentJson = com.sphereon.mdoc.data.device.DocumentJson
|
|
28
|
-
export type MdocDeviceResponse = com.sphereon.mdoc.data.device.DeviceResponseCbor
|
|
29
|
-
|
|
30
|
-
export interface WrappedMdocCredential {
|
|
31
|
-
/**
|
|
32
|
-
* Original IssuerSigned to Mdoc that we've received. Can be either the encoded or decoded variant.
|
|
33
|
-
*/
|
|
34
|
-
original: MdocDocument | MdocOid4vpIssuerSigned
|
|
35
|
-
/**
|
|
36
|
-
* Decoded version of the Mdoc payload. We add the record to make sure existing implementations remain happy
|
|
37
|
-
*/
|
|
38
|
-
decoded: MdocDocument & { [key: string]: any }
|
|
39
|
-
/**
|
|
40
|
-
* Type of this credential.
|
|
41
|
-
*/
|
|
42
|
-
type: OriginalType.MSO_MDOC_DECODED | OriginalType.MSO_MDOC_ENCODED
|
|
43
|
-
/**
|
|
44
|
-
* The claim format, typically used during exchange transport protocols
|
|
45
|
-
*/
|
|
46
|
-
format: 'mso_mdoc'
|
|
47
|
-
/**
|
|
48
|
-
* Internal stable representation of a Credential
|
|
49
|
-
*/
|
|
50
|
-
credential: IVerifiableCredential
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface WrappedMdocPresentation {
|
|
54
|
-
/**
|
|
55
|
-
* Original VP that we've received. Can be either the encoded or decoded variant.
|
|
56
|
-
*/
|
|
57
|
-
original: MdocDeviceResponse | MdocOid4vpMdocVpToken
|
|
58
|
-
/**
|
|
59
|
-
* Decoded version of the SD-JWT payload. This is the decoded payload, rather than the whole SD-JWT.
|
|
60
|
-
*/
|
|
61
|
-
decoded: MdocDeviceResponse
|
|
62
|
-
/**
|
|
63
|
-
* Type of this Presentation.
|
|
64
|
-
*/
|
|
65
|
-
type: OriginalType.MSO_MDOC_ENCODED | OriginalType.MSO_MDOC_DECODED
|
|
66
|
-
/**
|
|
67
|
-
* The claim format, typically used during exchange transport protocols
|
|
68
|
-
*/
|
|
69
|
-
format: 'mso_mdoc'
|
|
70
|
-
/**
|
|
71
|
-
* Internal stable representation of a Presentation
|
|
72
|
-
*/
|
|
73
|
-
presentation: MdocDeviceResponse
|
|
74
|
-
/**
|
|
75
|
-
* Wrapped Mdocs belonging to the Presentation. .
|
|
76
|
-
*/
|
|
77
|
-
vcs: [WrappedMdocCredential]
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function isWrappedMdocCredential(vc: WrappedVerifiableCredential): vc is WrappedMdocCredential {
|
|
81
|
-
return vc.format === 'mso_mdoc'
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function isWrappedMdocPresentation(vp: WrappedVerifiablePresentation): vp is WrappedMdocPresentation {
|
|
85
|
-
return vp.format === 'mso_mdoc'
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Decode an Mdoc from its issuerSigned OID4VP Base64URL (string) to an object containing the disclosures,
|
|
90
|
-
* signed payload, decoded payload
|
|
91
|
-
*
|
|
92
|
-
*/
|
|
93
|
-
export function decodeMdocIssuerSigned(oid4vpIssuerSigned: MdocOid4vpIssuerSigned): MdocDocument {
|
|
94
|
-
// Issuer signed according to 18013-7 in base64url
|
|
95
|
-
const issuerSigned: MdocIssuerSigned = IssuerSignedCbor.Static.cborDecode(decodeFrom(oid4vpIssuerSigned, Encoding.BASE64URL))
|
|
96
|
-
// Create an mdoc from it. // Validations need to be performed by the caller after this!
|
|
97
|
-
const holderMdoc: MdocDocument = issuerSigned.toDocument()
|
|
98
|
-
return holderMdoc
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Decode an Mdoc from its vp_token OID4VP Base64URL (string) to an object containing the disclosures,
|
|
103
|
-
* signed payload, decoded payload
|
|
104
|
-
*
|
|
105
|
-
*/
|
|
106
|
-
export function decodeMdocDeviceResponse(vpToken: MdocOid4vpMdocVpToken): MdocDeviceResponse {
|
|
107
|
-
const deviceResponse = DeviceResponseCbor.Static.cborDecode(decodeFrom(vpToken, Encoding.BASE64URL))
|
|
108
|
-
return deviceResponse
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// TODO naive implementation of mapping a mdoc onto a IVerifiableCredential. Needs some fixes and further implementation and needs to be moved out of ssi-types
|
|
112
|
-
export const mdocDecodedCredentialToUniformCredential = (
|
|
113
|
-
decoded: MdocDocument,
|
|
114
|
-
// @ts-ignore
|
|
115
|
-
opts?: { maxTimeSkewInMS?: number }
|
|
116
|
-
): IVerifiableCredential => {
|
|
117
|
-
const mdoc = decoded.toJson()
|
|
118
|
-
const json = mdoc.toJsonDTO<DocumentJson>()
|
|
119
|
-
const type = 'Personal Identification Data'
|
|
120
|
-
const MSO = mdoc.MSO
|
|
121
|
-
if (!MSO || !json.issuerSigned?.nameSpaces) {
|
|
122
|
-
throw Error(`Cannot access Mobile Security Object or Issuer Signed items from the Mdoc`)
|
|
123
|
-
}
|
|
124
|
-
const nameSpaces = json.issuerSigned.nameSpaces as unknown as Record<string, IssuerSignedItemJson[]>
|
|
125
|
-
if (!('eu.europa.ec.eudi.pid.1' in nameSpaces)) {
|
|
126
|
-
throw Error(`Only PID supported at present`)
|
|
127
|
-
}
|
|
128
|
-
const items = nameSpaces['eu.europa.ec.eudi.pid.1']
|
|
129
|
-
if (!items || items.length === 0) {
|
|
130
|
-
throw Error(`No issuer signed items were found`)
|
|
131
|
-
}
|
|
132
|
-
type DisclosuresAccumulator = {
|
|
133
|
-
[key: string]: any
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const credentialSubject = items.reduce((acc: DisclosuresAccumulator, item: IssuerSignedItemJson) => {
|
|
137
|
-
if (Array.isArray(item.value)) {
|
|
138
|
-
acc[item.key] = item.value.map((val) => val.value).join(', ')
|
|
139
|
-
} else {
|
|
140
|
-
acc[item.key] = item.value.value
|
|
141
|
-
}
|
|
142
|
-
return acc
|
|
143
|
-
}, {})
|
|
144
|
-
const validFrom = MSO.validityInfo.validFrom
|
|
145
|
-
const validUntil = MSO.validityInfo.validUntil
|
|
146
|
-
const docType = MSO.docType
|
|
147
|
-
const expirationDate = validUntil
|
|
148
|
-
let issuanceDateStr = validFrom
|
|
149
|
-
|
|
150
|
-
const issuanceDate = issuanceDateStr
|
|
151
|
-
if (!issuanceDate) {
|
|
152
|
-
throw Error(`JWT issuance date is required but was not present`)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const credential: Omit<IVerifiableCredential, 'issuer' | 'issuanceDate'> = {
|
|
156
|
-
type: [docType], // Mdoc not a W3C VC, so no VerifiableCredential
|
|
157
|
-
'@context': [], // Mdoc has no JSON-LD by default. Certainly not the VC DM1 default context for JSON-LD
|
|
158
|
-
credentialSubject: {
|
|
159
|
-
type,
|
|
160
|
-
...credentialSubject,
|
|
161
|
-
},
|
|
162
|
-
issuanceDate,
|
|
163
|
-
expirationDate,
|
|
164
|
-
proof: {
|
|
165
|
-
type: IProofType.MdocProof2024,
|
|
166
|
-
created: issuanceDate,
|
|
167
|
-
proofPurpose: IProofPurpose.authentication,
|
|
168
|
-
verificationMethod: json.issuerSigned.issuerAuth.payload,
|
|
169
|
-
mso_mdoc: encodeTo(decoded.cborEncode(), Encoding.BASE64URL),
|
|
170
|
-
},
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return credential as IVerifiableCredential
|
|
174
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Create some interface below to do a the mapping of the KMP library.
|
|
3
|
+
* For now we are using the library directly, and thus do not need them,
|
|
4
|
+
* but it would be nice if we can remove the imports and just have some interfaces here we can then use, like done
|
|
5
|
+
* for sd-jwts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { com } from '@sphereon/kmp-mdl-mdoc'
|
|
9
|
+
import { IProofPurpose, IProofType } from './did'
|
|
10
|
+
import { OriginalType, WrappedVerifiableCredential, WrappedVerifiablePresentation } from './vc'
|
|
11
|
+
import { IVerifiableCredential } from './w3c-vc'
|
|
12
|
+
import decodeFrom = com.sphereon.kmp.decodeFrom
|
|
13
|
+
import encodeTo = com.sphereon.kmp.encodeTo
|
|
14
|
+
import Encoding = com.sphereon.kmp.Encoding
|
|
15
|
+
import DeviceResponseCbor = com.sphereon.mdoc.data.device.DeviceResponseCbor
|
|
16
|
+
import DocumentJson = com.sphereon.mdoc.data.device.DocumentJson
|
|
17
|
+
import IssuerSignedCbor = com.sphereon.mdoc.data.device.IssuerSignedCbor
|
|
18
|
+
import IssuerSignedItemJson = com.sphereon.mdoc.data.device.IssuerSignedItemJson
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Represents a selective disclosure JWT vc in compact form.
|
|
22
|
+
*/
|
|
23
|
+
export type MdocOid4vpIssuerSigned = string
|
|
24
|
+
export type MdocOid4vpMdocVpToken = string
|
|
25
|
+
export type MdocIssuerSigned = com.sphereon.mdoc.data.device.IssuerSignedCbor
|
|
26
|
+
export type MdocDocument = com.sphereon.mdoc.data.device.DocumentCbor
|
|
27
|
+
export type MdocDocumentJson = com.sphereon.mdoc.data.device.DocumentJson
|
|
28
|
+
export type MdocDeviceResponse = com.sphereon.mdoc.data.device.DeviceResponseCbor
|
|
29
|
+
|
|
30
|
+
export interface WrappedMdocCredential {
|
|
31
|
+
/**
|
|
32
|
+
* Original IssuerSigned to Mdoc that we've received. Can be either the encoded or decoded variant.
|
|
33
|
+
*/
|
|
34
|
+
original: MdocDocument | MdocOid4vpIssuerSigned
|
|
35
|
+
/**
|
|
36
|
+
* Decoded version of the Mdoc payload. We add the record to make sure existing implementations remain happy
|
|
37
|
+
*/
|
|
38
|
+
decoded: MdocDocument & { [key: string]: any }
|
|
39
|
+
/**
|
|
40
|
+
* Type of this credential.
|
|
41
|
+
*/
|
|
42
|
+
type: OriginalType.MSO_MDOC_DECODED | OriginalType.MSO_MDOC_ENCODED
|
|
43
|
+
/**
|
|
44
|
+
* The claim format, typically used during exchange transport protocols
|
|
45
|
+
*/
|
|
46
|
+
format: 'mso_mdoc'
|
|
47
|
+
/**
|
|
48
|
+
* Internal stable representation of a Credential
|
|
49
|
+
*/
|
|
50
|
+
credential: IVerifiableCredential
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface WrappedMdocPresentation {
|
|
54
|
+
/**
|
|
55
|
+
* Original VP that we've received. Can be either the encoded or decoded variant.
|
|
56
|
+
*/
|
|
57
|
+
original: MdocDeviceResponse | MdocOid4vpMdocVpToken
|
|
58
|
+
/**
|
|
59
|
+
* Decoded version of the SD-JWT payload. This is the decoded payload, rather than the whole SD-JWT.
|
|
60
|
+
*/
|
|
61
|
+
decoded: MdocDeviceResponse
|
|
62
|
+
/**
|
|
63
|
+
* Type of this Presentation.
|
|
64
|
+
*/
|
|
65
|
+
type: OriginalType.MSO_MDOC_ENCODED | OriginalType.MSO_MDOC_DECODED
|
|
66
|
+
/**
|
|
67
|
+
* The claim format, typically used during exchange transport protocols
|
|
68
|
+
*/
|
|
69
|
+
format: 'mso_mdoc'
|
|
70
|
+
/**
|
|
71
|
+
* Internal stable representation of a Presentation
|
|
72
|
+
*/
|
|
73
|
+
presentation: MdocDeviceResponse
|
|
74
|
+
/**
|
|
75
|
+
* Wrapped Mdocs belonging to the Presentation. .
|
|
76
|
+
*/
|
|
77
|
+
vcs: [WrappedMdocCredential]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function isWrappedMdocCredential(vc: WrappedVerifiableCredential): vc is WrappedMdocCredential {
|
|
81
|
+
return vc.format === 'mso_mdoc'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function isWrappedMdocPresentation(vp: WrappedVerifiablePresentation): vp is WrappedMdocPresentation {
|
|
85
|
+
return vp.format === 'mso_mdoc'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Decode an Mdoc from its issuerSigned OID4VP Base64URL (string) to an object containing the disclosures,
|
|
90
|
+
* signed payload, decoded payload
|
|
91
|
+
*
|
|
92
|
+
*/
|
|
93
|
+
export function decodeMdocIssuerSigned(oid4vpIssuerSigned: MdocOid4vpIssuerSigned): MdocDocument {
|
|
94
|
+
// Issuer signed according to 18013-7 in base64url
|
|
95
|
+
const issuerSigned: MdocIssuerSigned = IssuerSignedCbor.Static.cborDecode(decodeFrom(oid4vpIssuerSigned, Encoding.BASE64URL))
|
|
96
|
+
// Create an mdoc from it. // Validations need to be performed by the caller after this!
|
|
97
|
+
const holderMdoc: MdocDocument = issuerSigned.toDocument()
|
|
98
|
+
return holderMdoc
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Decode an Mdoc from its vp_token OID4VP Base64URL (string) to an object containing the disclosures,
|
|
103
|
+
* signed payload, decoded payload
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
export function decodeMdocDeviceResponse(vpToken: MdocOid4vpMdocVpToken): MdocDeviceResponse {
|
|
107
|
+
const deviceResponse = DeviceResponseCbor.Static.cborDecode(decodeFrom(vpToken, Encoding.BASE64URL))
|
|
108
|
+
return deviceResponse
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// TODO naive implementation of mapping a mdoc onto a IVerifiableCredential. Needs some fixes and further implementation and needs to be moved out of ssi-types
|
|
112
|
+
export const mdocDecodedCredentialToUniformCredential = (
|
|
113
|
+
decoded: MdocDocument,
|
|
114
|
+
// @ts-ignore
|
|
115
|
+
opts?: { maxTimeSkewInMS?: number }
|
|
116
|
+
): IVerifiableCredential => {
|
|
117
|
+
const mdoc = decoded.toJson()
|
|
118
|
+
const json = mdoc.toJsonDTO<DocumentJson>()
|
|
119
|
+
const type = 'Personal Identification Data'
|
|
120
|
+
const MSO = mdoc.MSO
|
|
121
|
+
if (!MSO || !json.issuerSigned?.nameSpaces) {
|
|
122
|
+
throw Error(`Cannot access Mobile Security Object or Issuer Signed items from the Mdoc`)
|
|
123
|
+
}
|
|
124
|
+
const nameSpaces = json.issuerSigned.nameSpaces as unknown as Record<string, IssuerSignedItemJson[]>
|
|
125
|
+
if (!('eu.europa.ec.eudi.pid.1' in nameSpaces)) {
|
|
126
|
+
throw Error(`Only PID supported at present`)
|
|
127
|
+
}
|
|
128
|
+
const items = nameSpaces['eu.europa.ec.eudi.pid.1']
|
|
129
|
+
if (!items || items.length === 0) {
|
|
130
|
+
throw Error(`No issuer signed items were found`)
|
|
131
|
+
}
|
|
132
|
+
type DisclosuresAccumulator = {
|
|
133
|
+
[key: string]: any
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const credentialSubject = items.reduce((acc: DisclosuresAccumulator, item: IssuerSignedItemJson) => {
|
|
137
|
+
if (Array.isArray(item.value)) {
|
|
138
|
+
acc[item.key] = item.value.map((val) => val.value).join(', ')
|
|
139
|
+
} else {
|
|
140
|
+
acc[item.key] = item.value.value
|
|
141
|
+
}
|
|
142
|
+
return acc
|
|
143
|
+
}, {})
|
|
144
|
+
const validFrom = MSO.validityInfo.validFrom
|
|
145
|
+
const validUntil = MSO.validityInfo.validUntil
|
|
146
|
+
const docType = MSO.docType
|
|
147
|
+
const expirationDate = validUntil
|
|
148
|
+
let issuanceDateStr = validFrom
|
|
149
|
+
|
|
150
|
+
const issuanceDate = issuanceDateStr
|
|
151
|
+
if (!issuanceDate) {
|
|
152
|
+
throw Error(`JWT issuance date is required but was not present`)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const credential: Omit<IVerifiableCredential, 'issuer' | 'issuanceDate'> = {
|
|
156
|
+
type: [docType], // Mdoc not a W3C VC, so no VerifiableCredential
|
|
157
|
+
'@context': [], // Mdoc has no JSON-LD by default. Certainly not the VC DM1 default context for JSON-LD
|
|
158
|
+
credentialSubject: {
|
|
159
|
+
type,
|
|
160
|
+
...credentialSubject,
|
|
161
|
+
},
|
|
162
|
+
issuanceDate,
|
|
163
|
+
expirationDate,
|
|
164
|
+
proof: {
|
|
165
|
+
type: IProofType.MdocProof2024,
|
|
166
|
+
created: issuanceDate,
|
|
167
|
+
proofPurpose: IProofPurpose.authentication,
|
|
168
|
+
verificationMethod: json.issuerSigned.issuerAuth.payload,
|
|
169
|
+
mso_mdoc: encodeTo(decoded.cborEncode(), Encoding.BASE64URL),
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return credential as IVerifiableCredential
|
|
174
|
+
}
|
package/src/types/pex.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* It expresses how the inputs are presented as proofs to a Verifier.
|
|
3
|
-
*/
|
|
4
|
-
export interface PresentationSubmission {
|
|
5
|
-
/**
|
|
6
|
-
* A UUID or some other unique ID to identify this Presentation Submission
|
|
7
|
-
*/
|
|
8
|
-
id: string
|
|
9
|
-
/**
|
|
10
|
-
* A UUID or some other unique ID to identify this Presentation Definition
|
|
11
|
-
*/
|
|
12
|
-
definition_id: string
|
|
13
|
-
/**
|
|
14
|
-
* List of descriptors of how the claims are being mapped to presentation definition
|
|
15
|
-
*/
|
|
16
|
-
descriptor_map: Array<Descriptor>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* descriptor map laying out the structure of the presentation submission.
|
|
21
|
-
*/
|
|
22
|
-
export interface Descriptor {
|
|
23
|
-
/**
|
|
24
|
-
* ID to identify the descriptor from Presentation Definition Input Descriptor it coresponds to.
|
|
25
|
-
*/
|
|
26
|
-
id: string
|
|
27
|
-
/**
|
|
28
|
-
* The path where the verifiable credential is located in the presentation submission json
|
|
29
|
-
*/
|
|
30
|
-
path: string
|
|
31
|
-
path_nested?: Descriptor
|
|
32
|
-
/**
|
|
33
|
-
* The Proof or JWT algorith that the proof is in
|
|
34
|
-
*/
|
|
35
|
-
format: string
|
|
36
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* It expresses how the inputs are presented as proofs to a Verifier.
|
|
3
|
+
*/
|
|
4
|
+
export interface PresentationSubmission {
|
|
5
|
+
/**
|
|
6
|
+
* A UUID or some other unique ID to identify this Presentation Submission
|
|
7
|
+
*/
|
|
8
|
+
id: string
|
|
9
|
+
/**
|
|
10
|
+
* A UUID or some other unique ID to identify this Presentation Definition
|
|
11
|
+
*/
|
|
12
|
+
definition_id: string
|
|
13
|
+
/**
|
|
14
|
+
* List of descriptors of how the claims are being mapped to presentation definition
|
|
15
|
+
*/
|
|
16
|
+
descriptor_map: Array<Descriptor>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* descriptor map laying out the structure of the presentation submission.
|
|
21
|
+
*/
|
|
22
|
+
export interface Descriptor {
|
|
23
|
+
/**
|
|
24
|
+
* ID to identify the descriptor from Presentation Definition Input Descriptor it coresponds to.
|
|
25
|
+
*/
|
|
26
|
+
id: string
|
|
27
|
+
/**
|
|
28
|
+
* The path where the verifiable credential is located in the presentation submission json
|
|
29
|
+
*/
|
|
30
|
+
path: string
|
|
31
|
+
path_nested?: Descriptor
|
|
32
|
+
/**
|
|
33
|
+
* The Proof or JWT algorith that the proof is in
|
|
34
|
+
*/
|
|
35
|
+
format: string
|
|
36
|
+
}
|