@pagopa/io-react-native-iso18013 0.3.0 → 0.5.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.
Files changed (110) hide show
  1. package/README.md +10 -5
  2. package/android/build.gradle +7 -1
  3. package/android/src/main/java/com/ioreactnativeiso18013/IoReactNativeCborModule.kt +69 -134
  4. package/android/src/main/java/com/ioreactnativeiso18013/IoReactNativeIso18013Module.kt +254 -183
  5. package/android/src/test/java/com/ioreactnativeiso18013/Base64UtilsTest.kt +66 -0
  6. package/android/src/test/java/com/ioreactnativeiso18013/IoReactNativeIso18013Test.kt +508 -0
  7. package/ios/Base64Utils.swift +10 -3
  8. package/ios/IoReactNativeCbor.mm +21 -21
  9. package/ios/IoReactNativeCbor.swift +116 -138
  10. package/ios/IoReactNativeIso18013.mm +10 -10
  11. package/ios/IoReactNativeIso18013.swift +172 -193
  12. package/lib/module/cbor/cbor/README.md +39 -59
  13. package/lib/module/cbor/cbor/decoder.js +13 -23
  14. package/lib/module/cbor/cbor/decoder.js.map +1 -1
  15. package/lib/module/cbor/cbor/error.js +15 -0
  16. package/lib/module/cbor/cbor/error.js.map +1 -0
  17. package/lib/module/cbor/cbor/index.js +1 -0
  18. package/lib/module/cbor/cbor/index.js.map +1 -1
  19. package/lib/module/cbor/cose/README.md +39 -9
  20. package/lib/module/cbor/cose/error.js +17 -0
  21. package/lib/module/cbor/cose/error.js.map +1 -0
  22. package/lib/module/cbor/cose/index.js +1 -0
  23. package/lib/module/cbor/cose/index.js.map +1 -1
  24. package/lib/module/cbor/cose/sign.js +4 -3
  25. package/lib/module/cbor/cose/sign.js.map +1 -1
  26. package/lib/module/iso18013/index.js +0 -1
  27. package/lib/module/iso18013/index.js.map +1 -1
  28. package/lib/module/iso18013/iso18013-5/README.md +120 -44
  29. package/lib/module/iso18013/iso18013-5/error.js +25 -0
  30. package/lib/module/iso18013/iso18013-5/error.js.map +1 -0
  31. package/lib/module/iso18013/iso18013-5/index.js +3 -2
  32. package/lib/module/iso18013/iso18013-5/index.js.map +1 -1
  33. package/lib/module/iso18013/iso18013-5/proximity.js +20 -15
  34. package/lib/module/iso18013/iso18013-5/proximity.js.map +1 -1
  35. package/lib/module/iso18013/iso18013-5/{schema.js → request.js} +1 -37
  36. package/lib/module/iso18013/iso18013-5/request.js.map +1 -0
  37. package/lib/module/iso18013/iso18013-7/README.md +66 -41
  38. package/lib/module/iso18013/iso18013-7/error.js +15 -0
  39. package/lib/module/iso18013/iso18013-7/error.js.map +1 -0
  40. package/lib/module/iso18013/iso18013-7/index.js +1 -0
  41. package/lib/module/iso18013/iso18013-7/index.js.map +1 -1
  42. package/lib/module/iso18013/iso18013-7/remote.js +11 -24
  43. package/lib/module/iso18013/iso18013-7/remote.js.map +1 -1
  44. package/lib/module/schema.js +46 -0
  45. package/lib/module/schema.js.map +1 -0
  46. package/lib/typescript/src/cbor/cbor/decoder.d.ts +12 -22
  47. package/lib/typescript/src/cbor/cbor/decoder.d.ts.map +1 -1
  48. package/lib/typescript/src/cbor/cbor/error.d.ts +68 -0
  49. package/lib/typescript/src/cbor/cbor/error.d.ts.map +1 -0
  50. package/lib/typescript/src/cbor/cbor/index.d.ts +1 -1
  51. package/lib/typescript/src/cbor/cbor/index.d.ts.map +1 -1
  52. package/lib/typescript/src/cbor/cose/error.d.ts +68 -0
  53. package/lib/typescript/src/cbor/cose/error.d.ts.map +1 -0
  54. package/lib/typescript/src/cbor/cose/index.d.ts +1 -1
  55. package/lib/typescript/src/cbor/cose/index.d.ts.map +1 -1
  56. package/lib/typescript/src/cbor/cose/sign.d.ts +4 -3
  57. package/lib/typescript/src/cbor/cose/sign.d.ts.map +1 -1
  58. package/lib/typescript/src/iso18013/index.d.ts +0 -1
  59. package/lib/typescript/src/iso18013/index.d.ts.map +1 -1
  60. package/lib/typescript/src/iso18013/iso18013-5/error.d.ts +73 -0
  61. package/lib/typescript/src/iso18013/iso18013-5/error.d.ts.map +1 -0
  62. package/lib/typescript/src/iso18013/iso18013-5/index.d.ts +4 -3
  63. package/lib/typescript/src/iso18013/iso18013-5/index.d.ts.map +1 -1
  64. package/lib/typescript/src/iso18013/iso18013-5/proximity.d.ts +21 -14
  65. package/lib/typescript/src/iso18013/iso18013-5/proximity.d.ts.map +1 -1
  66. package/lib/typescript/src/iso18013/iso18013-5/{schema.d.ts → request.d.ts} +1 -39
  67. package/lib/typescript/src/iso18013/iso18013-5/request.d.ts.map +1 -0
  68. package/lib/typescript/src/iso18013/iso18013-7/error.d.ts +68 -0
  69. package/lib/typescript/src/iso18013/iso18013-7/error.d.ts.map +1 -0
  70. package/lib/typescript/src/iso18013/iso18013-7/index.d.ts +3 -2
  71. package/lib/typescript/src/iso18013/iso18013-7/index.d.ts.map +1 -1
  72. package/lib/typescript/src/iso18013/iso18013-7/remote.d.ts +11 -25
  73. package/lib/typescript/src/iso18013/iso18013-7/remote.d.ts.map +1 -1
  74. package/lib/typescript/src/iso18013/types.d.ts +25 -0
  75. package/lib/typescript/src/iso18013/types.d.ts.map +1 -1
  76. package/lib/typescript/src/schema.d.ts +76 -0
  77. package/lib/typescript/src/schema.d.ts.map +1 -0
  78. package/package.json +1 -1
  79. package/src/cbor/cbor/README.md +39 -59
  80. package/src/cbor/cbor/decoder.ts +13 -23
  81. package/src/cbor/cbor/error.ts +23 -0
  82. package/src/cbor/cbor/index.ts +5 -1
  83. package/src/cbor/cose/README.md +39 -9
  84. package/src/cbor/cose/error.ts +23 -0
  85. package/src/cbor/cose/index.ts +5 -1
  86. package/src/cbor/cose/sign.ts +5 -4
  87. package/src/iso18013/index.ts +0 -7
  88. package/src/iso18013/iso18013-5/README.md +120 -44
  89. package/src/iso18013/iso18013-5/error.ts +35 -0
  90. package/src/iso18013/iso18013-5/index.ts +9 -8
  91. package/src/iso18013/iso18013-5/proximity.ts +21 -17
  92. package/src/iso18013/iso18013-5/{schema.ts → request.ts} +0 -42
  93. package/src/iso18013/iso18013-7/README.md +66 -41
  94. package/src/iso18013/iso18013-7/error.ts +21 -0
  95. package/src/iso18013/iso18013-7/index.ts +6 -5
  96. package/src/iso18013/iso18013-7/remote.ts +12 -34
  97. package/src/iso18013/types.ts +24 -0
  98. package/src/schema.ts +55 -0
  99. package/lib/module/cbor/cbor/failure.js +0 -2
  100. package/lib/module/cbor/cbor/failure.js.map +0 -1
  101. package/lib/module/cbor/cose/failure.js +0 -2
  102. package/lib/module/cbor/cose/failure.js.map +0 -1
  103. package/lib/module/iso18013/iso18013-5/schema.js.map +0 -1
  104. package/lib/typescript/src/cbor/cbor/failure.d.ts +0 -15
  105. package/lib/typescript/src/cbor/cbor/failure.d.ts.map +0 -1
  106. package/lib/typescript/src/cbor/cose/failure.d.ts +0 -15
  107. package/lib/typescript/src/cbor/cose/failure.d.ts.map +0 -1
  108. package/lib/typescript/src/iso18013/iso18013-5/schema.d.ts.map +0 -1
  109. package/src/cbor/cbor/failure.ts +0 -18
  110. package/src/cbor/cose/failure.ts +0 -20
