1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;
use crate::*;
extern_class!(
/// A service that you use to validate the instance of your app running on a
/// device.
///
/// Use the ``DeviceCheck/DCAppAttestService/sharedService`` instance of the
/// ``DeviceCheck/DCAppAttestService`` class to assert the legitimacy of a
/// particular instance of your app to your server. After ensuring service
/// availability by reading the ``DeviceCheck/DCAppAttestService/supported``
/// property, you use the service to:
///
/// - Create a cryptographic key in the Secure Enclave by calling the
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method.
/// - Ask Apple to certify the key by calling the
/// ``DeviceCheck/DCAppAttestService/attestKey:clientDataHash:completionHandler:``
/// method. - Prepare an assertion of your app’s integrity to accompany any or
/// all server requests using the
/// ``DeviceCheck/DCAppAttestService/generateAssertion:clientDataHash:completionHandler:``
/// method.
///
/// For more information about how to support App Attest in your app, see
/// <doc
/// :establishing-your-app-s-integrity>. For information about the
/// complementary procedures you implement on your server, see
/// <doc
/// :validating-apps-that-connect-to-your-server>.
///
/// - Note: To use the App Attest service, your app must have an app ID that you
/// register on the [Apple Developer](https://developer.apple.com/account/)
/// website.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/devicecheck/dcappattestservice?language=objc)
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct DCAppAttestService;
);
extern_conformance!(
unsafe impl NSObjectProtocol for DCAppAttestService {}
);
impl DCAppAttestService {
extern_methods!(
/// The shared App Attest service that you use to validate your app.
///
/// Use the shared instance of the service to generate and to certify a
/// cryptographic key, and then to assert your app’s validity using that key.
#[unsafe(method(sharedService))]
#[unsafe(method_family = none)]
pub unsafe fn sharedService() -> Retained<DCAppAttestService>;
/// A Boolean value that indicates whether a particular device provides the App
/// Attest service.
///
/// > Important: Not all device types support the App Attest service, so check
/// > for support before using the service.
/// >
/// > If you read ``DeviceCheck/DCAppAttestService/supported`` from an app running
/// > on a Mac device, the value is
/// >
/// <doc
/// ://com.apple.documentation/documentation/swift/false>. This includes
/// > Mac Catalyst apps, and iOS or iPadOS apps running on Apple silicon.
///
/// If you read ``DeviceCheck/DCAppAttestService/supported`` from within an app
/// extension, the value might be
/// <doc
/// ://com.apple.documentation/documentation/swift/true> or
/// <doc
/// ://com.apple.documentation/documentation/swift/false>, depending on
/// the extension type. However, most extensions don’t support App Attest. The
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method
/// fails when you call it from an app extension, regardless of the value of
/// ``DeviceCheck/DCAppAttestService/supported``.
///
/// The only app extensions that support App Attest are watchOS extensions in
/// watchOS 9 or later. For these extensions, you can use the results from
/// ``DeviceCheck/DCAppAttestService/supported`` to indicate whether your
/// WatchKit extension bypasses attestation.
#[unsafe(method(isSupported))]
#[unsafe(method_family = none)]
pub unsafe fn isSupported(&self) -> bool;
#[cfg(feature = "block2")]
/// Creates a new cryptographic key for use with the App Attest service.
///
/// > Concurrency Note: You can call this method from synchronous code using a completion handler,
/// > as shown on this page, or you can call it as an asynchronous method that has the
/// > following declaration:
/// >
/// > ```swift
/// > func generateKey() async throws -> String
/// > ```
/// > For example:
/// > ```swift
/// > let keyIdentifier = try await generateKey()
/// > ```
/// > For information about concurrency and asynchronous code in Swift, see
/// <doc
/// ://com.apple.documentation/documentation/swift/calling-objective-c-apis-asynchronously>.
///
/// Call this method to request the creation of a secure, unattested key pair on
/// a device for a specific user. On success, the method provides your app with
/// an identifier that represents the key pair stored in the Secure Enclave.
/// Because there’s no way to use or retrieve the key without the identifier,
/// you’ll want to either record it in your app or on your server right away. If
/// key generation fails, the closure provides a ``DeviceCheck/DCError-swift.struct`` that
/// indicates the reason for the failure.
///
/// Create a unique key for each user account on a device. Otherwise it’s hard
/// to detect an attack that uses a single compromised device to serve multiple
/// remote users running a compromised version of your app. For more
/// information, see
/// <doc
/// :assessing-fraud-risk>.
///
/// After you get the identifier, you call the
/// ``DeviceCheck/DCAppAttestService/attestKey:clientDataHash:completionHandler:``
/// method with the key identifier to ask Apple to attest to the validity of the
/// associated key. Later, you call the
/// ``DeviceCheck/DCAppAttestService/generateAssertion:clientDataHash:completionHandler:``
/// method with the key identifier to answer a challenge from your server, and
/// establish the legitimacy of this instance of your app.
///
/// - Parameters:
/// - completionHandler: A closure that the method calls upon completion with
/// the following parameters:
/// - `keyId`: An identifier that you use to refer to the key. The framework securely
/// stores the key in the Secure Enclave.
/// - `error`: A ``DeviceCheck/DCError-swift.struct`` instance that indicates the
/// reason for failure, or `nil` on success.
#[unsafe(method(generateKeyWithCompletionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn generateKeyWithCompletionHandler(
&self,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSString, *mut NSError)>,
);
#[cfg(feature = "block2")]
/// Asks Apple to attest to the validity of a generated cryptographic key.
///
/// > Concurrency Note: You can call this method from synchronous code using a completion handler,
/// > as shown on this page, or you can call it as an asynchronous method that has the
/// > following declaration:
/// >
/// > ```swift
/// > func attestKey(_ keyId: String, clientDataHash: Data) async throws -> Data
/// > ```
/// >
/// > For information about concurrency and asynchronous code in Swift, see
/// <doc
/// ://com.apple.documentation/documentation/swift/calling-objective-c-apis-asynchronously>.
///
/// This method asks Apple to attest to the validity of a key that you
/// previously generated with a call to the
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method.
/// Provide the method with both the key identifier and a computed hash of a
/// data block that includes a one-time challenge from your server to prevent
/// replay attacks. For example, you can use CryptoKit to create a
/// <doc
/// ://com.apple.documentation/documentation/cryptokit/sha256> hash of
/// challenge data:
///
/// ```swift
/// import CryptoKit let hash = Data(SHA256.hash(data: challenge)) // A
/// challenge from your server.
/// ```
/// The attest method calls its completion handler to return an attestation
/// object to you, which you must send to your server for verification. A
/// compromised version of your app could falsify the verification result, thus
/// circumventing App Attest.
///
/// If you successfully verify the attestation object on your server, as
/// described in
/// <doc
/// :validating-apps-that-connect-to-your-server>, then you can
/// associate the key identifier with the user on the device for future
/// reference. You’ll need the identifier to generate assertions with calls to
/// ``DeviceCheck/DCAppAttestService/generateAssertion:clientDataHash:completionHandler:``.
/// If your server fails to verify the attestation object, discard the key
/// identifier.
///
/// If the method’s completion handler returns the
/// ``DeviceCheck/DCError-swift.struct/serverUnavailable`` error — typically due to network
/// connectivity issues — it means that the framework failed to reach the App
/// Attest service to complete the attestation. In this case, retry attestation
/// again using the same key and client data hash later to avoid unnecessarily
/// generating new keys. Retrying with the same inputs helps to preserve the
/// risk metric for a given device.
///
/// - Parameters:
/// - keyId: The identifier you received when generating a cryptographic key by
/// calling the
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method.
/// - clientDataHash: A SHA256 hash of a unique, single-use data block that
/// embeds a challenge from your server. Should be at least 16 bytes in length.
/// - completionHandler: A closure that the method calls upon completion with
/// the following parameters:
/// - `attestationObject`: A statement from Apple about the validity of the key
/// associated with `keyId`. Send this to your server for processing.
/// - `error`: A ``DeviceCheck/DCError-swift.struct`` instance that indicates the reason for
/// failure, or `nil` on success.
#[unsafe(method(attestKey:clientDataHash:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn attestKey_clientDataHash_completionHandler(
&self,
key_id: &NSString,
client_data_hash: &NSData,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
);
#[cfg(feature = "block2")]
/// Creates a block of data that demonstrates the legitimacy of an instance of
/// your app running on a device.
///
/// > Concurrency Note: You can call this method from synchronous code using a completion handler,
/// > as shown on this page, or you can call it as an asynchronous method that has the
/// > following declaration:
/// >
/// > ```swift
/// > func generateAssertion(_ keyId: String, clientDataHash: Data) async throws -> Data
/// > ```
/// >
/// > For information about concurrency and asynchronous code in Swift, see
/// <doc
/// ://com.apple.documentation/documentation/swift/calling-objective-c-apis-asynchronously>.
///
/// After generating a key with the
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method
/// and validating it with the
/// ``DeviceCheck/DCAppAttestService/attestKey:clientDataHash:completionHandler:``
/// method, you can use the key at critical moments in your app’s life cycle —
/// like when a user tries to access premium content — to reaffirm the
/// legitimacy of a given instance of your app. Do this by using the
/// ``DeviceCheck/DCAppAttestService/generateAssertion:clientDataHash:completionHandler:``
/// method to sign server requests with your attested key.
///
/// You provide the key identifier and a hash of the request that includes a
/// challenge from your server to prevent replay attacks, where an attacker
/// reuses captured network traffic to pose as someone else. The method returns
/// an assertion object in its completion handler that you send to your server
/// for verification, as described in
/// <doc
/// :establishing-your-app-s-integrity>.
///
/// - Parameters:
/// - keyId: The identifier you received when generating a cryptographic key by
/// calling the
/// ``DeviceCheck/DCAppAttestService/generateKeyWithCompletionHandler:`` method.
/// - clientDataHash: A SHA256 hash of a unique, single-use data block that
/// represents the client data to be signed with the attested private key. Should be at least 16 bytes in length.
/// - completionHandler: A closure that the method calls upon completion with
/// the following parameters:
/// - `assertionObject`: A data structure that you send to your server for processing.
/// - `error` : A ``DeviceCheck/DCError-swift.struct`` instance that indicates the reason for failure, or `nil` on success.
#[unsafe(method(generateAssertion:clientDataHash:completionHandler:))]
#[unsafe(method_family = none)]
pub unsafe fn generateAssertion_clientDataHash_completionHandler(
&self,
key_id: &NSString,
client_data_hash: &NSData,
completion_handler: &block2::DynBlock<dyn Fn(*mut NSData, *mut NSError)>,
);
);
}
/// Methods declared on superclass `NSObject`.
impl DCAppAttestService {
extern_methods!(
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}