@@ -9,13 +9,8 @@ enum CryptoUtils {}
99extension CryptoUtils {
1010
1111 static func digest< D: Codable , M: Codable > ( data: D , metadata: M ) throws -> Data {
12- let encoder = JSONEncoder ( )
13- encoder. dateEncodingStrategy = . iso8601
14- encoder. outputFormatting = . sortedKeys
15-
1612 let payload = DigestPayload ( data: data, metadata: metadata)
17- let serializedPayload = try encoder. encode ( payload)
18-
13+ let serializedPayload = try tbDEXJSONEncoder ( ) . encode ( payload)
1914 let digest = SHA256 . hash ( data: serializedPayload)
2015 return Data ( digest)
2116 }
@@ -26,148 +21,3 @@ extension CryptoUtils {
2621 }
2722
2823}
29-
30- // MARK: - Sign
31-
32- extension CryptoUtils {
33-
34- enum SigningError : Error {
35- case assertionMethodNotFound
36- case publicKeyJwkNotFound
37- case algorithmNotDefined
38- }
39-
40- /// Signs the provided payload using the specified DID and key.
41- /// - Parameters:
42- /// - did: DID to use for signing
43- /// - payload: The data to be signed
44- /// - assertionMethodId: The alias of the key to be used for signing.
45- /// - Returns: The signed payload as a detached payload JWT (JSON Web Token).
46- static func sign< D> ( did: BearerDID , payload: D , assertionMethodId: String ? = nil ) async throws -> String
47- where D: DataProtocol {
48- let assertionMethod = try await getAssertionMethod ( did: did, assertionMethodId: assertionMethodId)
49- guard let publicKeyJwk = assertionMethod. publicKeyJwk else {
50- throw SigningError . publicKeyJwkNotFound
51- }
52-
53- let keyAlias = try did. keyManager. getDeterministicAlias ( key: publicKeyJwk)
54- let publicKey = try did. keyManager. getPublicKey ( keyAlias: keyAlias)
55- guard let algorithm = publicKey. algorithm? . jwsAlgorithm else {
56- throw SigningError . algorithmNotDefined
57- }
58-
59- let jwsHeader = JWS . Header (
60- algorithm: algorithm,
61- keyID: assertionMethod. id
62- )
63-
64- let base64UrlEncodedHeader = try JSONEncoder ( ) . encode ( jwsHeader) . base64UrlEncodedString ( )
65- let base64UrlEncodedPayload = payload. base64UrlEncodedString ( )
66-
67- let toSign = " \( base64UrlEncodedHeader) . \( base64UrlEncodedPayload) "
68- let signatureBytes = try did. keyManager. sign ( keyAlias: keyAlias, payload: Data ( toSign. utf8) )
69- let base64UrlEncodedSignature = signatureBytes. base64UrlEncodedString ( )
70-
71- return " \( base64UrlEncodedHeader) .. \( base64UrlEncodedSignature) "
72- }
73-
74- private static func getAssertionMethod( did: BearerDID , assertionMethodId: String ? ) async throws
75- -> VerificationMethod
76- {
77- let resolutionResult = await DIDResolver . resolve ( didURI: did. uri)
78- let assertionMethods = resolutionResult. didDocument? . assertionMethodDereferenced
79-
80- guard
81- let assertionMethod =
82- if let assertionMethodId {
83- assertionMethods? . first ( where: { $0. id == assertionMethodId } )
84- } else {
85- assertionMethods? . first
86- }
87- else {
88- throw SigningError . assertionMethodNotFound
89- }
90-
91- return assertionMethod
92- }
93-
94- }
95-
96- // MARK: - Verify
97-
98- extension CryptoUtils {
99-
100- struct VerifyError : Error {
101- let reason : String
102- }
103-
104- // Verifies the integrity of a message or resource's signature.
105- static func verify< D: DataProtocol > (
106- didURI: String ,
107- signature: String ? ,
108- detachedPayload: D ? = nil
109- ) async throws -> Bool {
110- guard let signature else {
111- throw VerifyError ( reason: " Signature not present " )
112- }
113-
114- let splitJWS = signature. split ( separator: " . " , omittingEmptySubsequences: false )
115-
116- guard splitJWS. count == 3 else {
117- throw VerifyError ( reason: " Excpected valid JWS with 3 parts, got \( splitJWS. count) " )
118- }
119-
120- let decoder = JSONDecoder ( )
121- decoder. dateDecodingStrategy = . iso8601
122-
123- let jwsHeader = String ( splitJWS [ 0 ] )
124- let jwsSignature = String ( splitJWS [ 2 ] )
125- let jwsPayload : String
126-
127- if let detachedPayload {
128- guard splitJWS [ 1 ] . count == 0 else {
129- throw VerifyError ( reason: " Expected valid JWS with detached payload " )
130- }
131- jwsPayload = String ( detachedPayload. base64UrlEncodedString ( ) )
132- } else {
133- jwsPayload = String ( splitJWS [ 1 ] )
134- }
135-
136- guard let jwsHeader = try ? JSONDecoder ( ) . decode ( JWS . Header. self, from: jwsHeader. decodeBase64Url ( ) ) ,
137- let verificationMethodID = jwsHeader. keyID
138- else {
139- throw VerifyError ( reason: " " )
140- }
141-
142- let signingDID = try DID ( didURI: verificationMethodID)
143- let signingDIDURI = signingDID. uriWithoutFragment
144-
145- guard signingDIDURI == didURI else {
146- throw VerifyError ( reason: " Was not signed by the expected DID - Expected: \( didURI) Actual: \( signingDIDURI) " )
147- }
148-
149- let resolutionResult = await DIDResolver . resolve ( didURI: signingDIDURI)
150- if let error = resolutionResult. didResolutionMetadata. error {
151- throw VerifyError ( reason: " Failed to resolve DID \( signingDIDURI) : \( error) " )
152- }
153-
154- guard
155- let assertionMethod =
156- resolutionResult. didDocument? . assertionMethodDereferenced? . first (
157- where: { $0. absoluteId == verificationMethodID }
158- )
159- else {
160- throw VerifyError ( reason: " Assertion method not found " )
161- }
162-
163- let publicKeyJwk = assertionMethod. publicKeyJwk!
164-
165- return try Crypto . verify (
166- payload: try jwsPayload. decodeBase64Url ( ) ,
167- signature: try jwsSignature. decodeBase64Url ( ) ,
168- publicKey: publicKeyJwk,
169- jwsAlgorithm: jwsHeader. algorithm
170- )
171- }
172-
173- }
0 commit comments