@@ -4,185 +4,163 @@ import CryptoKit
4
4
 
5
5
  @objc(IoReactNativeCbor)
6
6
  class IoReactNativeCbor: NSObject {
7
- private typealias ME = ModuleException
8
- private let keyConfig: KeyConfig = .ec
9
7
 
10
- @objc func decode(
11
- _ cbor: String,
8
+ /**
9
+ Decode base64 or base64url encoded CBOR data to JSON object.
10
+ Resolves with a string containing the parsed data or rejects with an error code defined in ``ModuleErrorCodes``.
11
+ This method does not handle nested CBOR data, which will need additional parsing.
12
+ - Parameters:
13
+ - data: The base64 or base64url encoded CBOR string.
14
+ - resolve: The promise to be resolved.
15
+ - reject: The promise to be rejected.
16
+ */
17
+ @objc(decode:withResolver:withRejecter:)
18
+ func decode(
19
+ data: String,
12
20
  resolver resolve: RCTPromiseResolveBlock,
13
21
  rejecter reject: RCTPromiseRejectBlock
14
22
  ) {
15
- guard let data = try? Base64Utils.decodeBase64OrBase64URL(base: cbor) else {
16
- ME.invalidEncoding.reject(reject: reject)
17
- return
18
- }
19
-
20
- guard let json = CborCose.jsonFromCBOR(data: data) else {
21
- ME.unableToDecode.reject(reject: reject)
22
- return
23
+ do{
24
+ let buffer = try Base64Utils.decodeBase64OrBase64URL(base: data)
25
+ guard let json = CborCose.jsonFromCBOR(data: buffer) else {
26
+ // We don't have the exact error here as this method returns nil upon failure
27
+ reject(ModuleErrorCodes.decodeError.rawValue, "Unable to decode CBOR", nil)
28
+ return
29
+ }
30
+ resolve(json);
31
+
32
+ }catch{
33
+ reject(ModuleErrorCodes.decodeError.rawValue, error.localizedDescription, error)
23
34
  }
24
-
25
- resolve(json);
26
35
  }
27
36
 
28
-
29
- @objc func decodeDocuments(
30
- _ mdoc: String,
37
+ /**
38
+ Decode base64 or base64url encoded mDOC-CBOR data to a JSON object.
39
+ Resolves with a string containing the parsed data or rejects with an error code defined in ``ModuleErrorCodes``.
40
+ - Parameters:
41
+ - data: The base64 or base64url encoded mDOC-CBOR string.
42
+ - resolve: The promise to be resolved.
43
+ - reject: The promise to be rejected.
44
+ */
45
+ @objc(decodeDocuments:withResolver:withRejecter:)
46
+ func decodeDocuments(
47
+ data: String,
31
48
  resolver resolve: RCTPromiseResolveBlock,
32
49
  rejecter reject: RCTPromiseRejectBlock
33
50
  ) {
34
- guard let data = try? Base64Utils.decodeBase64OrBase64URL(base: mdoc) else {
35
- ME.invalidEncoding.reject(reject: reject)
51
+ do{
52
+ let buffer = try Base64Utils.decodeBase64OrBase64URL(base: data)
53
+ guard let json = CborCose.decodeCBOR(data: buffer, true, true) else {
54
+ // We don't have the exact error here as this method returns nil upon failure
55
+ reject(ModuleErrorCodes.decodeDocumentsError.rawValue, "Unable to decode document CBOR", nil)
36
56
  return
57
+ }
58
+ resolve(json);
59
+ }catch{
60
+ reject(ModuleErrorCodes.decodeDocumentsError.rawValue, error.localizedDescription, error)
37
61
  }
38
-
39
- guard let json = CborCose.decodeCBOR(data: data, true, true) else {
40
- ME.unableToDecode.reject(reject: reject)
41
- return
42
- }
43
-
44
- resolve(json);
45
62
  }
46
63
 
47
- @objc func decodeIssuerSigned(
48
- _ issuerSigned: String,
64
+ /**
65
+ Decode base64 or base64url encoded issuerSigned attribute part of an mDOC-CBOR.
66
+ Resolves with a string containing the parsed data or rejects with an error code defined in ``ModuleErrorCodes``.
67
+ - Parameters:
68
+ - data: The base64 or base64url encoded mDOC-CBOR containing the issuerSigned data string.
69
+ - resolve: The promise to be resolved.
70
+ - reject: The promise to be rejected.
71
+ */
72
+ @objc(decodeIssuerSigned:withResolver:withRejecter:)
73
+ func decodeIssuerSigned(
74
+ data: String,
49
75
  resolver resolve: RCTPromiseResolveBlock,
50
76
  rejecter reject: RCTPromiseRejectBlock
51
77
  ) {
52
- guard let data = try? Base64Utils.decodeBase64OrBase64URL(base: issuerSigned) else {
53
- ME.invalidEncoding.reject(reject: reject)
78
+ do{
79
+ let buffer = try Base64Utils.decodeBase64OrBase64URL(base: data)
80
+ guard let json = CborCose.issuerSignedCborToJson(data: buffer) else {
81
+ // We don't have the exact error here as this method returns nil upon failure
82
+ reject(ModuleErrorCodes.decodeIssuerSignedError.rawValue, "Unable to decode Issuer Signed CBOR", nil)
54
83
  return
84
+ }
85
+ resolve(json);
86
+ }catch{
87
+ reject(ModuleErrorCodes.decodeIssuerSignedError.rawValue, error.localizedDescription, error)
55
88
  }
56
-
57
- guard let json = CborCose.issuerSignedCborToJson(data: data) else {
58
- ME.unableToDecode.reject(reject: reject)
59
- return
60
- }
61
-
62
- resolve(json);
63
89
  }
64
90
 
65
- @objc func sign(
66
- _ payloadData: String,
91
+ /**
92
+ Sign base64 encoded data with COSE and return the COSE-Sign1 object in base64 encoding.
93
+ Resolves with a string containing the COSE-Sign1 object in base64 encoding or rejects with an error code defined in ``ModuleErrorCodes``.
94
+ - Parameters:
95
+ - data: The base64 or base64url encoded payload to sign.
96
+ - keyTag: The alias of the key to use for signing.
97
+ - resolve: The promise to be resolved.
98
+ - reject: The promise to be rejected.
99
+ */
100
+ @objc(sign:withKeyTag:withResolver:withRejecter:)
101
+ func sign(
102
+ data: String,
67
103
  keyTag: String,
68
104
  resolver resolve: @escaping RCTPromiseResolveBlock,
69
105
  rejecter reject: @escaping RCTPromiseRejectBlock
70
106
  ) {
71
- DispatchQueue.global().async { [weak self] in
72
- guard self != nil else {
73
- ME.threadingError.reject(reject: reject)
74
- return
107
+ DispatchQueue.global().async { [weak self] in
108
+ guard self != nil else {
109
+ reject(ModuleErrorCodes.threadingError.rawValue, "Failed to perform background operation, self was deallocated", nil)
110
+ return
111
+ }
112
+
113
+ do{
114
+ let buffer = try Base64Utils.decodeBase64OrBase64URL(base: data)
115
+ guard let coseKey = CoseKeyPrivate(crv: .p256, keyTag: keyTag) else {
116
+ // We don't have the exact error here as this method returns nil upon failure
117
+ reject(ModuleErrorCodes.signError.rawValue, "Unable to create a private key with the given keytag: \(keyTag)", nil)
118
+ return
119
+ }
120
+ let signedPayload = CborCose.sign(data: buffer, privateKey: coseKey)
121
+ resolve(signedPayload.base64EncodedString())
75
122
  }
76
-
77
- guard let data = try? Base64Utils.decodeBase64OrBase64URL(base: payloadData) else {
78
- ME.invalidEncoding.reject(reject: reject)
79
- return
123
+ catch{
124
+ reject(ModuleErrorCodes.signError.rawValue, error.localizedDescription, error)
80
125
  }
81
-
82
- guard let coseKey = CoseKeyPrivate(crv: .p256, keyTag: keyTag) else {
83
- ME.publicKeyNotFound.reject(reject: reject)
84
- return
85
- }
86
-
87
- let signedPayload = CborCose.sign(data: data, privateKey: coseKey)
88
- resolve(signedPayload.base64EncodedString())
89
126
  }
90
127
  }
91
128
 
92
- @objc func verify(
93
- _ sign1Data: String,
94
- jwk: NSDictionary,
129
+ /**
130
+ Verifies a COSE-Sign1 object with the provided public key.
131
+ Resolves with boolean indicating whether or not the verification succeeded or not or rejects with an error code defined in ``ModuleErrorCodes``.
132
+ - Parameters:
133
+ - data: The COSE-Sign1 object in base64 or base64url encoding.
134
+ - publicKey: The public key in JWK format.
135
+ - resolve: The promise to be resolved
136
+ - reject: The promise to be rejected..
137
+ */
138
+ @objc(verify:withJwk:withResolver:withRejecter:)
139
+ func verify(
140
+ data: String,
141
+ publicKey: NSDictionary,
95
142
  resolver resolve: RCTPromiseResolveBlock,
96
143
  rejecter reject: RCTPromiseRejectBlock
97
144
  ) {
98
145
  do {
99
- guard let data = try? Base64Utils.decodeBase64OrBase64URL(base: sign1Data) else {
100
- ME.invalidEncoding.reject(reject: reject)
101
- return
102
- }
103
-
104
- let publicKeyJson = try JSONSerialization.data(withJSONObject: jwk, options:[] )
146
+ let buffer = try Base64Utils.decodeBase64OrBase64URL(base: data)
147
+ let publicKeyJson = try JSONSerialization.data(withJSONObject: publicKey, options:[] )
105
148
  let publicKeyString = String(data: publicKeyJson, encoding: .utf8)!
106
149
  let publicKey = CoseKey(jwk: publicKeyString)!
107
-
108
- let verified = CborCose.verify(data: data, publicKey: publicKey)
109
-
150
+ let verified = CborCose.verify(data: buffer, publicKey: publicKey)
110
151
  resolve(verified)
111
152
  } catch {
112
- ME.unknownException.reject(reject: reject)
153
+ reject(ModuleErrorCodes.verifyError.rawValue, error.localizedDescription, error)
113
154
  }
114
155
  }
115
-
116
- private func keyExists(keyTag: String) -> (key: SecKey?, status: OSStatus) {
117
- let getQuery = privateKeyKeychainQuery(keyTag: keyTag)
118
- var item: CFTypeRef?
119
- let status = SecItemCopyMatching(getQuery as CFDictionary, &item)
120
- return (status == errSecSuccess ? (item as! SecKey) : nil, status)
121
- }
122
156
 
123
- private func privateKeyKeychainQuery(
124
- keyTag: String
125
- ) -> [String : Any] {
126
- return [
127
- kSecClass as String: kSecClassKey,
128
- kSecAttrApplicationTag as String: keyTag,
129
- kSecAttrKeyType as String: keyConfig.keyType(),
130
- kSecReturnRef as String: true
131
- ]
132
- }
133
-
134
- private enum KeyConfig: Int, CaseIterable {
135
- case ec
136
-
137
- func keyType() -> CFString {
138
- switch self {
139
- case .ec:
140
- return kSecAttrKeyTypeECSECPrimeRandom
141
- }
142
- }
143
-
144
- func keySizeInBits() -> Int {
145
- switch self {
146
- case .ec:
147
- return 256
148
- }
149
- }
150
-
151
- func keySignAlgorithm() -> SecKeyAlgorithm {
152
- switch self {
153
- case .ec:
154
- return .ecdsaSignatureMessageX962SHA256
155
- }
156
- }
157
- }
158
-
159
- private enum ModuleException: String, CaseIterable {
160
- case unableToDecode = "UNABLE_TO_DECODE"
161
- case publicKeyNotFound = "PUBLIC_KEY_NOT_FOUND"
162
- case invalidEncoding = "INVALID_ENCODING"
157
+ // Errors which this module uses to reject a promise
158
+ private enum ModuleErrorCodes: String, CaseIterable {
159
+ case decodeError = "DECODE_ERROR"
160
+ case decodeDocumentsError = "DECODE_DOCUMENTS_ERROR"
161
+ case decodeIssuerSignedError = "DECODE_ISSUER_SIGNED_ERROR"
162
+ case signError = "SIGN_ERROR"
163
+ case verifyError = "VERIFY_ERROR"
163
164
  case threadingError = "THREADING_ERROR"
164
- case unknownException = "UNKNOWN_EXCEPTION"
165
-
166
- func error(userInfo: [String : Any]? = nil) -> NSError {
167
- switch self {
168
- case .unableToDecode:
169
- return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
170
- case .publicKeyNotFound:
171
- return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
172
- case .invalidEncoding:
173
- return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
174
- case .threadingError:
175
- return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
176
- case .unknownException:
177
- return NSError(domain: self.rawValue, code: -1, userInfo: userInfo)
178
- }
179
- }
180
-
181
- func reject(reject: RCTPromiseRejectBlock, _ moreUserInfo: (String, Any)...) {
182
- var userInfo = [String : Any]()
183
- moreUserInfo.forEach { userInfo[$0.0] = $0.1 }
184
- let error = error(userInfo: userInfo)
185
- reject("\(error.code)", error.domain, error)
186
- }
187
165
  }
188
166
  }
@@ -18,22 +18,22 @@ RCT_EXTERN_METHOD(generateResponse:(NSArray *)documents
18
18
  withResolver:(RCTPromiseResolveBlock)resolve
19
19
  withRejecter:(RCTPromiseRejectBlock)reject)
20
20
 
21
- RCT_EXTERN_METHOD(sendResponse:(NSString)response
21
+ RCT_EXTERN_METHOD(sendResponse:(NSString *)response
22
22
  withResolver:(RCTPromiseResolveBlock)resolve
23
23
  withRejecter:(RCTPromiseRejectBlock)reject)
24
24
 
25
- RCT_EXTERN_METHOD(sendErrorResponse:(NSInteger)status
25
+ RCT_EXTERN_METHOD(sendErrorResponse:(NSInteger *)code
26
26
  withResolver:(RCTPromiseResolveBlock)resolve
27
27
  withRejecter:(RCTPromiseRejectBlock)reject)
28
28
 
29
- RCT_EXTERN_METHOD(generateOID4VPDeviceResponse: (NSString)clientId
30
- responseUri: (NSString*)responseUri
31
- authorizationRequestNonce: (NSString*)authorizationRequestNonce
32
- mdocGeneratedNonce: (NSString*)mdocGeneratedNonce
33
- documents: (NSArray*)documents
34
- fieldRequestedAndAccepted: (NSString*)fieldRequestedAndAccepted
35
- resolver: (RCTPromiseResolveBlock)resolve
36
- rejecter: (RCTPromiseRejectBlock)reject)
29
+ RCT_EXTERN_METHOD(generateOID4VPDeviceResponse: (NSString *)clientId
30
+ withResponseUri: (NSString *)responseUri
31
+ withAuthorizationRequestNonce: (NSString *)authorizationRequestNonce
32
+ withMdocGeneratedNonce: (NSString *)mdocGeneratedNonce
33
+ withDocuments: (NSArray *)documents
34
+ withAcceptedFields: (NSDictionary *)acceptedFields
35
+ withResolver: (RCTPromiseResolveBlock)resolve
36
+ withRejecter: (RCTPromiseRejectBlock)reject)
37
37
 
38
38
  + (BOOL)requiresMainQueueSetup
39
39
  {