@pagopa/io-react-native-jwt 0.4.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 +20 -0
- package/README.md +145 -0
- package/android/build.gradle +97 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/pagopa/ioreactnativejwt/IoReactNativeJwtModule.kt +114 -0
- package/android/src/main/java/com/pagopa/ioreactnativejwt/IoReactNativeJwtPackage.kt +17 -0
- package/android/src/main/java/com/pagopa/ioreactnativejwt/Utils.kt +95 -0
- package/ios/ASN1DERParsing.swift +226 -0
- package/ios/IoReactNativeJwt-Bridging-Header.h +2 -0
- package/ios/IoReactNativeJwt.mm +28 -0
- package/ios/IoReactNativeJwt.swift +156 -0
- package/ios/IoReactNativeJwt.xcodeproj/project.pbxproj +283 -0
- package/lib/commonjs/algorithms.js +39 -0
- package/lib/commonjs/algorithms.js.map +1 -0
- package/lib/commonjs/hash.js +17 -0
- package/lib/commonjs/hash.js.map +1 -0
- package/lib/commonjs/index.js +194 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/jwt_claims_set.js +112 -0
- package/lib/commonjs/jwt_claims_set.js.map +1 -0
- package/lib/commonjs/produce.js +140 -0
- package/lib/commonjs/produce.js.map +1 -0
- package/lib/commonjs/sign.js +159 -0
- package/lib/commonjs/sign.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/unsecured.js +118 -0
- package/lib/commonjs/unsecured.js.map +1 -0
- package/lib/commonjs/utils/asn1.js +37 -0
- package/lib/commonjs/utils/asn1.js.map +1 -0
- package/lib/commonjs/utils/base64.js +43 -0
- package/lib/commonjs/utils/base64.js.map +1 -0
- package/lib/commonjs/utils/errors.js +214 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/is_object.js +23 -0
- package/lib/commonjs/utils/is_object.js.map +1 -0
- package/lib/commonjs/utils/proxy.js +17 -0
- package/lib/commonjs/utils/proxy.js.map +1 -0
- package/lib/commonjs/utils/secs.js +61 -0
- package/lib/commonjs/utils/secs.js.map +1 -0
- package/lib/module/algorithms.js +29 -0
- package/lib/module/algorithms.js.map +1 -0
- package/lib/module/hash.js +11 -0
- package/lib/module/hash.js.map +1 -0
- package/lib/module/index.js +115 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/jwt_claims_set.js +103 -0
- package/lib/module/jwt_claims_set.js.map +1 -0
- package/lib/module/produce.js +131 -0
- package/lib/module/produce.js.map +1 -0
- package/lib/module/sign.js +153 -0
- package/lib/module/sign.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/unsecured.js +110 -0
- package/lib/module/unsecured.js.map +1 -0
- package/lib/module/utils/asn1.js +31 -0
- package/lib/module/utils/asn1.js.map +1 -0
- package/lib/module/utils/base64.js +36 -0
- package/lib/module/utils/base64.js.map +1 -0
- package/lib/module/utils/errors.js +200 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/is_object.js +17 -0
- package/lib/module/utils/is_object.js.map +1 -0
- package/lib/module/utils/proxy.js +10 -0
- package/lib/module/utils/proxy.js.map +1 -0
- package/lib/module/utils/secs.js +53 -0
- package/lib/module/utils/secs.js.map +1 -0
- package/lib/typescript/algorithms.d.ts +5 -0
- package/lib/typescript/algorithms.d.ts.map +1 -0
- package/lib/typescript/hash.d.ts +5 -0
- package/lib/typescript/hash.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +93 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/jwt_claims_set.d.ts +4 -0
- package/lib/typescript/jwt_claims_set.d.ts.map +1 -0
- package/lib/typescript/produce.d.ts +55 -0
- package/lib/typescript/produce.d.ts.map +1 -0
- package/lib/typescript/sign.d.ts +61 -0
- package/lib/typescript/sign.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +172 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/unsecured.d.ts +64 -0
- package/lib/typescript/unsecured.d.ts.map +1 -0
- package/lib/typescript/utils/asn1.d.ts +2 -0
- package/lib/typescript/utils/asn1.d.ts.map +1 -0
- package/lib/typescript/utils/base64.d.ts +4 -0
- package/lib/typescript/utils/base64.d.ts.map +1 -0
- package/lib/typescript/utils/errors.d.ts +157 -0
- package/lib/typescript/utils/errors.d.ts.map +1 -0
- package/lib/typescript/utils/is_object.d.ts +2 -0
- package/lib/typescript/utils/is_object.d.ts.map +1 -0
- package/lib/typescript/utils/proxy.d.ts +2 -0
- package/lib/typescript/utils/proxy.d.ts.map +1 -0
- package/lib/typescript/utils/secs.d.ts +4 -0
- package/lib/typescript/utils/secs.d.ts.map +1 -0
- package/package.json +170 -0
- package/pagopa-io-react-native-jwt.podspec +44 -0
- package/src/algorithms.ts +46 -0
- package/src/hash.ts +10 -0
- package/src/index.tsx +120 -0
- package/src/jwt_claims_set.ts +194 -0
- package/src/produce.ts +109 -0
- package/src/sign.ts +180 -0
- package/src/types.ts +203 -0
- package/src/unsecured.ts +127 -0
- package/src/utils/asn1.ts +36 -0
- package/src/utils/base64.ts +37 -0
- package/src/utils/errors.ts +206 -0
- package/src/utils/is_object.ts +20 -0
- package/src/utils/proxy.ts +15 -0
- package/src/utils/secs.ts +58 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ASN1DERParsing.swift
|
|
3
|
+
// JOSESwift
|
|
4
|
+
//
|
|
5
|
+
// Created by Daniel Egger on 06.02.18.
|
|
6
|
+
//
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Copyright 2019 Airside Mobile Inc.
|
|
9
|
+
//
|
|
10
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
11
|
+
// you may not use this file except in compliance with the License.
|
|
12
|
+
// You may obtain a copy of the License at
|
|
13
|
+
//
|
|
14
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
15
|
+
//
|
|
16
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
// See the License for the specific language governing permissions and
|
|
20
|
+
// limitations under the License.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
//
|
|
23
|
+
|
|
24
|
+
import Foundation
|
|
25
|
+
|
|
26
|
+
internal enum ASN1DERParsingError: Error {
|
|
27
|
+
case incorrectTypeTag(actualTag: UInt8, expectedTag: UInt8)
|
|
28
|
+
case incorrectLengthFieldLength
|
|
29
|
+
case incorrectValueLength
|
|
30
|
+
case incorrectTLVLength
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// Possible ASN.1 types.
|
|
34
|
+
/// See [here](https://msdn.microsoft.com/en-us/library/windows/desktop/bb648640(v=vs.85).aspx)
|
|
35
|
+
/// for more information.
|
|
36
|
+
internal enum ASN1Type {
|
|
37
|
+
case sequence
|
|
38
|
+
case integer
|
|
39
|
+
|
|
40
|
+
var tag: UInt8 {
|
|
41
|
+
switch self {
|
|
42
|
+
case .sequence:
|
|
43
|
+
return 0x30
|
|
44
|
+
case .integer:
|
|
45
|
+
return 0x02
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
internal struct TLVTriplet {
|
|
51
|
+
let tag: UInt8
|
|
52
|
+
let length: [UInt8]
|
|
53
|
+
let value: [UInt8]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// MARK: Array Extension for Parsing
|
|
57
|
+
// Inspired by: https://github.com/henrinormak/Heimdall/blob/master/Heimdall/Heimdall.swift
|
|
58
|
+
|
|
59
|
+
internal extension Array where Element == UInt8 {
|
|
60
|
+
|
|
61
|
+
/// Reads the value of the specified ASN.1 type from the front of the bytes array.
|
|
62
|
+
/// The bytes array is expected to be a DER encoding of an ASN.1 type.
|
|
63
|
+
/// The specified type's TLV triplet is expected to be at the front of the bytes array.
|
|
64
|
+
/// The bytes array may contain trailing bytes after the TLV triplet that are ignored during parsing.
|
|
65
|
+
///
|
|
66
|
+
/// - Parameter type: The ASN.1 type to read.
|
|
67
|
+
/// More information about the expected DER encoding of the specified ASN.1 type can be found
|
|
68
|
+
/// [here](https://msdn.microsoft.com/en-us/library/windows/desktop/bb648640(v=vs.85).aspx).
|
|
69
|
+
/// - Returns: The value of the specified ASN.1 type. More formally, the value field of the type's TLV triplet.
|
|
70
|
+
/// - Throws: An `ASN1DERParsingError` indicating any parsing errors.
|
|
71
|
+
func read(_ type: ASN1Type) throws -> [UInt8] {
|
|
72
|
+
let triplet = try self.nextTLVTriplet()
|
|
73
|
+
|
|
74
|
+
guard triplet.tag == type.tag else {
|
|
75
|
+
throw ASN1DERParsingError.incorrectTypeTag(actualTag: triplet.tag, expectedTag: type.tag)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return triplet.value
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Removes the specified ASN.1 type from the bytes array.
|
|
82
|
+
/// The bytes array is expected to be a DER encoding of a ASN.1 type.
|
|
83
|
+
/// The specified type's TLV triplet is expected to be at the front of the bytes array.
|
|
84
|
+
///
|
|
85
|
+
/// - Parameter type: The ASN.1 type to be removed from the bytes array.
|
|
86
|
+
/// More information about the expected DER encoding of the specified ASN.1 type can be found
|
|
87
|
+
/// [here](https://msdn.microsoft.com/en-us/library/windows/desktop/bb648640(v=vs.85).aspx).
|
|
88
|
+
/// - Returns: The remaining bytes of the bytes array that may contain further ASN.1 types.
|
|
89
|
+
/// - Throws: An `ASN1DERParsingError` indicating any parsing errors.
|
|
90
|
+
func skip(_ type: ASN1Type) throws -> [UInt8] {
|
|
91
|
+
let triplet = try self.nextTLVTriplet()
|
|
92
|
+
|
|
93
|
+
guard triplet.tag == type.tag else {
|
|
94
|
+
throw ASN1DERParsingError.incorrectTypeTag(actualTag: triplet.tag, expectedTag: type.tag)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// TLV triplet = 1 tag byte + some length bytes + some value bytes
|
|
98
|
+
let skippedTripletLength = (1 + triplet.length.count + triplet.value.count)
|
|
99
|
+
|
|
100
|
+
return Array(self.dropFirst(skippedTripletLength))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/// Reads a TLV (tag, length, value) triplet of a DER encoded ASN.1 type from the bytes array.
|
|
104
|
+
/// More information on the DER Transfer Syntax encoding ASN.1 types can be found
|
|
105
|
+
/// [here](https://msdn.microsoft.com/en-us/library/windows/desktop/bb540801(v=vs.85).aspx).
|
|
106
|
+
///
|
|
107
|
+
/// - Returns: A triplet containing the ASN.1 type's tag, length, and value field.
|
|
108
|
+
func nextTLVTriplet() throws -> TLVTriplet {
|
|
109
|
+
var pointer = 0
|
|
110
|
+
|
|
111
|
+
// DER encoding of an ASN.1 type: [ TAG | LENGTH | VALUE ].
|
|
112
|
+
|
|
113
|
+
// At least the tag and one length byte must be present.
|
|
114
|
+
guard self.count >= 2 else {
|
|
115
|
+
throw ASN1DERParsingError.incorrectTLVLength
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let tag = readTag(from: self, pointer: &pointer)
|
|
119
|
+
|
|
120
|
+
let lengthField = try readLengthField(from: self, pointer: &pointer)
|
|
121
|
+
|
|
122
|
+
let valueFieldLength = try length(encodedBy: lengthField)
|
|
123
|
+
|
|
124
|
+
let valueField = try readValueField(ofLength: valueFieldLength, from: self, pointer: &pointer)
|
|
125
|
+
|
|
126
|
+
return TLVTriplet(tag: tag, length: lengthField, value: valueField)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// MARK: Freestanding Helper Functions
|
|
132
|
+
|
|
133
|
+
private func readTag(from encodedTriplet: [UInt8], pointer: inout Int) -> UInt8 {
|
|
134
|
+
let tag = encodedTriplet[pointer]
|
|
135
|
+
|
|
136
|
+
// ---------------------------------------- //
|
|
137
|
+
// tag length field value field //
|
|
138
|
+
// [ 0xN | ............ | ........... ] //
|
|
139
|
+
// ^ //
|
|
140
|
+
// | //
|
|
141
|
+
// pointer //
|
|
142
|
+
// ---------------------------------------- //
|
|
143
|
+
|
|
144
|
+
pointer.advance()
|
|
145
|
+
|
|
146
|
+
return tag
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private func readLengthField(from encodedTriplet: [UInt8], pointer: inout Int) throws -> [UInt8] {
|
|
150
|
+
if encodedTriplet[pointer] < 128 {
|
|
151
|
+
let lengthField = [ encodedTriplet[pointer] ]
|
|
152
|
+
pointer.advance()
|
|
153
|
+
|
|
154
|
+
return lengthField
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// -------------------------------------------------- //
|
|
158
|
+
// tag length field value field //
|
|
159
|
+
// [ ... | 0x8N 0x00 0x01 ... 0xN | ........... ] //
|
|
160
|
+
// ^ | | //
|
|
161
|
+
// | -------v------- //
|
|
162
|
+
// | lengthFieldCount //
|
|
163
|
+
// | //
|
|
164
|
+
// pointer //
|
|
165
|
+
// -------------------------------------------------- //
|
|
166
|
+
|
|
167
|
+
let lengthFieldCount = Int(encodedTriplet[pointer] - 128)
|
|
168
|
+
|
|
169
|
+
// Ensure we have enough bytes left.
|
|
170
|
+
guard (pointer + lengthFieldCount) < encodedTriplet.count else {
|
|
171
|
+
throw ASN1DERParsingError.incorrectLengthFieldLength
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let lengthField = Array(encodedTriplet[pointer...(pointer + lengthFieldCount)])
|
|
175
|
+
|
|
176
|
+
pointer.advance()
|
|
177
|
+
pointer.advance(by: lengthFieldCount)
|
|
178
|
+
|
|
179
|
+
return lengthField
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private func readValueField(ofLength length: Int, from encodedTriplet: [UInt8], pointer: inout Int) throws -> [UInt8] {
|
|
183
|
+
let endPointer = (pointer + length)
|
|
184
|
+
|
|
185
|
+
// --------------------------------------------------------------- //
|
|
186
|
+
// tag length field value field //
|
|
187
|
+
// [ ... | ............ | 0x01 0x02 0x03 0x04 ... 0xN ] //
|
|
188
|
+
// ^ ^ //
|
|
189
|
+
// | | //
|
|
190
|
+
// pointer endPointer //
|
|
191
|
+
// --------------------------------------------------------------- //
|
|
192
|
+
|
|
193
|
+
// Ensure we have enough bytes left.
|
|
194
|
+
guard endPointer <= encodedTriplet.count else {
|
|
195
|
+
throw ASN1DERParsingError.incorrectValueLength
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return Array(encodedTriplet[pointer..<endPointer])
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private func length(encodedBy lengthField: [UInt8]) throws -> Int {
|
|
202
|
+
// If the value field contains < 128 bytes, the length field requires only one byte (00000010 = length two).
|
|
203
|
+
// If the value field contains >= 128 bytes, the highest bit of the length field is 1 and the remaining bits
|
|
204
|
+
// identify the number of bytes needed to encode the length (10000010 - 10000000 = 10 = two length bytes follow).
|
|
205
|
+
|
|
206
|
+
// Length is directly encoded by the only byte in the length field.
|
|
207
|
+
if lengthField.count == 1 {
|
|
208
|
+
return Int(lengthField[0])
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Length is encoded by all but the first byte in the length field.
|
|
212
|
+
// The first byte in the length field encodes the number of remaining bytes used to encode the length.
|
|
213
|
+
var length: UInt64 = 0
|
|
214
|
+
for byte in lengthField.dropFirst() {
|
|
215
|
+
length = (length << 8)
|
|
216
|
+
length += UInt64(byte)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return Int(length)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private extension Int {
|
|
223
|
+
mutating func advance(by n: Int = 1) {
|
|
224
|
+
self = self.advanced(by: n)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
|
|
3
|
+
@interface RCT_EXTERN_MODULE(IoReactNativeJwt, NSObject)
|
|
4
|
+
|
|
5
|
+
RCT_EXTERN_METHOD(verify: (NSString)token
|
|
6
|
+
jwk: (NSDictionary *)jwk
|
|
7
|
+
resolver: (RCTPromiseResolveBlock)resolve
|
|
8
|
+
rejecter: (RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
RCT_EXTERN_METHOD(unpackBerEncodedASN1: (NSString)signature
|
|
11
|
+
coordinateOctetLength: (NSInteger *)coordinateOctetLength
|
|
12
|
+
resolver: (RCTPromiseResolveBlock)resolve
|
|
13
|
+
rejecter: (RCTPromiseRejectBlock)reject)
|
|
14
|
+
|
|
15
|
+
RCT_EXTERN_METHOD(thumbprint: (NSDictionary)jwk
|
|
16
|
+
resolver: (RCTPromiseResolveBlock)resolve
|
|
17
|
+
rejecter: (RCTPromiseRejectBlock)reject)
|
|
18
|
+
|
|
19
|
+
RCT_EXTERN_METHOD(sha256: (NSString)toHash
|
|
20
|
+
resolver: (RCTPromiseResolveBlock)resolve
|
|
21
|
+
rejecter: (RCTPromiseRejectBlock)reject)
|
|
22
|
+
|
|
23
|
+
+ (BOOL)requiresMainQueueSetup
|
|
24
|
+
{
|
|
25
|
+
return NO;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import JOSESwift
|
|
2
|
+
import CommonCrypto
|
|
3
|
+
|
|
4
|
+
@objc(IoReactNativeJwt)
|
|
5
|
+
class IoReactNativeJwt: NSObject {
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
func isECKey(jwk:NSDictionary) -> Bool{
|
|
9
|
+
let kty = jwk["kty"] as! String
|
|
10
|
+
return kty == "EC"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc
|
|
14
|
+
func verify(_ token: String, jwk: NSDictionary, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
|
|
15
|
+
do {
|
|
16
|
+
let jws = try JWS(compactSerialization: token)
|
|
17
|
+
let publicKeyJson = try JSONSerialization.data(withJSONObject: jwk, options:[] )
|
|
18
|
+
var verifier: Verifier?
|
|
19
|
+
if jws.header.algorithm == nil {
|
|
20
|
+
reject("Error", "Invalid algorithm", nil);
|
|
21
|
+
} else {
|
|
22
|
+
if isECKey(jwk:jwk) {
|
|
23
|
+
let ecJwk = try ECPublicKey(data: publicKeyJson)
|
|
24
|
+
let publicKey = try ecJwk.converted(to: SecKey.self)
|
|
25
|
+
verifier = Verifier(verifyingAlgorithm: jws.header.algorithm!, key: publicKey)!
|
|
26
|
+
} else {
|
|
27
|
+
let rsaJwk = try RSAPublicKey(data: publicKeyJson)
|
|
28
|
+
let publicKey = try rsaJwk.converted(to: SecKey.self)
|
|
29
|
+
verifier = Verifier(verifyingAlgorithm: jws.header.algorithm!, key: publicKey)!
|
|
30
|
+
}
|
|
31
|
+
_ = try jws.validate(using: verifier!)
|
|
32
|
+
resolve(true)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
} catch JOSESwiftError.verifyingFailed {
|
|
37
|
+
resolve(false)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
catch {
|
|
41
|
+
reject("Error", "\(error)", error);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@objc
|
|
48
|
+
func unpackBerEncodedASN1(_ signature: String, coordinateOctetLength: Int, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
|
|
49
|
+
do {
|
|
50
|
+
let signatureData = Data(base64Encoded: signature)
|
|
51
|
+
|
|
52
|
+
let ecSignatureTLV = [UInt8](signatureData!)
|
|
53
|
+
let ecSignature = try ecSignatureTLV.read(.sequence)
|
|
54
|
+
let varlenR = try Data(ecSignature.read(.integer))
|
|
55
|
+
let varlenS = try Data(ecSignature.skip(.integer).read(.integer))
|
|
56
|
+
let fixlenR = Asn1IntegerConversion.toRaw(varlenR, of: coordinateOctetLength)
|
|
57
|
+
let fixlenS = Asn1IntegerConversion.toRaw(varlenS, of: coordinateOctetLength)
|
|
58
|
+
let sign = fixlenR + fixlenS
|
|
59
|
+
resolve(String(
|
|
60
|
+
decoding: Data(sign).base64EncodedData(),
|
|
61
|
+
as: UTF8.self
|
|
62
|
+
))
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
reject("Error", "\(error)", error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Converting integers to and from DER encoded ASN.1 as described here:
|
|
71
|
+
// https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-integer
|
|
72
|
+
// This conversion is required because the Secure Enclave only supports generating ASN.1 encoded signatures,
|
|
73
|
+
// while the JWS Standard requires raw signatures, where the R and S are unsigned integers with a fixed length:
|
|
74
|
+
// https://github.com/airsidemobile/JOSESwift/pull/156#discussion_r292370209
|
|
75
|
+
// https://tools.ietf.org/html/rfc7515#appendix-A.3.1
|
|
76
|
+
internal struct Asn1IntegerConversion {
|
|
77
|
+
static func toRaw(_ data: Data, of fixedLength: Int) -> Data {
|
|
78
|
+
let varLength = data.count
|
|
79
|
+
if varLength > fixedLength + 1 {
|
|
80
|
+
fatalError("ASN.1 integer is \(varLength) bytes long when it should be < \(fixedLength + 1).")
|
|
81
|
+
}
|
|
82
|
+
if varLength == fixedLength + 1 {
|
|
83
|
+
assert(data.first == 0)
|
|
84
|
+
return data.dropFirst()
|
|
85
|
+
}
|
|
86
|
+
if varLength == fixedLength {
|
|
87
|
+
return data
|
|
88
|
+
}
|
|
89
|
+
if varLength < fixedLength {
|
|
90
|
+
// pad to fixed length using 0x00 bytes
|
|
91
|
+
return Data(count: fixedLength - varLength) + data
|
|
92
|
+
}
|
|
93
|
+
fatalError("Unable to parse ASN.1 integer. This should be unreachable.")
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static func fromRaw(_ data: Data) -> Data {
|
|
97
|
+
assert(data.count > 0)
|
|
98
|
+
let msb: UInt8 = 0b1000_0000
|
|
99
|
+
// drop all leading zero bytes
|
|
100
|
+
let varlen = data.drop { $0 == 0}
|
|
101
|
+
guard let firstNonZero = varlen.first else {
|
|
102
|
+
// all bytes were zero so the encoded value is zero
|
|
103
|
+
return Data(count: 1)
|
|
104
|
+
}
|
|
105
|
+
if (firstNonZero & msb) == msb {
|
|
106
|
+
return Data(count: 1) + varlen
|
|
107
|
+
}
|
|
108
|
+
return varlen
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@objc
|
|
113
|
+
func thumbprint(_ jwk: NSDictionary, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
|
|
114
|
+
do {
|
|
115
|
+
let publicKeyJson = try JSONSerialization.data(withJSONObject: jwk, options:[] )
|
|
116
|
+
var thumbprint: String?
|
|
117
|
+
if isECKey(jwk:jwk) {
|
|
118
|
+
let ecJwk = try ECPublicKey(data: publicKeyJson)
|
|
119
|
+
thumbprint = try ecJwk.thumbprint()
|
|
120
|
+
} else {
|
|
121
|
+
let rsaJwk = try RSAPublicKey(data: publicKeyJson)
|
|
122
|
+
thumbprint = try rsaJwk.thumbprint()
|
|
123
|
+
}
|
|
124
|
+
resolve(thumbprint)
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
reject("Error", "\(error)", error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
@objc
|
|
132
|
+
func sha256(_ toHash: String, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
|
|
133
|
+
let inputData = toHash.data(using: .utf8)
|
|
134
|
+
if (inputData != nil){
|
|
135
|
+
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
|
136
|
+
_ = inputData!.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in
|
|
137
|
+
if let pointer = bytes.baseAddress?.assumingMemoryBound(to: UInt8.self) {
|
|
138
|
+
CC_SHA256(pointer, CC_LONG(inputData!.count), &digest)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
var sha256String = ""
|
|
142
|
+
for byte in digest {
|
|
143
|
+
sha256String += String(format: "%02x", byte)
|
|
144
|
+
}
|
|
145
|
+
resolve(String(
|
|
146
|
+
decoding: Data(digest).base64EncodedData(),
|
|
147
|
+
as: UTF8.self
|
|
148
|
+
))
|
|
149
|
+
//resolve(sha256String)
|
|
150
|
+
} else {
|
|
151
|
+
reject("Error", "Unable to parse string to hash", nil);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// !$*UTF8*$!
|
|
2
|
+
{
|
|
3
|
+
archiveVersion = 1;
|
|
4
|
+
classes = {
|
|
5
|
+
};
|
|
6
|
+
objectVersion = 46;
|
|
7
|
+
objects = {
|
|
8
|
+
|
|
9
|
+
/* Begin PBXBuildFile section */
|
|
10
|
+
5E555C0D2413F4C50049A1A2 /* IoReactNativeJwt.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* IoReactNativeJwt.mm */; };
|
|
11
|
+
F4FF95D7245B92E800C19C63 /* IoReactNativeJwt.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* IoReactNativeJwt.swift */; };
|
|
12
|
+
/* End PBXBuildFile section */
|
|
13
|
+
|
|
14
|
+
/* Begin PBXCopyFilesBuildPhase section */
|
|
15
|
+
58B511D91A9E6C8500147676 /* CopyFiles */ = {
|
|
16
|
+
isa = PBXCopyFilesBuildPhase;
|
|
17
|
+
buildActionMask = 2147483647;
|
|
18
|
+
dstPath = "include/$(PRODUCT_NAME)";
|
|
19
|
+
dstSubfolderSpec = 16;
|
|
20
|
+
files = (
|
|
21
|
+
);
|
|
22
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
23
|
+
};
|
|
24
|
+
/* End PBXCopyFilesBuildPhase section */
|
|
25
|
+
|
|
26
|
+
/* Begin PBXFileReference section */
|
|
27
|
+
134814201AA4EA6300B7C361 /* libIoReactNativeJwt.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libIoReactNativeJwt.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
28
|
+
B3E7B5891CC2AC0600A0062D /* IoReactNativeJwt.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IoReactNativeJwt.mm; sourceTree = "<group>"; };
|
|
29
|
+
F4FF95D5245B92E700C19C63 /* IoReactNativeJwt-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IoReactNativeJwt-Bridging-Header.h"; sourceTree = "<group>"; };
|
|
30
|
+
F4FF95D6245B92E800C19C63 /* IoReactNativeJwt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IoReactNativeJwt.swift; sourceTree = "<group>"; };
|
|
31
|
+
/* End PBXFileReference section */
|
|
32
|
+
|
|
33
|
+
/* Begin PBXFrameworksBuildPhase section */
|
|
34
|
+
58B511D81A9E6C8500147676 /* Frameworks */ = {
|
|
35
|
+
isa = PBXFrameworksBuildPhase;
|
|
36
|
+
buildActionMask = 2147483647;
|
|
37
|
+
files = (
|
|
38
|
+
);
|
|
39
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
40
|
+
};
|
|
41
|
+
/* End PBXFrameworksBuildPhase section */
|
|
42
|
+
|
|
43
|
+
/* Begin PBXGroup section */
|
|
44
|
+
134814211AA4EA7D00B7C361 /* Products */ = {
|
|
45
|
+
isa = PBXGroup;
|
|
46
|
+
children = (
|
|
47
|
+
134814201AA4EA6300B7C361 /* libIoReactNativeJwt.a */,
|
|
48
|
+
);
|
|
49
|
+
name = Products;
|
|
50
|
+
sourceTree = "<group>";
|
|
51
|
+
};
|
|
52
|
+
58B511D21A9E6C8500147676 = {
|
|
53
|
+
isa = PBXGroup;
|
|
54
|
+
children = (
|
|
55
|
+
F4FF95D6245B92E800C19C63 /* IoReactNativeJwt.swift */,
|
|
56
|
+
B3E7B5891CC2AC0600A0062D /* IoReactNativeJwt.mm */,
|
|
57
|
+
F4FF95D5245B92E700C19C63 /* IoReactNativeJwt-Bridging-Header.h */,
|
|
58
|
+
134814211AA4EA7D00B7C361 /* Products */,
|
|
59
|
+
);
|
|
60
|
+
sourceTree = "<group>";
|
|
61
|
+
};
|
|
62
|
+
/* End PBXGroup section */
|
|
63
|
+
|
|
64
|
+
/* Begin PBXNativeTarget section */
|
|
65
|
+
58B511DA1A9E6C8500147676 /* IoReactNativeJwt */ = {
|
|
66
|
+
isa = PBXNativeTarget;
|
|
67
|
+
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "IoReactNativeJwt" */;
|
|
68
|
+
buildPhases = (
|
|
69
|
+
58B511D71A9E6C8500147676 /* Sources */,
|
|
70
|
+
58B511D81A9E6C8500147676 /* Frameworks */,
|
|
71
|
+
58B511D91A9E6C8500147676 /* CopyFiles */,
|
|
72
|
+
);
|
|
73
|
+
buildRules = (
|
|
74
|
+
);
|
|
75
|
+
dependencies = (
|
|
76
|
+
);
|
|
77
|
+
name = IoReactNativeJwt;
|
|
78
|
+
productName = RCTDataManager;
|
|
79
|
+
productReference = 134814201AA4EA6300B7C361 /* libIoReactNativeJwt.a */;
|
|
80
|
+
productType = "com.apple.product-type.library.static";
|
|
81
|
+
};
|
|
82
|
+
/* End PBXNativeTarget section */
|
|
83
|
+
|
|
84
|
+
/* Begin PBXProject section */
|
|
85
|
+
58B511D31A9E6C8500147676 /* Project object */ = {
|
|
86
|
+
isa = PBXProject;
|
|
87
|
+
attributes = {
|
|
88
|
+
LastUpgradeCheck = 0920;
|
|
89
|
+
ORGANIZATIONNAME = Facebook;
|
|
90
|
+
TargetAttributes = {
|
|
91
|
+
58B511DA1A9E6C8500147676 = {
|
|
92
|
+
CreatedOnToolsVersion = 6.1.1;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "IoReactNativeJwt" */;
|
|
97
|
+
compatibilityVersion = "Xcode 3.2";
|
|
98
|
+
developmentRegion = English;
|
|
99
|
+
hasScannedForEncodings = 0;
|
|
100
|
+
knownRegions = (
|
|
101
|
+
English,
|
|
102
|
+
en,
|
|
103
|
+
);
|
|
104
|
+
mainGroup = 58B511D21A9E6C8500147676;
|
|
105
|
+
productRefGroup = 58B511D21A9E6C8500147676;
|
|
106
|
+
projectDirPath = "";
|
|
107
|
+
projectRoot = "";
|
|
108
|
+
targets = (
|
|
109
|
+
58B511DA1A9E6C8500147676 /* IoReactNativeJwt */,
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
/* End PBXProject section */
|
|
113
|
+
|
|
114
|
+
/* Begin PBXSourcesBuildPhase section */
|
|
115
|
+
58B511D71A9E6C8500147676 /* Sources */ = {
|
|
116
|
+
isa = PBXSourcesBuildPhase;
|
|
117
|
+
buildActionMask = 2147483647;
|
|
118
|
+
files = (
|
|
119
|
+
F4FF95D7245B92E800C19C63 /* IoReactNativeJwt.swift in Sources */,
|
|
120
|
+
B3E7B58A1CC2AC0600A0062D /* IoReactNativeJwt.mm in Sources */,
|
|
121
|
+
);
|
|
122
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
123
|
+
};
|
|
124
|
+
/* End PBXSourcesBuildPhase section */
|
|
125
|
+
|
|
126
|
+
/* Begin XCBuildConfiguration section */
|
|
127
|
+
58B511ED1A9E6C8500147676 /* Debug */ = {
|
|
128
|
+
isa = XCBuildConfiguration;
|
|
129
|
+
buildSettings = {
|
|
130
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
131
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
132
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
133
|
+
CLANG_ENABLE_MODULES = YES;
|
|
134
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
135
|
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
136
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
137
|
+
CLANG_WARN_COMMA = YES;
|
|
138
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
139
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
140
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
141
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
142
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
143
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
144
|
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
145
|
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
146
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
147
|
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
148
|
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
149
|
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
150
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
151
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
152
|
+
COPY_PHASE_STRIP = NO;
|
|
153
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
154
|
+
ENABLE_TESTABILITY = YES;
|
|
155
|
+
"EXCLUDED_ARCHS[sdk=*]" = arm64;
|
|
156
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
157
|
+
GCC_DYNAMIC_NO_PIC = NO;
|
|
158
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
159
|
+
GCC_OPTIMIZATION_LEVEL = 0;
|
|
160
|
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
161
|
+
"DEBUG=1",
|
|
162
|
+
"$(inherited)",
|
|
163
|
+
);
|
|
164
|
+
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
|
165
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
166
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
167
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
168
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
169
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
170
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
171
|
+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
172
|
+
MTL_ENABLE_DEBUG_INFO = YES;
|
|
173
|
+
ONLY_ACTIVE_ARCH = YES;
|
|
174
|
+
SDKROOT = iphoneos;
|
|
175
|
+
};
|
|
176
|
+
name = Debug;
|
|
177
|
+
};
|
|
178
|
+
58B511EE1A9E6C8500147676 /* Release */ = {
|
|
179
|
+
isa = XCBuildConfiguration;
|
|
180
|
+
buildSettings = {
|
|
181
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
182
|
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
183
|
+
CLANG_CXX_LIBRARY = "libc++";
|
|
184
|
+
CLANG_ENABLE_MODULES = YES;
|
|
185
|
+
CLANG_ENABLE_OBJC_ARC = YES;
|
|
186
|
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
|
187
|
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
188
|
+
CLANG_WARN_COMMA = YES;
|
|
189
|
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
190
|
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
191
|
+
CLANG_WARN_EMPTY_BODY = YES;
|
|
192
|
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
193
|
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
194
|
+
CLANG_WARN_INT_CONVERSION = YES;
|
|
195
|
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
|
196
|
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
|
197
|
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
198
|
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
|
199
|
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
|
200
|
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
201
|
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
202
|
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
203
|
+
COPY_PHASE_STRIP = YES;
|
|
204
|
+
ENABLE_NS_ASSERTIONS = NO;
|
|
205
|
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
206
|
+
"EXCLUDED_ARCHS[sdk=*]" = arm64;
|
|
207
|
+
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
208
|
+
GCC_NO_COMMON_BLOCKS = YES;
|
|
209
|
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
210
|
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
211
|
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
212
|
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
213
|
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
214
|
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
215
|
+
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
216
|
+
MTL_ENABLE_DEBUG_INFO = NO;
|
|
217
|
+
SDKROOT = iphoneos;
|
|
218
|
+
VALIDATE_PRODUCT = YES;
|
|
219
|
+
};
|
|
220
|
+
name = Release;
|
|
221
|
+
};
|
|
222
|
+
58B511F01A9E6C8500147676 /* Debug */ = {
|
|
223
|
+
isa = XCBuildConfiguration;
|
|
224
|
+
buildSettings = {
|
|
225
|
+
HEADER_SEARCH_PATHS = (
|
|
226
|
+
"$(inherited)",
|
|
227
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
228
|
+
"$(SRCROOT)/../../../React/**",
|
|
229
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
230
|
+
);
|
|
231
|
+
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
232
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
233
|
+
PRODUCT_NAME = IoReactNativeJwt;
|
|
234
|
+
SKIP_INSTALL = YES;
|
|
235
|
+
SWIFT_OBJC_BRIDGING_HEADER = "IoReactNativeJwt-Bridging-Header.h";
|
|
236
|
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
237
|
+
SWIFT_VERSION = 5.0;
|
|
238
|
+
};
|
|
239
|
+
name = Debug;
|
|
240
|
+
};
|
|
241
|
+
58B511F11A9E6C8500147676 /* Release */ = {
|
|
242
|
+
isa = XCBuildConfiguration;
|
|
243
|
+
buildSettings = {
|
|
244
|
+
HEADER_SEARCH_PATHS = (
|
|
245
|
+
"$(inherited)",
|
|
246
|
+
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
|
247
|
+
"$(SRCROOT)/../../../React/**",
|
|
248
|
+
"$(SRCROOT)/../../react-native/React/**",
|
|
249
|
+
);
|
|
250
|
+
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
|
251
|
+
OTHER_LDFLAGS = "-ObjC";
|
|
252
|
+
PRODUCT_NAME = IoReactNativeJwt;
|
|
253
|
+
SKIP_INSTALL = YES;
|
|
254
|
+
SWIFT_OBJC_BRIDGING_HEADER = "IoReactNativeJwt-Bridging-Header.h";
|
|
255
|
+
SWIFT_VERSION = 5.0;
|
|
256
|
+
};
|
|
257
|
+
name = Release;
|
|
258
|
+
};
|
|
259
|
+
/* End XCBuildConfiguration section */
|
|
260
|
+
|
|
261
|
+
/* Begin XCConfigurationList section */
|
|
262
|
+
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "IoReactNativeJwt" */ = {
|
|
263
|
+
isa = XCConfigurationList;
|
|
264
|
+
buildConfigurations = (
|
|
265
|
+
58B511ED1A9E6C8500147676 /* Debug */,
|
|
266
|
+
58B511EE1A9E6C8500147676 /* Release */,
|
|
267
|
+
);
|
|
268
|
+
defaultConfigurationIsVisible = 0;
|
|
269
|
+
defaultConfigurationName = Release;
|
|
270
|
+
};
|
|
271
|
+
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "IoReactNativeJwt" */ = {
|
|
272
|
+
isa = XCConfigurationList;
|
|
273
|
+
buildConfigurations = (
|
|
274
|
+
58B511F01A9E6C8500147676 /* Debug */,
|
|
275
|
+
58B511F11A9E6C8500147676 /* Release */,
|
|
276
|
+
);
|
|
277
|
+
defaultConfigurationIsVisible = 0;
|
|
278
|
+
defaultConfigurationName = Release;
|
|
279
|
+
};
|
|
280
|
+
/* End XCConfigurationList section */
|
|
281
|
+
};
|
|
282
|
+
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
|
283
|
+
}
|