@europeum-ebsi/cli 0.0.0
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.txt +289 -0
- package/README.md +98 -0
- package/bin/cli.js +13 -0
- package/dist/abi/pilot/DidRegistry.js +568 -0
- package/dist/abi/pilot/DidRegistry.js.map +1 -0
- package/dist/abi/pilot/Ptr.js +666 -0
- package/dist/abi/pilot/Ptr.js.map +1 -0
- package/dist/abi/pilot/SchemaSCRegistry.js +264 -0
- package/dist/abi/pilot/SchemaSCRegistry.js.map +1 -0
- package/dist/abi/pilot/Tcr.js +715 -0
- package/dist/abi/pilot/Tcr.js.map +1 -0
- package/dist/abi/pilot/Timestamp.js +658 -0
- package/dist/abi/pilot/Timestamp.js.map +1 -0
- package/dist/abi/pilot/Tir.js +428 -0
- package/dist/abi/pilot/Tir.js.map +1 -0
- package/dist/abi/pilot/TnT.js +842 -0
- package/dist/abi/pilot/TnT.js.map +1 -0
- package/dist/abi/pilot/Tpr.js +492 -0
- package/dist/abi/pilot/Tpr.js.map +1 -0
- package/dist/abi/test/DidRegistry.js +568 -0
- package/dist/abi/test/DidRegistry.js.map +1 -0
- package/dist/abi/test/Ptr.js +666 -0
- package/dist/abi/test/Ptr.js.map +1 -0
- package/dist/abi/test/SchemaSCRegistry.js +300 -0
- package/dist/abi/test/SchemaSCRegistry.js.map +1 -0
- package/dist/abi/test/Tcr.js +715 -0
- package/dist/abi/test/Tcr.js.map +1 -0
- package/dist/abi/test/Timestamp.js +658 -0
- package/dist/abi/test/Timestamp.js.map +1 -0
- package/dist/abi/test/Tir.js +428 -0
- package/dist/abi/test/Tir.js.map +1 -0
- package/dist/abi/test/TnT.js +842 -0
- package/dist/abi/test/TnT.js.map +1 -0
- package/dist/abi/test/Tpr.js +492 -0
- package/dist/abi/test/Tpr.js.map +1 -0
- package/dist/app.js +659 -0
- package/dist/app.js.map +1 -0
- package/dist/buildParam/didr.js +374 -0
- package/dist/buildParam/didr.js.map +1 -0
- package/dist/buildParam/index.js +53 -0
- package/dist/buildParam/index.js.map +1 -0
- package/dist/buildParam/ptr.js +80 -0
- package/dist/buildParam/ptr.js.map +1 -0
- package/dist/buildParam/tcr.js +36 -0
- package/dist/buildParam/tcr.js.map +1 -0
- package/dist/buildParam/timestamp.js +350 -0
- package/dist/buildParam/timestamp.js.map +1 -0
- package/dist/buildParam/tir.js +110 -0
- package/dist/buildParam/tir.js.map +1 -0
- package/dist/buildParam/tnt.js +214 -0
- package/dist/buildParam/tnt.js.map +1 -0
- package/dist/buildParam/tpr.js +91 -0
- package/dist/buildParam/tpr.js.map +1 -0
- package/dist/buildParam/tsr.js +115 -0
- package/dist/buildParam/tsr.js.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/authorisation.js +144 -0
- package/dist/commands/authorisation.js.map +1 -0
- package/dist/commands/compute.js +680 -0
- package/dist/commands/compute.js.map +1 -0
- package/dist/commands/conformance.js +813 -0
- package/dist/commands/conformance.js.map +1 -0
- package/dist/commands/hardwarewallet.js +41 -0
- package/dist/commands/hardwarewallet.js.map +1 -0
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/ledger.js +397 -0
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/ptr.js +54 -0
- package/dist/commands/ptr.js.map +1 -0
- package/dist/commands/tcr.js +50 -0
- package/dist/commands/tcr.js.map +1 -0
- package/dist/commands/tir.js +64 -0
- package/dist/commands/tir.js.map +1 -0
- package/dist/commands/tnl.js +81 -0
- package/dist/commands/tnl.js.map +1 -0
- package/dist/commands/tsr.js +45 -0
- package/dist/commands/tsr.js.map +1 -0
- package/dist/commands/view.js +53 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/config.js +497 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/context.js +2 -0
- package/dist/interfaces/context.js.map +1 -0
- package/dist/interfaces/contracts/ProxyFactory.js +2 -0
- package/dist/interfaces/contracts/ProxyFactory.js.map +1 -0
- package/dist/interfaces/contracts/ProxyTemplateRegistry.js +2 -0
- package/dist/interfaces/contracts/ProxyTemplateRegistry.js.map +1 -0
- package/dist/interfaces/contracts/SchemaSCRegistry.js +2 -0
- package/dist/interfaces/contracts/SchemaSCRegistry.js.map +1 -0
- package/dist/interfaces/contracts/common.js +2 -0
- package/dist/interfaces/contracts/common.js.map +1 -0
- package/dist/interfaces/index.js +5 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/jsonrpc.interface.js +2 -0
- package/dist/interfaces/jsonrpc.interface.js.map +1 -0
- package/dist/interfaces/paginated-list.interface.js +2 -0
- package/dist/interfaces/paginated-list.interface.js.map +1 -0
- package/dist/interfaces/unsigned-transaction.interface.js +2 -0
- package/dist/interfaces/unsigned-transaction.interface.js.map +1 -0
- package/dist/interfaces/utils.interface.js +2 -0
- package/dist/interfaces/utils.interface.js.map +1 -0
- package/dist/programs/migrateDid.js +159 -0
- package/dist/programs/migrateDid.js.map +1 -0
- package/dist/programs/migrateDids.js +232 -0
- package/dist/programs/migrateDids.js.map +1 -0
- package/dist/programs/migrateTsr.js +201 -0
- package/dist/programs/migrateTsr.js.map +1 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step1 +34 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step2 +18 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step3 +9 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step4 +27 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step5 +13 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step6 +14 -0
- package/dist/scripts/accreditAndAuthorize/conformance/step7 +7 -0
- package/dist/scripts/accreditAndAuthorize/test/step1 +34 -0
- package/dist/scripts/accreditAndAuthorize/test/step2 +18 -0
- package/dist/scripts/accreditAndAuthorize/test/step3 +9 -0
- package/dist/scripts/accreditAndAuthorize/test/step4 +27 -0
- package/dist/scripts/accreditAndAuthorize/test/step5 +13 -0
- package/dist/scripts/accreditAndAuthorize/test/step6 +14 -0
- package/dist/scripts/accreditAndAuthorize/test/step7 +7 -0
- package/dist/scripts/accreditTI +21 -0
- package/dist/scripts/assets/Nodes.json +27 -0
- package/dist/scripts/assets/vcdm1.1/CTRevocableCredential.json +30 -0
- package/dist/scripts/assets/vcdm1.1/CredentialToAttestVerifiableAuthorisationForTrustChain.json +29 -0
- package/dist/scripts/assets/vcdm1.1/Nodes.json +27 -0
- package/dist/scripts/assets/vcdm1.1/TrustedNodesList.json +35 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAccredit.json +35 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAttest.json +33 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationForTrustChain.json +22 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToInvoke.json +24 -0
- package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToOnboard.json +24 -0
- package/dist/scripts/assets/vcdm2.0/CredentialToAttestVerifiableAuthorisationForTrustChain.json +29 -0
- package/dist/scripts/assets/vcdm2.0/TrustedNodesList.json +36 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAccredit.json +40 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAttest.json +38 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationForTrustChain.json +30 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToInvoke.json +24 -0
- package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToOnboard.json +23 -0
- package/dist/scripts/bootstrap/0a-loadTPROperator +5 -0
- package/dist/scripts/bootstrap/0b-loadAdmin +8 -0
- package/dist/scripts/bootstrap/1-populateTPR +92 -0
- package/dist/scripts/bootstrap/2-populateDID +6 -0
- package/dist/scripts/bootstrap/3-populateTimestamp +9 -0
- package/dist/scripts/bootstrap/4-populateTIR +8 -0
- package/dist/scripts/bootstrap/5-populateTSR +85 -0
- package/dist/scripts/bootstrap/6-setupConformanceIssuer +35 -0
- package/dist/scripts/bootstrap/README.md +218 -0
- package/dist/scripts/issueVcInvoke +10 -0
- package/dist/scripts/issueVcOnboard +9 -0
- package/dist/scripts/issueVcRootTAO +11 -0
- package/dist/scripts/issueVcTAO +12 -0
- package/dist/scripts/issueVcTI +12 -0
- package/dist/scripts/issueVcTnl +32 -0
- package/dist/scripts/issue_CTRevocableCredential +12 -0
- package/dist/scripts/issue_SelfAttestationSupportOffice +10 -0
- package/dist/scripts/issue_VerifiableAccreditationToAccredit +11 -0
- package/dist/scripts/issue_VerifiableAccreditationToAttest +11 -0
- package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +10 -0
- package/dist/scripts/issue_VerifiableAuthorisationToOnboard +9 -0
- package/dist/scripts/preregisterIssuer +6 -0
- package/dist/scripts/registerDidDocument +15 -0
- package/dist/scripts/registerIssuer +6 -0
- package/dist/scripts/updateVcRootTAO +10 -0
- package/dist/scripts/updateVcTAO +11 -0
- package/dist/scripts/updateVcTI +11 -0
- package/dist/scripts/vcdm2.0/issueSelfAttestationSupportOffice +10 -0
- package/dist/scripts/vcdm2.0/issueVcInvoke +12 -0
- package/dist/scripts/vcdm2.0/issueVcOnboard +11 -0
- package/dist/scripts/vcdm2.0/issueVcRootTAO +14 -0
- package/dist/scripts/vcdm2.0/issueVcTAO +15 -0
- package/dist/scripts/vcdm2.0/issueVcTI +15 -0
- package/dist/scripts/vcdm2.0/issueVcTnl +34 -0
- package/dist/scripts/vcdm2.0/registerDidDocument +15 -0
- package/dist/scripts/vcdm2.0/updateVcRootTAO +13 -0
- package/dist/scripts/vcdm2.0/updateVcTAO +14 -0
- package/dist/scripts/vcdm2.0/updateVcTI +14 -0
- package/dist/scripts/vcdm2.0/verifyVcTnl +10 -0
- package/dist/scripts/verifyVcTnl +10 -0
- package/dist/scripts/wct/accreditAndAuthorize +133 -0
- package/dist/scripts/wct/accreditAndAuthorize2 +89 -0
- package/dist/scripts/wct/holderWallet +39 -0
- package/dist/scripts/wct/holderWallet2 +39 -0
- package/dist/scripts/wct/issueToHolder +38 -0
- package/dist/scripts/wct/issueToHolder2 +38 -0
- package/dist/scripts/wct/pda1 +3 -0
- package/dist/scripts/wct/verifier +8 -0
- package/dist/scripts/wct/verifier2 +7 -0
- package/dist/utils/Client.js +155 -0
- package/dist/utils/Client.js.map +1 -0
- package/dist/utils/HardwareWallet.js +326 -0
- package/dist/utils/HardwareWallet.js.map +1 -0
- package/dist/utils/http.js +132 -0
- package/dist/utils/http.js.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/jsonrpc.js +38 -0
- package/dist/utils/jsonrpc.js.map +1 -0
- package/dist/utils/print.js +56 -0
- package/dist/utils/print.js.map +1 -0
- package/dist/utils/utils.js +427 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/vcdm.js +47 -0
- package/dist/utils/vcdm.js.map +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
using user null
|
|
2
|
+
using user ES256 did2
|
|
3
|
+
|
|
4
|
+
c0: conformance holder CTWalletCrossAuthorisedInTime authorisedInTime ES256 1.1
|
|
5
|
+
conformance check ct_wallet_cross_authorised_in_time
|
|
6
|
+
|
|
7
|
+
c1: conformance holder CTWalletCrossAuthorisedDeferred authorisedDeferred ES256 1.1
|
|
8
|
+
conformance check ct_wallet_cross_authorised_deferred
|
|
9
|
+
|
|
10
|
+
c2: conformance holder CTWalletCrossPreAuthorisedInTime preAuthorisedInTime ES256 1.1
|
|
11
|
+
conformance check ct_wallet_cross_pre_authorised_in_time
|
|
12
|
+
|
|
13
|
+
c3: conformance holder CTWalletCrossPreAuthorisedDeferred preAuthorisedDeferred ES256 1.1
|
|
14
|
+
conformance check ct_wallet_cross_pre_authorised_deferred
|
|
15
|
+
|
|
16
|
+
c4: conformance holder CTWalletSameAuthorisedInTime authorisedInTime ES256 1.1
|
|
17
|
+
conformance check ct_wallet_same_authorised_in_time
|
|
18
|
+
|
|
19
|
+
c5: conformance holder CTWalletSameAuthorisedDeferred authorisedDeferred ES256 1.1
|
|
20
|
+
conformance check ct_wallet_same_authorised_deferred
|
|
21
|
+
|
|
22
|
+
c6: conformance holder CTWalletSamePreAuthorisedInTime preAuthorisedInTime ES256 1.1
|
|
23
|
+
conformance check ct_wallet_same_pre_authorised_in_time
|
|
24
|
+
|
|
25
|
+
c7: conformance holder CTWalletSamePreAuthorisedDeferred preAuthorisedDeferred ES256 1.1
|
|
26
|
+
conformance check ct_wallet_same_pre_authorised_deferred
|
|
27
|
+
|
|
28
|
+
set credentials []
|
|
29
|
+
set credentials.0 c0
|
|
30
|
+
set credentials.1 c1
|
|
31
|
+
set credentials.2 c2
|
|
32
|
+
set credentials.3 c3
|
|
33
|
+
set credentials.4 c4
|
|
34
|
+
set credentials.5 c5
|
|
35
|
+
set credentials.6 c6
|
|
36
|
+
set credentials.7 c7
|
|
37
|
+
|
|
38
|
+
conformance holder CTWalletQualificationCredential authorisedInTime ES256 1.1 credentials
|
|
39
|
+
conformance check request_ct_wallet_qualification_credential
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
using user null
|
|
2
|
+
using user ES256 did2
|
|
3
|
+
|
|
4
|
+
c0: conformance holder CTWalletCrossAuthorisedInTime authorisedInTime ES256 2.0
|
|
5
|
+
conformance check ct_wallet_cross_authorised_in_time 2.0
|
|
6
|
+
|
|
7
|
+
c1: conformance holder CTWalletCrossAuthorisedDeferred authorisedDeferred ES256 2.0
|
|
8
|
+
conformance check ct_wallet_cross_authorised_deferred 2.0
|
|
9
|
+
|
|
10
|
+
c2: conformance holder CTWalletCrossPreAuthorisedInTime preAuthorisedInTime ES256 2.0
|
|
11
|
+
conformance check ct_wallet_cross_pre_authorised_in_time 2.0
|
|
12
|
+
|
|
13
|
+
c3: conformance holder CTWalletCrossPreAuthorisedDeferred preAuthorisedDeferred ES256 2.0
|
|
14
|
+
conformance check ct_wallet_cross_pre_authorised_deferred 2.0
|
|
15
|
+
|
|
16
|
+
c4: conformance holder CTWalletSameAuthorisedInTime authorisedInTime ES256 2.0
|
|
17
|
+
conformance check ct_wallet_same_authorised_in_time 2.0
|
|
18
|
+
|
|
19
|
+
c5: conformance holder CTWalletSameAuthorisedDeferred authorisedDeferred ES256 2.0
|
|
20
|
+
conformance check ct_wallet_same_authorised_deferred 2.0
|
|
21
|
+
|
|
22
|
+
c6: conformance holder CTWalletSamePreAuthorisedInTime preAuthorisedInTime ES256 2.0
|
|
23
|
+
conformance check ct_wallet_same_pre_authorised_in_time 2.0
|
|
24
|
+
|
|
25
|
+
c7: conformance holder CTWalletSamePreAuthorisedDeferred preAuthorisedDeferred ES256 2.0
|
|
26
|
+
conformance check ct_wallet_same_pre_authorised_deferred 2.0
|
|
27
|
+
|
|
28
|
+
set credentials []
|
|
29
|
+
set credentials.0 c0
|
|
30
|
+
set credentials.1 c1
|
|
31
|
+
set credentials.2 c2
|
|
32
|
+
set credentials.3 c3
|
|
33
|
+
set credentials.4 c4
|
|
34
|
+
set credentials.5 c5
|
|
35
|
+
set credentials.6 c6
|
|
36
|
+
set credentials.7 c7
|
|
37
|
+
|
|
38
|
+
conformance holder CTWalletQualificationCredential authorisedInTime ES256 2.0 credentials
|
|
39
|
+
conformance check request_ct_wallet_qualification_credential
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
using user null
|
|
2
|
+
using user ES256 did2
|
|
3
|
+
set user.issuerState issuer-state
|
|
4
|
+
conformance clientMockInitiate
|
|
5
|
+
|
|
6
|
+
jwks: conformance get /issuer-mock/jwks
|
|
7
|
+
issuerMockDidNP: compute did2 jwks.keys.0
|
|
8
|
+
|
|
9
|
+
set preAuthInTimePayload {"authorization_details":[{"type":"openid_credential","format":"jwt_vc","types":["VerifiableCredential","VerifiableAttestation","CTWalletSamePreAuthorisedInTime"],"locations":[""]}]}
|
|
10
|
+
set preAuthInTimePayload.iss user.clientId
|
|
11
|
+
set preAuthInTimePayload.sub issuerMockDidNP
|
|
12
|
+
set preAuthInTimePayload.client_id issuerMockDidNP
|
|
13
|
+
set preAuthInTimePayload.authorization_details[0].locations[0] user.clientId
|
|
14
|
+
set preAuthHeaders {}
|
|
15
|
+
set preAuthHeaders.kid user.keys.ES256.kid
|
|
16
|
+
preAuthorizedInTimeCode: compute signJwt preAuthInTimePayload ES256 preAuthHeaders
|
|
17
|
+
|
|
18
|
+
set preAuthDeferredPayload {"authorization_details":[{"type":"openid_credential","format":"jwt_vc","types":["VerifiableCredential","VerifiableAttestation","CTWalletSamePreAuthorisedDeferred"],"locations":[""]}]}
|
|
19
|
+
set preAuthDeferredPayload.iss user.clientId
|
|
20
|
+
set preAuthDeferredPayload.sub issuerMockDidNP
|
|
21
|
+
set preAuthDeferredPayload.client_id issuerMockDidNP
|
|
22
|
+
set preAuthDeferredPayload.authorization_details[0].locations[0] user.clientId
|
|
23
|
+
preAuthorizedDeferredCode: compute signJwt preAuthDeferredPayload ES256 preAuthHeaders
|
|
24
|
+
|
|
25
|
+
userPin: compute userPin issuerMockDidNP
|
|
26
|
+
|
|
27
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_authorised_in_time 1.1
|
|
28
|
+
conformance check issue_to_holder_validate_ct_wallet_same_authorised_in_time 1.1
|
|
29
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_authorised_deferred 1.1
|
|
30
|
+
conformance check issue_to_holder_validate_ct_wallet_same_authorised_deferred 1.1
|
|
31
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_pre_authorised_in_time 1.1 preAuthorizedInTimeCode userPin
|
|
32
|
+
conformance check issue_to_holder_validate_ct_wallet_same_pre_authorised_in_time 1.1 preAuthorizedInTimeCode userPin
|
|
33
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_pre_authorised_deferred 1.1 preAuthorizedDeferredCode userPin
|
|
34
|
+
conformance check issue_to_holder_validate_ct_wallet_same_pre_authorised_deferred 1.1 preAuthorizedDeferredCode userPin
|
|
35
|
+
|
|
36
|
+
compute wait 11
|
|
37
|
+
conformance holder CTIssueQualificationCredential authorisedInTime ES256 1.1 [] skip-credential-offer
|
|
38
|
+
conformance check request_ct_issue_to_holder_qualification_credential
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
using user null
|
|
2
|
+
using user ES256 did2
|
|
3
|
+
set user.issuerState issuer-state
|
|
4
|
+
conformance clientMockInitiate
|
|
5
|
+
|
|
6
|
+
jwks: conformance get /issuer-mock/jwks
|
|
7
|
+
issuerMockDidNP: compute did2 jwks.keys.0
|
|
8
|
+
|
|
9
|
+
set preAuthInTimePayload {"authorization_details":[{"type":"openid_credential","format":"jwt_vc","types":["VerifiableCredential","VerifiableAttestation","CTWalletSamePreAuthorisedInTime"],"locations":[""]}]}
|
|
10
|
+
set preAuthInTimePayload.iss user.clientId
|
|
11
|
+
set preAuthInTimePayload.sub issuerMockDidNP
|
|
12
|
+
set preAuthInTimePayload.client_id issuerMockDidNP
|
|
13
|
+
set preAuthInTimePayload.authorization_details[0].locations[0] user.clientId
|
|
14
|
+
set preAuthHeaders {}
|
|
15
|
+
set preAuthHeaders.kid user.keys.ES256.kid
|
|
16
|
+
preAuthorizedInTimeCode: compute signJwt preAuthInTimePayload ES256 preAuthHeaders
|
|
17
|
+
|
|
18
|
+
set preAuthDeferredPayload {"authorization_details":[{"type":"openid_credential","format":"jwt_vc","types":["VerifiableCredential","VerifiableAttestation","CTWalletSamePreAuthorisedDeferred"],"locations":[""]}]}
|
|
19
|
+
set preAuthDeferredPayload.iss user.clientId
|
|
20
|
+
set preAuthDeferredPayload.sub issuerMockDidNP
|
|
21
|
+
set preAuthDeferredPayload.client_id issuerMockDidNP
|
|
22
|
+
set preAuthDeferredPayload.authorization_details[0].locations[0] user.clientId
|
|
23
|
+
preAuthorizedDeferredCode: compute signJwt preAuthDeferredPayload ES256 preAuthHeaders
|
|
24
|
+
|
|
25
|
+
userPin: compute userPin issuerMockDidNP
|
|
26
|
+
|
|
27
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_authorised_in_time 2.0
|
|
28
|
+
conformance check issue_to_holder_validate_ct_wallet_same_authorised_in_time 2.0
|
|
29
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_authorised_deferred 2.0
|
|
30
|
+
conformance check issue_to_holder_validate_ct_wallet_same_authorised_deferred 2.0
|
|
31
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_pre_authorised_in_time 2.0 preAuthorizedInTimeCode userPin
|
|
32
|
+
conformance check issue_to_holder_validate_ct_wallet_same_pre_authorised_in_time 2.0 preAuthorizedInTimeCode userPin
|
|
33
|
+
conformance check issue_to_holder_initiate_ct_wallet_same_pre_authorised_deferred 2.0 preAuthorizedDeferredCode userPin
|
|
34
|
+
conformance check issue_to_holder_validate_ct_wallet_same_pre_authorised_deferred 2.0 preAuthorizedDeferredCode userPin
|
|
35
|
+
|
|
36
|
+
compute wait 11
|
|
37
|
+
conformance holder CTIssueQualificationCredential authorisedInTime ES256 2.0 [] skip-credential-offer
|
|
38
|
+
conformance check request_ct_issue_to_holder_qualification_credential
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
using user null
|
|
2
|
+
using user ES256
|
|
3
|
+
conformance clientMockInitiate
|
|
4
|
+
conformance check verifier_id_token_exchange
|
|
5
|
+
conformance check verifier_vp_valid_vc
|
|
6
|
+
conformance check verifier_vp_expired_vc
|
|
7
|
+
conformance check verifier_vp_revoked_vc
|
|
8
|
+
conformance check verifier_vp_not_yet_valid_vc
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createJWT, ES256KSigner } from "@europeum-ebsi/did-jwt";
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
import { exportJWK, generateKeyPair, importJWK, SignJWT } from "jose";
|
|
4
|
+
import { HardwareWallet } from "./HardwareWallet.js";
|
|
5
|
+
import { encodePrivateKey, encodePublicKey, removePrefix0x } from "./utils.js";
|
|
6
|
+
export class Client {
|
|
7
|
+
accreditationId;
|
|
8
|
+
accreditationUrl;
|
|
9
|
+
clientId;
|
|
10
|
+
did;
|
|
11
|
+
didVersion;
|
|
12
|
+
ethWallet;
|
|
13
|
+
hardwareWallet;
|
|
14
|
+
issuerState;
|
|
15
|
+
keys;
|
|
16
|
+
proxyId;
|
|
17
|
+
supportOfficeAccreditationUrl;
|
|
18
|
+
constructor() {
|
|
19
|
+
this.keys = {};
|
|
20
|
+
}
|
|
21
|
+
async createRandom(alg) {
|
|
22
|
+
const { privateKeyJwk } = await generateKeys(alg);
|
|
23
|
+
this.setJwk(alg, privateKeyJwk);
|
|
24
|
+
}
|
|
25
|
+
generateDidDocument() {
|
|
26
|
+
const context = [
|
|
27
|
+
"https://www.w3.org/ns/did/v1",
|
|
28
|
+
"https://w3id.org/security/suites/jws-2020/v1",
|
|
29
|
+
];
|
|
30
|
+
const didDocument = {
|
|
31
|
+
"@context": context,
|
|
32
|
+
assertionMethod: [],
|
|
33
|
+
authentication: [],
|
|
34
|
+
capabilityInvocation: [],
|
|
35
|
+
id: this.did,
|
|
36
|
+
verificationMethod: [],
|
|
37
|
+
};
|
|
38
|
+
for (const alg of Object.keys(this.keys)) {
|
|
39
|
+
const key = this.keys[alg];
|
|
40
|
+
if (!key)
|
|
41
|
+
continue;
|
|
42
|
+
didDocument.verificationMethod.push({
|
|
43
|
+
controller: this.did,
|
|
44
|
+
id: key.kid,
|
|
45
|
+
publicKeyJwk: key.publicKeyJwk,
|
|
46
|
+
type: "JsonWebKey2020",
|
|
47
|
+
});
|
|
48
|
+
didDocument.authentication.push(key.kid);
|
|
49
|
+
didDocument.assertionMethod.push(key.kid);
|
|
50
|
+
didDocument.capabilityInvocation.push(key.kid);
|
|
51
|
+
}
|
|
52
|
+
return didDocument;
|
|
53
|
+
}
|
|
54
|
+
privateKeysBase64() {
|
|
55
|
+
const keys = [];
|
|
56
|
+
for (const alg of Object.keys(this.keys)) {
|
|
57
|
+
const key = this.keys[alg];
|
|
58
|
+
if (!key)
|
|
59
|
+
continue;
|
|
60
|
+
keys.push({
|
|
61
|
+
alg,
|
|
62
|
+
id: key.kid,
|
|
63
|
+
privateKeyJwk: key.privateKeyJwk,
|
|
64
|
+
publicKeyJwk: key.publicKeyJwk,
|
|
65
|
+
type: "JsonWebKey2020",
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return Buffer.from(JSON.stringify(keys)).toString("base64");
|
|
69
|
+
}
|
|
70
|
+
setJwk(alg, privateKeyJwk) {
|
|
71
|
+
const publicKeyJwk = encodePublicKey({
|
|
72
|
+
format: "jwk",
|
|
73
|
+
key: privateKeyJwk,
|
|
74
|
+
});
|
|
75
|
+
const publicKeyPem = encodePublicKey({
|
|
76
|
+
alg,
|
|
77
|
+
format: "pem",
|
|
78
|
+
key: publicKeyJwk,
|
|
79
|
+
sourceType: "publicJwk",
|
|
80
|
+
});
|
|
81
|
+
let publicKeyHex = "";
|
|
82
|
+
let privateKeyHex = "";
|
|
83
|
+
if (["ES256", "ES256K"].includes(alg)) {
|
|
84
|
+
privateKeyHex = encodePrivateKey({
|
|
85
|
+
alg,
|
|
86
|
+
format: "hex",
|
|
87
|
+
key: privateKeyJwk,
|
|
88
|
+
});
|
|
89
|
+
publicKeyHex = encodePublicKey({
|
|
90
|
+
alg,
|
|
91
|
+
format: "hex",
|
|
92
|
+
key: publicKeyJwk,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
this.keys[alg] = {
|
|
96
|
+
id: "",
|
|
97
|
+
isHardwareWallet: false,
|
|
98
|
+
kid: "",
|
|
99
|
+
...(privateKeyHex && { privateKeyHex }),
|
|
100
|
+
privateKeyJwk,
|
|
101
|
+
...(publicKeyHex && { publicKeyHex }),
|
|
102
|
+
publicKeyJwk,
|
|
103
|
+
publicKeyPem,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async signJWT(payload, inputHeader, alg) {
|
|
107
|
+
if (!this.keys[alg])
|
|
108
|
+
throw new Error(`There is no key defined for alg ${alg}`);
|
|
109
|
+
const header = {
|
|
110
|
+
alg,
|
|
111
|
+
kid: this.keys[alg].kid,
|
|
112
|
+
...(this.didVersion === 2 && {
|
|
113
|
+
jwk: this.keys[alg].publicKeyJwk,
|
|
114
|
+
}),
|
|
115
|
+
...inputHeader,
|
|
116
|
+
};
|
|
117
|
+
if (this.keys[alg].isHardwareWallet) {
|
|
118
|
+
const jwt = await this.hardwareWallet.signJWT(payload, header);
|
|
119
|
+
return jwt;
|
|
120
|
+
}
|
|
121
|
+
if (alg === "ES256K") {
|
|
122
|
+
// ES256K is not supported by jose library
|
|
123
|
+
const signer = ES256KSigner(Buffer.from(removePrefix0x(this.keys.ES256K.privateKeyHex), "hex"));
|
|
124
|
+
const jwt = createJWT(payload, { signer }, header);
|
|
125
|
+
return jwt;
|
|
126
|
+
}
|
|
127
|
+
const privateKey = await importJWK(this.keys[alg].privateKeyJwk, alg);
|
|
128
|
+
const jwt = await new SignJWT(payload)
|
|
129
|
+
.setProtectedHeader(header)
|
|
130
|
+
.sign(privateKey);
|
|
131
|
+
return jwt;
|
|
132
|
+
}
|
|
133
|
+
toJSON() {
|
|
134
|
+
return {
|
|
135
|
+
accreditationId: this.accreditationId,
|
|
136
|
+
accreditationUrl: this.accreditationUrl,
|
|
137
|
+
address: this.ethWallet?.address ?? "",
|
|
138
|
+
clientId: this.clientId,
|
|
139
|
+
did: this.did,
|
|
140
|
+
didVersion: this.didVersion,
|
|
141
|
+
issuerState: this.issuerState,
|
|
142
|
+
keys: this.keys,
|
|
143
|
+
proxyId: this.proxyId,
|
|
144
|
+
supportOfficeAccreditationUrl: this.supportOfficeAccreditationUrl,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export async function generateKeys(alg) {
|
|
149
|
+
const keys = await generateKeyPair(alg, { extractable: true });
|
|
150
|
+
return {
|
|
151
|
+
privateKeyJwk: await exportJWK(keys.privateKey),
|
|
152
|
+
publicKeyJwk: await exportJWK(keys.publicKey),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=Client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../../src/utils/Client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import * as asn1 from "asn1js";
|
|
2
|
+
import Joi from "joi";
|
|
3
|
+
import { base64url } from "multiformats/bases/base64";
|
|
4
|
+
import crypto from "node:crypto";
|
|
5
|
+
import * as pki from "pkijs";
|
|
6
|
+
import { red, yellow } from "./print.js";
|
|
7
|
+
import { askQuestion } from "./utils.js";
|
|
8
|
+
export class HardwareWallet {
|
|
9
|
+
graphene;
|
|
10
|
+
mod;
|
|
11
|
+
session;
|
|
12
|
+
slot;
|
|
13
|
+
slotNumber = 0;
|
|
14
|
+
slots;
|
|
15
|
+
constructor(library) {
|
|
16
|
+
this.loadGraphene()
|
|
17
|
+
.then(() => {
|
|
18
|
+
this.mod = this.graphene.Module.load(library, "OpenSC");
|
|
19
|
+
})
|
|
20
|
+
.catch(() => {
|
|
21
|
+
console.warn("Failed to load graphene-pk11");
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
static verify2(message, signature, publicKeyJwk) {
|
|
25
|
+
const derFormatSig = convertRawSignatureToDER(signature);
|
|
26
|
+
const isValid = crypto.verify("sha256", Buffer.from(message), {
|
|
27
|
+
format: "jwk",
|
|
28
|
+
key: publicKeyJwk,
|
|
29
|
+
}, derFormatSig);
|
|
30
|
+
return isValid;
|
|
31
|
+
}
|
|
32
|
+
static verifyJwt(jwt, publicKeyJwk) {
|
|
33
|
+
const jwtParts = jwt.split(".");
|
|
34
|
+
if (jwtParts.length !== 3)
|
|
35
|
+
throw new Error("Invalid JWT format");
|
|
36
|
+
const [headerBase64url, payloadBase64url, signatureBase64url] = jwtParts;
|
|
37
|
+
const message = `${headerBase64url}.${payloadBase64url}`;
|
|
38
|
+
const headerString = Buffer.from(base64url.baseDecode(headerBase64url)).toString();
|
|
39
|
+
const payloadString = Buffer.from(base64url.baseDecode(payloadBase64url)).toString();
|
|
40
|
+
const signature = Buffer.from(base64url.baseDecode(signatureBase64url));
|
|
41
|
+
const result = HardwareWallet.verify2(message, signature, publicKeyJwk);
|
|
42
|
+
if (!result) {
|
|
43
|
+
throw new Error("Invalid signature");
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
header: JSON.parse(headerString),
|
|
47
|
+
payload: JSON.parse(payloadString),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
endSession() {
|
|
51
|
+
try {
|
|
52
|
+
if (this.session)
|
|
53
|
+
this.session.logout();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// empty
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
if (this.mod)
|
|
60
|
+
this.mod.finalize();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// empty
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async generateKeys() {
|
|
67
|
+
this.init();
|
|
68
|
+
await this.login("admin");
|
|
69
|
+
const privateKeys = this.session.find({
|
|
70
|
+
class: this.graphene.ObjectClass.PRIVATE_KEY,
|
|
71
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
72
|
+
paramsECDSA: this.graphene.NamedCurve.getByName("secp256r1").value,
|
|
73
|
+
sign: true,
|
|
74
|
+
token: true,
|
|
75
|
+
});
|
|
76
|
+
if (privateKeys.length > 0) {
|
|
77
|
+
yellow("A P-256 key pair already exists");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
this.session.generateKeyPair(this.graphene.KeyGenMechanism.ECDSA,
|
|
82
|
+
// Public template
|
|
83
|
+
{
|
|
84
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
85
|
+
paramsECDSA: this.graphene.NamedCurve.getByName("secp256r1").value,
|
|
86
|
+
token: true,
|
|
87
|
+
verify: true,
|
|
88
|
+
},
|
|
89
|
+
// Private template
|
|
90
|
+
{
|
|
91
|
+
derive: true,
|
|
92
|
+
extractable: true,
|
|
93
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
94
|
+
paramsECDSA: this.graphene.NamedCurve.getByName("secp256r1").value,
|
|
95
|
+
sign: true,
|
|
96
|
+
token: true,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error instanceof Error) {
|
|
101
|
+
this.endSession();
|
|
102
|
+
if (error.message === "CKR_FUNCTION_NOT_SUPPORTED") {
|
|
103
|
+
throw new Error('CKR_FUNCTION_NOT_SUPPORTED: in your OpenPGP app, go to "Settings" > "Key template", then set "Key" to "Signature" and "Type" to "SECP 256R1", and finally click on "Set Template".', { cause: error });
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
yellow("Key pair generated successfully!");
|
|
109
|
+
this.endSession();
|
|
110
|
+
}
|
|
111
|
+
getInfo() {
|
|
112
|
+
this.init();
|
|
113
|
+
const info = {
|
|
114
|
+
description: this.slot.slotDescription,
|
|
115
|
+
isHardware: Boolean(this.slot.flags & this.graphene.SlotFlag.HW_SLOT),
|
|
116
|
+
isInitialized: Boolean(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT),
|
|
117
|
+
isRemovable: Boolean(this.slot.flags & this.graphene.SlotFlag.REMOVABLE_DEVICE),
|
|
118
|
+
password: {
|
|
119
|
+
max: this.slot.getToken().maxPinLen,
|
|
120
|
+
min: this.slot.getToken().minPinLen,
|
|
121
|
+
},
|
|
122
|
+
serial: this.slot.getToken().serialNumber,
|
|
123
|
+
slot: this.slotNumber,
|
|
124
|
+
};
|
|
125
|
+
this.endSession();
|
|
126
|
+
return info;
|
|
127
|
+
}
|
|
128
|
+
getPublicKey() {
|
|
129
|
+
this.init();
|
|
130
|
+
const publicKeys = this.session.find({
|
|
131
|
+
class: this.graphene.ObjectClass.PUBLIC_KEY,
|
|
132
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
133
|
+
});
|
|
134
|
+
if (publicKeys.length === 0) {
|
|
135
|
+
this.endSession();
|
|
136
|
+
throw new Error('No EC public key found. Run the "generatekey" command first.');
|
|
137
|
+
}
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
139
|
+
const publicKey = publicKeys.items(0).toType();
|
|
140
|
+
const { pointEC } = publicKey.getAttribute({ pointEC: null });
|
|
141
|
+
const schema =
|
|
142
|
+
// @ts-expect-error "Property 'valueHexView' does not exist on type 'ValueBlock'.ts(2339)"
|
|
143
|
+
asn1.fromBER(pointEC).result.valueBlock.valueHexView;
|
|
144
|
+
const publicKeyDecoded = new pki.ECPublicKey({
|
|
145
|
+
namedCurve: "P-256",
|
|
146
|
+
schema,
|
|
147
|
+
});
|
|
148
|
+
this.endSession();
|
|
149
|
+
return { kty: "EC", ...publicKeyDecoded.toJSON() };
|
|
150
|
+
}
|
|
151
|
+
init() {
|
|
152
|
+
if (!this.mod) {
|
|
153
|
+
throw new Error("Hardware wallet cannot be used because the graphene-pk11 package was not loaded");
|
|
154
|
+
}
|
|
155
|
+
this.endSession();
|
|
156
|
+
this.mod.initialize();
|
|
157
|
+
this.slotNumber = 0;
|
|
158
|
+
// get slots
|
|
159
|
+
this.slots = this.mod.getSlots(true);
|
|
160
|
+
if (this.slots.length === 0) {
|
|
161
|
+
this.mod.finalize();
|
|
162
|
+
throw new Error("No slots found. Make sure your Ledger is unlocked and the OpenPGP app is open.");
|
|
163
|
+
}
|
|
164
|
+
this.slot = this.slots.items(this.slotNumber);
|
|
165
|
+
if (!(this.slot.flags & this.graphene.SlotFlag.TOKEN_PRESENT)) {
|
|
166
|
+
this.mod.finalize();
|
|
167
|
+
throw new Error(`Slot ${this.slotNumber} is not initialized`);
|
|
168
|
+
}
|
|
169
|
+
this.session = this.slot.open(this.graphene.SessionFlag.RW_SESSION |
|
|
170
|
+
this.graphene.SessionFlag.SERIAL_SESSION);
|
|
171
|
+
}
|
|
172
|
+
async loadGraphene() {
|
|
173
|
+
this.graphene = await import("graphene-pk11");
|
|
174
|
+
if (!this.graphene) {
|
|
175
|
+
throw new Error("Failed to load graphene-pk11");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async login(userType, loginMessage) {
|
|
179
|
+
let attemptsLeft = 3;
|
|
180
|
+
const isAdmin = userType === "admin";
|
|
181
|
+
let pin = "";
|
|
182
|
+
let validPin = false;
|
|
183
|
+
let loginMsg = isAdmin ? "Enter admin pin: " : "Enter pin: ";
|
|
184
|
+
if (loginMessage)
|
|
185
|
+
loginMsg = loginMessage;
|
|
186
|
+
while (!validPin) {
|
|
187
|
+
try {
|
|
188
|
+
pin = await askQuestion(loginMsg, true);
|
|
189
|
+
this.session.login(pin, isAdmin ? this.graphene.UserType.SO : this.graphene.UserType.USER);
|
|
190
|
+
validPin = true;
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
validPin = false;
|
|
194
|
+
if (error instanceof Error) {
|
|
195
|
+
switch (error.message) {
|
|
196
|
+
case "CKR_PIN_LEN_RANGE": {
|
|
197
|
+
red("Invalid PIN length");
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case "CKR_USER_NOT_LOGGED_IN": {
|
|
201
|
+
attemptsLeft -= 1;
|
|
202
|
+
red(`Invalid PIN. You have ${attemptsLeft} attempts before the PIN is locked`);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case "CKR_PIN_LOCKED": {
|
|
206
|
+
throw new Error(`The PIN is locked. If you want to reset it, open OpenPGP app, go to "Settings" > "Reset" and select "YES"`, { cause: error });
|
|
207
|
+
}
|
|
208
|
+
case "CKR_GENERAL_ERROR": {
|
|
209
|
+
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`, { cause: error });
|
|
210
|
+
}
|
|
211
|
+
// No default
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return pin;
|
|
218
|
+
}
|
|
219
|
+
async setPin(user) {
|
|
220
|
+
Joi.assert(user, Joi.string().valid("user", "admin"));
|
|
221
|
+
this.init();
|
|
222
|
+
const pin = await this.login(user, `Enter current pin for ${user}: `);
|
|
223
|
+
const newPin = await askQuestion("Enter new pin: ", true);
|
|
224
|
+
try {
|
|
225
|
+
this.session.setPin(pin, newPin);
|
|
226
|
+
this.endSession();
|
|
227
|
+
yellow(user === "user"
|
|
228
|
+
? "New pin configured!"
|
|
229
|
+
: "New pin configured for admin!");
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
if (error instanceof Error) {
|
|
233
|
+
if (error.message === "CKR_PIN_LEN_RANGE") {
|
|
234
|
+
throw new Error("Invalid PIN length", { cause: error });
|
|
235
|
+
}
|
|
236
|
+
else if (error.message === "CKR_GENERAL_ERROR") {
|
|
237
|
+
throw new Error(`Hardware wallet error. Make sure your Ledger is unlocked and the OpenPGP app is open`, { cause: error });
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async sign(message) {
|
|
246
|
+
this.init();
|
|
247
|
+
await this.login("user");
|
|
248
|
+
const privateKeys = this.session.find({
|
|
249
|
+
class: this.graphene.ObjectClass.PRIVATE_KEY,
|
|
250
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
251
|
+
paramsECDSA: this.graphene.NamedCurve.getByName("secp256r1").value,
|
|
252
|
+
sign: true,
|
|
253
|
+
token: true,
|
|
254
|
+
});
|
|
255
|
+
if (privateKeys.length === 0) {
|
|
256
|
+
throw new Error('No EC private key found. Run the "generatekey" command first.');
|
|
257
|
+
}
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
259
|
+
const privateKey = privateKeys.items(0).toType();
|
|
260
|
+
// Hash the message using SHA-256
|
|
261
|
+
const sign = this.session.createSign("ECDSA_SHA256", privateKey);
|
|
262
|
+
const signature = sign.once(message);
|
|
263
|
+
// Split the raw signature into r and s components
|
|
264
|
+
const r = signature.toString("hex").slice(0, 66); // First 33 bytes may be padded r
|
|
265
|
+
const s = signature.toString("hex").slice(66); // Next 33 bytes may be padded s
|
|
266
|
+
const sig = Buffer.from(`${r.slice(2)}${s.slice(2)}`, "hex");
|
|
267
|
+
this.endSession();
|
|
268
|
+
return sig;
|
|
269
|
+
}
|
|
270
|
+
async signJWT(payload, header) {
|
|
271
|
+
const headerBase64url = base64url.baseEncode(Buffer.from(JSON.stringify(header)));
|
|
272
|
+
const payloadBase64url = base64url.baseEncode(Buffer.from(JSON.stringify(payload)));
|
|
273
|
+
const message = `${headerBase64url}.${payloadBase64url}`;
|
|
274
|
+
const signature = await this.sign(message);
|
|
275
|
+
const signatureBase64url = base64url.baseEncode(signature);
|
|
276
|
+
return `${message}.${signatureBase64url}`;
|
|
277
|
+
}
|
|
278
|
+
verify(message, signature) {
|
|
279
|
+
this.init();
|
|
280
|
+
const publicKeys = this.session.find({
|
|
281
|
+
class: this.graphene.ObjectClass.PUBLIC_KEY,
|
|
282
|
+
keyType: this.graphene.KeyType.ECDSA,
|
|
283
|
+
});
|
|
284
|
+
if (publicKeys.length === 0) {
|
|
285
|
+
throw new Error('No EC public key found. Run the "generatekey" command first.');
|
|
286
|
+
}
|
|
287
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
288
|
+
const publicKey = publicKeys.items(0).toType();
|
|
289
|
+
const verify = this.session.createVerify("ECDSA_SHA256", publicKey);
|
|
290
|
+
const isValid = verify.once(message, signature);
|
|
291
|
+
this.endSession();
|
|
292
|
+
return isValid;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function convertRawSignatureToDER(rawSignature) {
|
|
296
|
+
if (rawSignature.length !== 64) {
|
|
297
|
+
throw new Error("Raw signature must be 64 bytes (32 bytes for r and 32 bytes for s)");
|
|
298
|
+
}
|
|
299
|
+
// Split raw signature into r and s
|
|
300
|
+
const r = rawSignature.subarray(0, 32);
|
|
301
|
+
const s = rawSignature.subarray(32);
|
|
302
|
+
// Convert r and s to DER integers
|
|
303
|
+
const rDER = toDERInteger(r);
|
|
304
|
+
const sDER = toDERInteger(s);
|
|
305
|
+
// Create DER-encoded SEQUENCE containing the r and s values
|
|
306
|
+
const derSignature = Buffer.concat([
|
|
307
|
+
Buffer.from([0x30]), // ASN.1 SEQUENCE tag
|
|
308
|
+
Buffer.from([rDER.length + sDER.length + 4]), // Total length of SEQUENCE
|
|
309
|
+
Buffer.from([0x02]), // ASN.1 INTEGER tag for r
|
|
310
|
+
Buffer.from([rDER.length]), // Length of r
|
|
311
|
+
rDER, // r value
|
|
312
|
+
Buffer.from([0x02]), // ASN.1 INTEGER tag for s
|
|
313
|
+
Buffer.from([sDER.length]), // Length of s
|
|
314
|
+
sDER, // s value
|
|
315
|
+
]);
|
|
316
|
+
return derSignature;
|
|
317
|
+
}
|
|
318
|
+
// Function to add leading zero if needed
|
|
319
|
+
function toDERInteger(value) {
|
|
320
|
+
if (value[0] && value[0] & 0x80) {
|
|
321
|
+
// If the first byte is >= 0x80, prepend 0x00 to indicate a positive integer
|
|
322
|
+
return Buffer.concat([Buffer.from([0x00]), value]);
|
|
323
|
+
}
|
|
324
|
+
return value;
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=HardwareWallet.js.map
|