@derec-alliance/react-native 0.0.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/DeRec.podspec +25 -0
- package/LICENSE +201 -0
- package/README.md +222 -0
- package/android/CMakeLists.txt +38 -0
- package/android/build.gradle +79 -0
- package/android/src/main/AndroidManifest.xml +12 -0
- package/android/src/main/java/org/derec/DeRecModule.kt +56 -0
- package/android/src/main/java/org/derec/DeRecPackage.kt +24 -0
- package/android/src/main/jni/OnLoad.cpp +39 -0
- package/android/src/main/jniLibs/arm64-v8a/libderec_library.a +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libderec_library.a +0 -0
- package/android/src/main/jniLibs/x86_64/libderec_library.a +0 -0
- package/cpp/Convert.cpp +50 -0
- package/cpp/Convert.h +38 -0
- package/cpp/DeRecInstaller.cpp +186 -0
- package/cpp/DeRecInstaller.h +28 -0
- package/cpp/Invoker.h +20 -0
- package/cpp/JsCallbackBridge.cpp +144 -0
- package/cpp/JsCallbackBridge.h +148 -0
- package/cpp/Primitives.cpp +1193 -0
- package/cpp/Primitives.h +39 -0
- package/cpp/ProtocolHost.cpp +613 -0
- package/cpp/ProtocolHost.h +88 -0
- package/cpp/RuntimeInvoker.h +29 -0
- package/cpp/StoreCallbacks.cpp +1293 -0
- package/cpp/StoreCallbacks.h +111 -0
- package/cpp/WorkerThread.cpp +74 -0
- package/cpp/WorkerThread.h +54 -0
- package/cpp/derec_ffi.h +2145 -0
- package/ios/DeRec.h +23 -0
- package/ios/DeRec.mm +39 -0
- package/ios/DeRecFFI.xcframework/Info.plist +48 -0
- package/ios/DeRecFFI.xcframework/ios-arm64/Headers/derec_ffi.h +2145 -0
- package/ios/DeRecFFI.xcframework/ios-arm64/libderec_library.a +0 -0
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/Headers/derec_ffi.h +2145 -0
- package/ios/DeRecFFI.xcframework/ios-arm64_x86_64-simulator/libderec_library.a +0 -0
- package/lib/binary.d.ts +19 -0
- package/lib/binary.js +164 -0
- package/lib/codec.d.ts +16 -0
- package/lib/codec.js +80 -0
- package/lib/errors.d.ts +23 -0
- package/lib/errors.js +35 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +27 -0
- package/lib/messages.d.ts +41 -0
- package/lib/messages.js +192 -0
- package/lib/native.d.ts +11 -0
- package/lib/native.js +40 -0
- package/lib/primitives.d.ts +137 -0
- package/lib/primitives.js +329 -0
- package/lib/protocol.d.ts +188 -0
- package/lib/protocol.js +514 -0
- package/lib/types.d.ts +1014 -0
- package/lib/types.js +63 -0
- package/package.json +55 -0
- package/react-native.config.js +19 -0
- package/src/binary.ts +182 -0
- package/src/codec.ts +79 -0
- package/src/errors.ts +45 -0
- package/src/index.ts +7 -0
- package/src/messages.ts +192 -0
- package/src/native.ts +52 -0
- package/src/primitives.ts +770 -0
- package/src/protocol.ts +621 -0
- package/src/types.ts +1040 -0
package/cpp/derec_ffi.h
ADDED
|
@@ -0,0 +1,2145 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 DeRec Alliance. All rights reserved.
|
|
3
|
+
//
|
|
4
|
+
// GENERATED FILE - DO NOT EDIT.
|
|
5
|
+
// Regenerate with: scripts/prepare-react-native-package.sh
|
|
6
|
+
|
|
7
|
+
#ifndef DEREC_FFI_H
|
|
8
|
+
#define DEREC_FFI_H
|
|
9
|
+
|
|
10
|
+
#include <stdarg.h>
|
|
11
|
+
#include <stdbool.h>
|
|
12
|
+
#include <stddef.h>
|
|
13
|
+
#include <stdint.h>
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* `share` bytes carry a **full `Secret` payload** (`DeRecSecret` proto)
|
|
18
|
+
* instead of a single VSS share fragment. Used on replica channels —
|
|
19
|
+
* every replica holds an identical copy of the secret rather than a
|
|
20
|
+
* reconstructable fragment of it.
|
|
21
|
+
*
|
|
22
|
+
* Disambiguates the payload semantics on the wire; the receiver's
|
|
23
|
+
* `Channel.peer_role` is the authoritative source of truth, but a distinct
|
|
24
|
+
* `share_algorithm` value lets wire dumps and middle-boxes tell the two
|
|
25
|
+
* payload shapes apart without channel-state context.
|
|
26
|
+
*/
|
|
27
|
+
#define SHARE_ALGORITHM_REPLICA_SECRET 1
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Latest encoding major version, used for all new encodes. Bump only on a
|
|
31
|
+
* breaking format change, adding the matching `vN` module and match arm.
|
|
32
|
+
*/
|
|
33
|
+
#define LATEST 2
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Minimum number of shares required to reconstruct the secret, absent an
|
|
37
|
+
* explicit [`DeRecProtocolBuilder::with_threshold`] call. This is the sole
|
|
38
|
+
* definition of the value — [`DeRecProtocolBuilder::new`] and the FFI
|
|
39
|
+
* config's serde default both read it rather than each hardcoding `3`.
|
|
40
|
+
*/
|
|
41
|
+
#define DEFAULT_THRESHOLD 3
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Number of recent share versions each helper retains, absent an explicit
|
|
45
|
+
* [`DeRecProtocolBuilder::with_keep_versions_count`] call. Sole definition
|
|
46
|
+
* of the value; see [`DEFAULT_THRESHOLD`].
|
|
47
|
+
*/
|
|
48
|
+
#define DEFAULT_KEEP_VERSIONS_COUNT 3
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Maximum accepted transport URI length, in bytes.
|
|
52
|
+
*
|
|
53
|
+
* Matches the de-facto 2048-byte limit most HTTP stacks enforce
|
|
54
|
+
* for request URIs. Pairing payloads embed the URI verbatim, so
|
|
55
|
+
* capping it also bounds the propagated blob size.
|
|
56
|
+
*/
|
|
57
|
+
#define MAX_TRANSPORT_URI_LEN 2048
|
|
58
|
+
|
|
59
|
+
#define DEREC_CATEGORY_OK 0
|
|
60
|
+
|
|
61
|
+
#define DEREC_CATEGORY_FFI 1
|
|
62
|
+
|
|
63
|
+
#define DEREC_CATEGORY_PAIRING 2
|
|
64
|
+
|
|
65
|
+
#define DEREC_CATEGORY_SHARING 3
|
|
66
|
+
|
|
67
|
+
#define DEREC_CATEGORY_RECOVERY 4
|
|
68
|
+
|
|
69
|
+
#define DEREC_CATEGORY_VERIFICATION 5
|
|
70
|
+
|
|
71
|
+
#define DEREC_CATEGORY_DISCOVERY 6
|
|
72
|
+
|
|
73
|
+
#define DEREC_CATEGORY_UNPAIRING 7
|
|
74
|
+
|
|
75
|
+
#define DEREC_CATEGORY_DEREC_MESSAGE 8
|
|
76
|
+
|
|
77
|
+
#define DEREC_CATEGORY_SECRET_STORE 9
|
|
78
|
+
|
|
79
|
+
#define DEREC_CATEGORY_CHANNEL_STORE 10
|
|
80
|
+
|
|
81
|
+
#define DEREC_CATEGORY_SHARE_STORE 11
|
|
82
|
+
|
|
83
|
+
#define DEREC_CATEGORY_INVALID_INPUT 12
|
|
84
|
+
|
|
85
|
+
#define DEREC_CATEGORY_PROTOBUF 13
|
|
86
|
+
|
|
87
|
+
#define DEREC_CATEGORY_INVARIANT 14
|
|
88
|
+
|
|
89
|
+
#define DEREC_CATEGORY_STATE_STORE 15
|
|
90
|
+
|
|
91
|
+
#define DEREC_CODE_OK 0
|
|
92
|
+
|
|
93
|
+
#define DEREC_CODE_NON_OK_STATUS 1
|
|
94
|
+
|
|
95
|
+
#define DEREC_CODE_VERSION_MISMATCH 2
|
|
96
|
+
|
|
97
|
+
#define DEREC_CODE_INVARIANT 3
|
|
98
|
+
|
|
99
|
+
#define DEREC_CODE_INVALID_INPUT 4
|
|
100
|
+
|
|
101
|
+
#define DEREC_CODE_PROTOBUF_DECODE 5
|
|
102
|
+
|
|
103
|
+
#define DEREC_CODE_PROTOBUF_ENCODE 6
|
|
104
|
+
|
|
105
|
+
#define DEREC_CODE_PROTOCOL_VIOLATION 7
|
|
106
|
+
|
|
107
|
+
#define DEREC_CODE_STORE_ERROR 8
|
|
108
|
+
|
|
109
|
+
#define DEREC_CODE_BUILDER_ERROR 9
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* `SecretStore::load_many(.., MissingPolicy::Fail)` returned because one or
|
|
113
|
+
* more channels had no `SharedKey` entry. The formatted `message` carries
|
|
114
|
+
* the missing channel ids (e.g. `"secret store: missing SharedKey entries
|
|
115
|
+
* for channel(s): [42, 7]"`). `category` is
|
|
116
|
+
* [`DEREC_CATEGORY_SECRET_STORE`].
|
|
117
|
+
*/
|
|
118
|
+
#define DEREC_CODE_MISSING_SHARED_KEY 10
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Flow or inbound message attempted against a channel where this node holds
|
|
122
|
+
* the wrong [`derec_proto::SenderKind`]. Surfaced as
|
|
123
|
+
* [`DEREC_CATEGORY_INVALID_INPUT`].
|
|
124
|
+
*/
|
|
125
|
+
#define DEREC_CODE_ROLE_MISMATCH 11
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The protocol was constructed without `with_replica_id(..)` but a
|
|
129
|
+
* replica-mode flow was attempted. Returned by every entry point that
|
|
130
|
+
* requires local replica identity. `DEREC_CATEGORY_INVALID_INPUT`.
|
|
131
|
+
*/
|
|
132
|
+
#define DEREC_CODE_REPLICA_ID_NOT_CONFIGURED 12
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* `start(Pairing)` was called for a `channel_id` that already has a
|
|
136
|
+
* `Paired` channel record. Returned by both the inline-keys and
|
|
137
|
+
* hashed-keys branches of `start`. `DEREC_CATEGORY_INVALID_INPUT`.
|
|
138
|
+
*/
|
|
139
|
+
#define DEREC_CODE_CHANNEL_ALREADY_PAIRED 13
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* `derec_protocol_restore` precondition: a `UserSecrets` snapshot
|
|
143
|
+
* already exists for the protocol's `secret_id`. The application must
|
|
144
|
+
* clear it before retrying. `DEREC_CATEGORY_INVALID_INPUT`.
|
|
145
|
+
*/
|
|
146
|
+
#define DEREC_CODE_ALREADY_RESTORED 14
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* `derec_protocol_restore` precondition: one or more channels live at
|
|
150
|
+
* canonical helper / replica ids carried by the recovered `Secret`.
|
|
151
|
+
* `DeRecError::message` formats the collision list as
|
|
152
|
+
* `"restore conflict: channel(s) [a, b, ...]"`.
|
|
153
|
+
* `DEREC_CATEGORY_INVALID_INPUT`.
|
|
154
|
+
*/
|
|
155
|
+
#define DEREC_CODE_RESTORE_CONFLICT 15
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* A replica pairing named a `replica_id` already held by another member of
|
|
159
|
+
* the group, this device included. Assignment is the application's, so this
|
|
160
|
+
* is a configuration fault: assign a distinct id and pair again.
|
|
161
|
+
* `DEREC_CATEGORY_INVALID_INPUT`.
|
|
162
|
+
*/
|
|
163
|
+
#define DEREC_CODE_REPLICA_ID_CONFLICT 16
|
|
164
|
+
|
|
165
|
+
#define DEREC_CODE_ENCRYPTION 20
|
|
166
|
+
|
|
167
|
+
#define DEREC_CODE_KEYGEN 21
|
|
168
|
+
|
|
169
|
+
#define DEREC_CODE_FINISH_PAIRING_INITIATOR 22
|
|
170
|
+
|
|
171
|
+
#define DEREC_CODE_FINISH_PAIRING_RESPONDER 23
|
|
172
|
+
|
|
173
|
+
#define DEREC_CODE_EMPTY_TRANSPORT_URI 40
|
|
174
|
+
|
|
175
|
+
#define DEREC_CODE_INVALID_CONTACT_MESSAGE 41
|
|
176
|
+
|
|
177
|
+
#define DEREC_CODE_INVALID_PAIR_REQUEST_MESSAGE 42
|
|
178
|
+
|
|
179
|
+
#define DEREC_CODE_INVALID_PAIR_RESPONSE_MESSAGE 43
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* `HashedKeys` pairing — the scanner recomputed the SHA-384 binding hash
|
|
183
|
+
* over the public keys published in `PrePairResponseMessage` and got a
|
|
184
|
+
* digest that doesn't match `ContactMessage.contactBindingHash`. Surfaced
|
|
185
|
+
* as [`DEREC_CATEGORY_PAIRING`]. Distinct from a generic
|
|
186
|
+
* [`DEREC_CODE_PROTOCOL_VIOLATION`] so applications can flag this with
|
|
187
|
+
* the security-relevant framing it deserves (the contact the user
|
|
188
|
+
* scanned does not match the keys they would pair with).
|
|
189
|
+
*/
|
|
190
|
+
#define DEREC_CODE_PREPAIR_HASH_MISMATCH 44
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* A replica-mode pairing arrived without the reserved
|
|
194
|
+
* `derec.replica_id` key in `CommunicationInfo`.
|
|
195
|
+
* `DEREC_CATEGORY_PAIRING`.
|
|
196
|
+
*/
|
|
197
|
+
#define DEREC_CODE_MISSING_REPLICA_ID 45
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* A non-replica pairing carried the reserved `derec.replica_id` key in
|
|
201
|
+
* `CommunicationInfo`. `DEREC_CATEGORY_PAIRING`.
|
|
202
|
+
*/
|
|
203
|
+
#define DEREC_CODE_UNEXPECTED_REPLICA_ID 46
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The peer's [`derec_proto::ParameterRange`] does not overlap the
|
|
207
|
+
* locally-configured one on some field (e.g. `local.minShareSize >
|
|
208
|
+
* peer.maxShareSize`). `DEREC_CATEGORY_PAIRING`. The
|
|
209
|
+
* [`DeRecError::message`](DeRecError) carries the field name and
|
|
210
|
+
* both `(min, max)` pairs.
|
|
211
|
+
*/
|
|
212
|
+
#define DEREC_CODE_INCOMPATIBLE_PARAMETER_RANGE 47
|
|
213
|
+
|
|
214
|
+
#define DEREC_CODE_EMPTY_CHANNELS 60
|
|
215
|
+
|
|
216
|
+
#define DEREC_CODE_DUPLICATE_CHANNEL_ID 61
|
|
217
|
+
|
|
218
|
+
#define DEREC_CODE_INVALID_THRESHOLD 62
|
|
219
|
+
|
|
220
|
+
#define DEREC_CODE_EMPTY_SECRET_DATA 63
|
|
221
|
+
|
|
222
|
+
#define DEREC_CODE_VSS_SHARE_FAILED 64
|
|
223
|
+
|
|
224
|
+
#define DEREC_CODE_EMPTY_RESPONSES 80
|
|
225
|
+
|
|
226
|
+
#define DEREC_CODE_EMPTY_COMMITTED_DEREC_SHARE 81
|
|
227
|
+
|
|
228
|
+
#define DEREC_CODE_DECODE_COMMITTED_DEREC_SHARE 82
|
|
229
|
+
|
|
230
|
+
#define DEREC_CODE_DECODE_DEREC_SHARE 83
|
|
231
|
+
|
|
232
|
+
#define DEREC_CODE_SECRET_ID_MISMATCH 84
|
|
233
|
+
|
|
234
|
+
#define DEREC_CODE_RECONSTRUCTION_FAILED 85
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* VSS reconstruction succeeded but the resulting bytes did not decode as
|
|
238
|
+
* the canonical `DeRecSecret` / `Secret` protobuf. Almost always a sign
|
|
239
|
+
* of share corruption.
|
|
240
|
+
*/
|
|
241
|
+
#define DEREC_CODE_MALFORMED_RECOVERED_SECRET 86
|
|
242
|
+
|
|
243
|
+
#define DEREC_CODE_FFI_NULL_PTR 100
|
|
244
|
+
|
|
245
|
+
#define DEREC_CODE_FFI_BAD_LENGTH 101
|
|
246
|
+
|
|
247
|
+
#define DEREC_CODE_FFI_BAD_UTF8 102
|
|
248
|
+
|
|
249
|
+
#define DEREC_CODE_FFI_BAD_PROTO 103
|
|
250
|
+
|
|
251
|
+
#define DEREC_CODE_FFI_INVALID_ENUM 104
|
|
252
|
+
|
|
253
|
+
#define DEREC_CODE_FFI_BAD_SHARED_KEY 105
|
|
254
|
+
|
|
255
|
+
#define DEREC_CODE_FFI_NUL_IN_STRING 106
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Transport URI/protocol pair failed [`crate::transport::validate`]:
|
|
259
|
+
* length cap, control character, unknown protocol discriminant, or
|
|
260
|
+
* URI scheme that doesn't match the declared `Protocol`. Surfaced
|
|
261
|
+
* as [`DEREC_CATEGORY_INVALID_INPUT`]. The
|
|
262
|
+
* [`DeRecError::message`](DeRecError) carries the specific reason.
|
|
263
|
+
*/
|
|
264
|
+
#define DEREC_CODE_TRANSPORT_INVALID 120
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Discriminants selecting which message [`derec_decode_message_json`] and
|
|
268
|
+
* [`derec_encode_message_json`] operate on.
|
|
269
|
+
*
|
|
270
|
+
* Mirrored in `bindings/test_fixture/enums.json`, which every SDK asserts
|
|
271
|
+
* against, so a message added here cannot reach a binding as a silently
|
|
272
|
+
* unhandled value.
|
|
273
|
+
*/
|
|
274
|
+
#define DEREC_MESSAGE_KIND_PAIR_REQUEST 0
|
|
275
|
+
|
|
276
|
+
#define DEREC_MESSAGE_KIND_PAIR_RESPONSE 1
|
|
277
|
+
|
|
278
|
+
#define DEREC_MESSAGE_KIND_PRE_PAIR_REQUEST 2
|
|
279
|
+
|
|
280
|
+
#define DEREC_MESSAGE_KIND_PRE_PAIR_RESPONSE 3
|
|
281
|
+
|
|
282
|
+
#define DEREC_MESSAGE_KIND_GET_SECRET_IDS_VERSIONS_REQUEST 4
|
|
283
|
+
|
|
284
|
+
#define DEREC_MESSAGE_KIND_GET_SECRET_IDS_VERSIONS_RESPONSE 5
|
|
285
|
+
|
|
286
|
+
#define DEREC_MESSAGE_KIND_GET_SHARE_REQUEST 6
|
|
287
|
+
|
|
288
|
+
#define DEREC_MESSAGE_KIND_GET_SHARE_RESPONSE 7
|
|
289
|
+
|
|
290
|
+
#define DEREC_MESSAGE_KIND_STORE_SHARE_REQUEST 8
|
|
291
|
+
|
|
292
|
+
#define DEREC_MESSAGE_KIND_STORE_SHARE_RESPONSE 9
|
|
293
|
+
|
|
294
|
+
#define DEREC_MESSAGE_KIND_UNPAIR_REQUEST 10
|
|
295
|
+
|
|
296
|
+
#define DEREC_MESSAGE_KIND_UNPAIR_RESPONSE 11
|
|
297
|
+
|
|
298
|
+
#define DEREC_MESSAGE_KIND_VERIFY_SHARE_REQUEST 12
|
|
299
|
+
|
|
300
|
+
#define DEREC_MESSAGE_KIND_VERIFY_SHARE_RESPONSE 13
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Not a standalone message on the wire, but it crosses this FFI on its own
|
|
304
|
+
* as the `transport_protocol` argument of `create_contact_message` and the
|
|
305
|
+
* `peer_transport_protocol` result of `produce_pair_response_message`.
|
|
306
|
+
*/
|
|
307
|
+
#define DEREC_MESSAGE_KIND_TRANSPORT_PROTOCOL 14
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Crosses on its own as the `communication_info` argument of the pairing
|
|
311
|
+
* produce calls. See [`DEREC_MESSAGE_KIND_TRANSPORT_PROTOCOL`].
|
|
312
|
+
*/
|
|
313
|
+
#define DEREC_MESSAGE_KIND_COMMUNICATION_INFO 15
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Crosses on its own as the `parameter_range` argument of the pairing
|
|
317
|
+
* produce calls. See [`DEREC_MESSAGE_KIND_TRANSPORT_PROTOCOL`].
|
|
318
|
+
*/
|
|
319
|
+
#define DEREC_MESSAGE_KIND_PARAMETER_RANGE 16
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Crosses on its own as the `committed_share` argument of
|
|
323
|
+
* `produce_store_share_request_message` and as the `committed_share_bytes`
|
|
324
|
+
* result of `produce_store_share_response_message`.
|
|
325
|
+
*/
|
|
326
|
+
#define DEREC_MESSAGE_KIND_COMMITTED_DEREC_SHARE 17
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Numeric flow-kind identifiers — must match the dotnet `FlowKind` enum.
|
|
330
|
+
*/
|
|
331
|
+
#define FLOW_KIND_PAIRING 0
|
|
332
|
+
|
|
333
|
+
#define FLOW_KIND_DISCOVERY 1
|
|
334
|
+
|
|
335
|
+
#define FLOW_KIND_PROTECT_SECRET 2
|
|
336
|
+
|
|
337
|
+
#define FLOW_KIND_VERIFY_SHARES 3
|
|
338
|
+
|
|
339
|
+
#define FLOW_KIND_RECOVER_SECRET 4
|
|
340
|
+
|
|
341
|
+
#define FLOW_KIND_UNPAIR 5
|
|
342
|
+
|
|
343
|
+
#define FLOW_KIND_UPDATE_CHANNEL_INFO 6
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Replica catch-up. Takes no parameters: the group and this device's own
|
|
347
|
+
* version are both read from the stores.
|
|
348
|
+
*/
|
|
349
|
+
#define FLOW_KIND_SYNC_CHECK 7
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Remove a member from the replica group. Params:
|
|
353
|
+
* `{ "replica_id": "<decimal>", "memo": "<optional>" }`.
|
|
354
|
+
*/
|
|
355
|
+
#define FLOW_KIND_REMOVE_REPLICA 8
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Opaque handle returned by [`derec_protocol_new`] and consumed by
|
|
359
|
+
* every other entry point in this module. Holds the protocol instance + the
|
|
360
|
+
* per-handle tokio runtime used to drive the async core synchronously.
|
|
361
|
+
*
|
|
362
|
+
* The `inner` protocol is wrapped in [`std::sync::Mutex`] so concurrent
|
|
363
|
+
* FFI calls from different host threads (.NET worker pool, Node.js
|
|
364
|
+
* worker_threads, etc.) are safe by construction. Each entry point
|
|
365
|
+
* locks the mutex for the duration of its call, serializing access to
|
|
366
|
+
* the protocol state — no `&mut DeRecProtocolHandle` is ever
|
|
367
|
+
* materialized, so aliased `&mut` references (which would be immediate
|
|
368
|
+
* undefined behavior) cannot arise even under contention. The tokio
|
|
369
|
+
* `Runtime` itself is `Sync` and accepts `&self` `block_on`, but
|
|
370
|
+
* holding the protocol lock across `block_on` also serializes runtime
|
|
371
|
+
* invocations on the current-thread executor.
|
|
372
|
+
*/
|
|
373
|
+
typedef struct DeRecProtocolHandle DeRecProtocolHandle;
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* DeRec protocol version supported by this SDK.
|
|
377
|
+
*
|
|
378
|
+
* This type represents the protocol-level version carried in the
|
|
379
|
+
* [`DeRecMessage`](derec_proto::DeRecMessage) envelope:
|
|
380
|
+
*
|
|
381
|
+
* - `protocolVersionMajor`
|
|
382
|
+
* - `protocolVersionMinor`
|
|
383
|
+
*
|
|
384
|
+
* This is **not** the same as the Rust crate version, npm package version,
|
|
385
|
+
* or NuGet package version. Package versions identify SDK releases, while
|
|
386
|
+
* `ProtocolVersion` identifies the DeRec wire protocol version expected by
|
|
387
|
+
* protocol messages.
|
|
388
|
+
*
|
|
389
|
+
* # Fields
|
|
390
|
+
*
|
|
391
|
+
* * `major` - Protocol major version.
|
|
392
|
+
* * `minor` - Protocol minor version.
|
|
393
|
+
*
|
|
394
|
+
* # Compatibility
|
|
395
|
+
*
|
|
396
|
+
* The compatibility policy associated with protocol major/minor versions is
|
|
397
|
+
* defined by the DeRec protocol specification, not by this helper type.
|
|
398
|
+
*
|
|
399
|
+
* # Example
|
|
400
|
+
*
|
|
401
|
+
* ```rust
|
|
402
|
+
* use derec_library::protocol_version::ProtocolVersion;
|
|
403
|
+
*
|
|
404
|
+
* let version = ProtocolVersion::current();
|
|
405
|
+
*
|
|
406
|
+
* assert!(version.major >= 0);
|
|
407
|
+
* assert!(version.minor >= 0);
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
410
|
+
typedef struct ProtocolVersion ProtocolVersion;
|
|
411
|
+
|
|
412
|
+
typedef struct DeRecError {
|
|
413
|
+
int32_t category;
|
|
414
|
+
int32_t code;
|
|
415
|
+
/**
|
|
416
|
+
* Owned C string. Null on success. Released by [`derec_free_error`].
|
|
417
|
+
*/
|
|
418
|
+
char *message;
|
|
419
|
+
/**
|
|
420
|
+
* Valid when `code == DEREC_CODE_NON_OK_STATUS`.
|
|
421
|
+
*/
|
|
422
|
+
int32_t peer_status;
|
|
423
|
+
/**
|
|
424
|
+
* Owned C string. Null when not applicable. Released by [`derec_free_error`].
|
|
425
|
+
*/
|
|
426
|
+
char *peer_memo;
|
|
427
|
+
/**
|
|
428
|
+
* Valid when `code == DEREC_CODE_VERSION_MISMATCH`.
|
|
429
|
+
*/
|
|
430
|
+
uint32_t expected;
|
|
431
|
+
/**
|
|
432
|
+
* Valid when `code == DEREC_CODE_VERSION_MISMATCH`.
|
|
433
|
+
*/
|
|
434
|
+
uint32_t got;
|
|
435
|
+
} DeRecError;
|
|
436
|
+
|
|
437
|
+
typedef struct DeRecBuffer {
|
|
438
|
+
uint8_t *ptr;
|
|
439
|
+
size_t len;
|
|
440
|
+
} DeRecBuffer;
|
|
441
|
+
|
|
442
|
+
typedef struct ProduceGetSecretIdsVersionsRequestMessageResult {
|
|
443
|
+
struct DeRecError error;
|
|
444
|
+
struct DeRecBuffer envelope_wire_bytes;
|
|
445
|
+
} ProduceGetSecretIdsVersionsRequestMessageResult;
|
|
446
|
+
|
|
447
|
+
typedef struct ExtractGetSecretIdsVersionsRequestResult {
|
|
448
|
+
struct DeRecError error;
|
|
449
|
+
uint64_t channel_id;
|
|
450
|
+
/**
|
|
451
|
+
* prost-encoded inner `GetSecretIdsVersionsRequestMessage` bytes.
|
|
452
|
+
* Empty buffer when extraction fails. SDK consumers decode this
|
|
453
|
+
* to inspect optional fields such as `reply_to`.
|
|
454
|
+
*/
|
|
455
|
+
struct DeRecBuffer request_proto_bytes;
|
|
456
|
+
} ExtractGetSecretIdsVersionsRequestResult;
|
|
457
|
+
|
|
458
|
+
typedef struct ProduceGetSecretIdsVersionsResponseMessageResult {
|
|
459
|
+
struct DeRecError error;
|
|
460
|
+
struct DeRecBuffer envelope_wire_bytes;
|
|
461
|
+
} ProduceGetSecretIdsVersionsResponseMessageResult;
|
|
462
|
+
|
|
463
|
+
typedef struct ExtractGetSecretIdsVersionsResponseResult {
|
|
464
|
+
struct DeRecError error;
|
|
465
|
+
uint64_t channel_id;
|
|
466
|
+
/**
|
|
467
|
+
* Inner `GetSecretIdsVersionsResponseMessage` proto bytes for chaining
|
|
468
|
+
* into [`process_get_secret_ids_versions_response_message`].
|
|
469
|
+
*/
|
|
470
|
+
struct DeRecBuffer response_proto_bytes;
|
|
471
|
+
} ExtractGetSecretIdsVersionsResponseResult;
|
|
472
|
+
|
|
473
|
+
typedef struct ProcessGetSecretIdsVersionsResponseMessageResult {
|
|
474
|
+
struct DeRecError error;
|
|
475
|
+
/**
|
|
476
|
+
* Validated secret list in the format documented at the module level.
|
|
477
|
+
*/
|
|
478
|
+
struct DeRecBuffer secret_list_bytes;
|
|
479
|
+
} ProcessGetSecretIdsVersionsResponseMessageResult;
|
|
480
|
+
|
|
481
|
+
typedef struct ApplyTraceIdResult {
|
|
482
|
+
struct DeRecError error;
|
|
483
|
+
/**
|
|
484
|
+
* Re-encoded envelope bytes with `trace_id` overwritten. Empty on error.
|
|
485
|
+
*/
|
|
486
|
+
struct DeRecBuffer wire_bytes;
|
|
487
|
+
} ApplyTraceIdResult;
|
|
488
|
+
|
|
489
|
+
typedef struct ReadTraceIdResult {
|
|
490
|
+
struct DeRecError error;
|
|
491
|
+
/**
|
|
492
|
+
* Trace id read off the envelope. Zero on error (also zero if the
|
|
493
|
+
* sender did not set one — the protobuf default is indistinguishable).
|
|
494
|
+
*/
|
|
495
|
+
uint64_t trace_id;
|
|
496
|
+
} ReadTraceIdResult;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Result of a message JSON codec call. `bytes` is UTF-8 JSON for
|
|
500
|
+
* [`derec_decode_message_json`] and protobuf wire bytes for
|
|
501
|
+
* [`derec_encode_message_json`]; it is empty when `error` is non-zero.
|
|
502
|
+
*/
|
|
503
|
+
typedef struct DeRecMessageJsonResult {
|
|
504
|
+
struct DeRecError error;
|
|
505
|
+
struct DeRecBuffer bytes;
|
|
506
|
+
} DeRecMessageJsonResult;
|
|
507
|
+
|
|
508
|
+
typedef struct CreateContactMessageResult {
|
|
509
|
+
struct DeRecError error;
|
|
510
|
+
struct DeRecBuffer contact_wire_bytes;
|
|
511
|
+
/**
|
|
512
|
+
* Opaque pairing secret key material. See module docs.
|
|
513
|
+
*/
|
|
514
|
+
struct DeRecBuffer secret_key_material;
|
|
515
|
+
} CreateContactMessageResult;
|
|
516
|
+
|
|
517
|
+
typedef struct EncodeContactMessageResult {
|
|
518
|
+
struct DeRecError error;
|
|
519
|
+
/**
|
|
520
|
+
* Proto-encoded `ContactMessage`, ready to publish out of band.
|
|
521
|
+
*/
|
|
522
|
+
struct DeRecBuffer wire_bytes;
|
|
523
|
+
} EncodeContactMessageResult;
|
|
524
|
+
|
|
525
|
+
typedef struct DecodeContactMessageResult {
|
|
526
|
+
struct DeRecError error;
|
|
527
|
+
/**
|
|
528
|
+
* UTF-8 JSON object. See [`encode_contact_message`] for the shape.
|
|
529
|
+
*/
|
|
530
|
+
struct DeRecBuffer contact_json;
|
|
531
|
+
} DecodeContactMessageResult;
|
|
532
|
+
|
|
533
|
+
typedef struct ProducePairRequestMessageResult {
|
|
534
|
+
struct DeRecError error;
|
|
535
|
+
struct DeRecBuffer request_wire_bytes;
|
|
536
|
+
struct DeRecBuffer initiator_contact_message_wire_bytes;
|
|
537
|
+
/**
|
|
538
|
+
* Opaque pairing secret key material. See module docs.
|
|
539
|
+
*/
|
|
540
|
+
struct DeRecBuffer secret_key_material;
|
|
541
|
+
} ProducePairRequestMessageResult;
|
|
542
|
+
|
|
543
|
+
typedef struct ExtractPairRequestResult {
|
|
544
|
+
struct DeRecError error;
|
|
545
|
+
uint64_t channel_id;
|
|
546
|
+
/**
|
|
547
|
+
* Inner `PairRequestMessage` proto bytes for chaining into
|
|
548
|
+
* [`produce_pair_response_message`].
|
|
549
|
+
*/
|
|
550
|
+
struct DeRecBuffer request_proto_bytes;
|
|
551
|
+
} ExtractPairRequestResult;
|
|
552
|
+
|
|
553
|
+
typedef struct ProducePairResponseMessageResult {
|
|
554
|
+
struct DeRecError error;
|
|
555
|
+
struct DeRecBuffer response_wire_bytes;
|
|
556
|
+
struct DeRecBuffer peer_transport_protocol;
|
|
557
|
+
struct DeRecBuffer shared_key;
|
|
558
|
+
/**
|
|
559
|
+
* Post-handshake rekey channel id the responder is committing to.
|
|
560
|
+
* Callers MUST atomically rename their local channel record from the
|
|
561
|
+
* pre-rekey id (the one passed to `produce_pair_response_message`) to
|
|
562
|
+
* this value as part of accepting the response. Zero on error.
|
|
563
|
+
*/
|
|
564
|
+
uint64_t channel_id;
|
|
565
|
+
} ProducePairResponseMessageResult;
|
|
566
|
+
|
|
567
|
+
typedef struct ExtractPairResponseResult {
|
|
568
|
+
struct DeRecError error;
|
|
569
|
+
uint64_t channel_id;
|
|
570
|
+
/**
|
|
571
|
+
* Inner `PairResponseMessage` proto bytes for chaining into
|
|
572
|
+
* [`process_pair_response_message`].
|
|
573
|
+
*/
|
|
574
|
+
struct DeRecBuffer response_proto_bytes;
|
|
575
|
+
} ExtractPairResponseResult;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* `shared_key` is populated only on success; empty on peer rejection (see
|
|
579
|
+
* [`crate::interop::ffi::error`]).
|
|
580
|
+
*/
|
|
581
|
+
typedef struct ProcessPairResponseMessageResult {
|
|
582
|
+
struct DeRecError error;
|
|
583
|
+
struct DeRecBuffer shared_key;
|
|
584
|
+
/**
|
|
585
|
+
* Post-handshake rekey channel id — already validated against the
|
|
586
|
+
* caller's own derivation. Callers MUST atomically rename their local
|
|
587
|
+
* channel record from the pre-rekey id (the one in the contact) to
|
|
588
|
+
* this value. Zero on error.
|
|
589
|
+
*/
|
|
590
|
+
uint64_t channel_id;
|
|
591
|
+
} ProcessPairResponseMessageResult;
|
|
592
|
+
|
|
593
|
+
typedef struct ProducePrePairRequestMessageResult {
|
|
594
|
+
struct DeRecError error;
|
|
595
|
+
/**
|
|
596
|
+
* Serialized outer plaintext `DeRecMessage` envelope carrying a
|
|
597
|
+
* `PrePairRequestMessage`. Ready to send over transport.
|
|
598
|
+
*/
|
|
599
|
+
struct DeRecBuffer envelope_wire_bytes;
|
|
600
|
+
} ProducePrePairRequestMessageResult;
|
|
601
|
+
|
|
602
|
+
typedef struct ExtractPrePairRequestResult {
|
|
603
|
+
struct DeRecError error;
|
|
604
|
+
/**
|
|
605
|
+
* Channel identifier decoded from the outer envelope's routing field.
|
|
606
|
+
*/
|
|
607
|
+
uint64_t channel_id;
|
|
608
|
+
/**
|
|
609
|
+
* Inner `PrePairRequestMessage` proto bytes for chaining into
|
|
610
|
+
* [`produce_pre_pair_response_message`].
|
|
611
|
+
*/
|
|
612
|
+
struct DeRecBuffer request_proto_bytes;
|
|
613
|
+
} ExtractPrePairRequestResult;
|
|
614
|
+
|
|
615
|
+
typedef struct ProducePrePairResponseMessageResult {
|
|
616
|
+
struct DeRecError error;
|
|
617
|
+
/**
|
|
618
|
+
* Serialized outer plaintext `DeRecMessage` envelope carrying a
|
|
619
|
+
* `PrePairResponseMessage`. Ready to send over transport.
|
|
620
|
+
*/
|
|
621
|
+
struct DeRecBuffer envelope_wire_bytes;
|
|
622
|
+
} ProducePrePairResponseMessageResult;
|
|
623
|
+
|
|
624
|
+
typedef struct ExtractPrePairResponseResult {
|
|
625
|
+
struct DeRecError error;
|
|
626
|
+
/**
|
|
627
|
+
* Channel identifier decoded from the outer envelope's routing field.
|
|
628
|
+
*/
|
|
629
|
+
uint64_t channel_id;
|
|
630
|
+
/**
|
|
631
|
+
* Inner `PrePairResponseMessage` proto bytes for chaining into
|
|
632
|
+
* [`process_pre_pair_response_message`].
|
|
633
|
+
*/
|
|
634
|
+
struct DeRecBuffer response_proto_bytes;
|
|
635
|
+
} ExtractPrePairResponseResult;
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* On success the two key buffers hold the validated public keys republished
|
|
639
|
+
* by the contact creator. On failure (status non-Ok, hash mismatch, etc.)
|
|
640
|
+
* both buffers are empty; consult `error`.
|
|
641
|
+
*/
|
|
642
|
+
typedef struct ProcessPrePairResponseMessageResult {
|
|
643
|
+
struct DeRecError error;
|
|
644
|
+
struct DeRecBuffer mlkem_encapsulation_key;
|
|
645
|
+
struct DeRecBuffer ecies_public_key;
|
|
646
|
+
/**
|
|
647
|
+
* Nonce echoed from the original `ContactMessage`. Zero on failure.
|
|
648
|
+
*/
|
|
649
|
+
uint64_t nonce;
|
|
650
|
+
} ProcessPrePairResponseMessageResult;
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Result type for [`derec_protocol_new`].
|
|
654
|
+
*/
|
|
655
|
+
typedef struct DeRecProtocolNewResult {
|
|
656
|
+
struct DeRecError error;
|
|
657
|
+
/**
|
|
658
|
+
* On success, the opaque handle. On error, null.
|
|
659
|
+
*/
|
|
660
|
+
struct DeRecProtocolHandle *handle;
|
|
661
|
+
} DeRecProtocolNewResult;
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Caller-supplied callbacks for channel persistence.
|
|
665
|
+
*
|
|
666
|
+
* All function pointers are invoked synchronously from the protocol's
|
|
667
|
+
* async core (the FFI shim drives futures with `block_on`). Buffer
|
|
668
|
+
* ownership for any byte payload returned via out-parameters belongs
|
|
669
|
+
* to the caller; the shim copies into a Rust `Vec` and then calls
|
|
670
|
+
* [`Self::free_buffer`] to release the original allocation.
|
|
671
|
+
*
|
|
672
|
+
* Return code convention:
|
|
673
|
+
* - `0` on success
|
|
674
|
+
* - `1` on "not found" (only meaningful for `load`)
|
|
675
|
+
* - any other value indicates a backend failure; the shim wraps it as
|
|
676
|
+
* [`ChannelStoreError::Backend`]
|
|
677
|
+
*
|
|
678
|
+
* # Addressing a record
|
|
679
|
+
*
|
|
680
|
+
* `load`, `save` and `remove` take a `(channel_id, replica_id)` pair. A
|
|
681
|
+
* `replica_id` of `0` — the value [`crate::types::ReplicaId`] reserves as
|
|
682
|
+
* "absent" — addresses the helper channel at `channel_id`.
|
|
683
|
+
*
|
|
684
|
+
* Any other value addresses that member of the replica group, and the member
|
|
685
|
+
* is keyed by **`replica_id` alone**. The accompanying `channel_id` is
|
|
686
|
+
* context, not part of the key: a member moves between channels during an
|
|
687
|
+
* admission handover while remaining the same member, and a lookup that
|
|
688
|
+
* required both to match would miss it exactly when the move needs to be
|
|
689
|
+
* observed. Backends therefore keep two maps — helpers by `channel_id`,
|
|
690
|
+
* members by `replica_id` — not one keyed by the pair.
|
|
691
|
+
*
|
|
692
|
+
* The `bytes` payload of `save`, and the buffer `load` returns, are a
|
|
693
|
+
* JSON-encoded [`crate::protocol::types::ChannelRecord`]. `list_helpers` and
|
|
694
|
+
* `list_replicas` return a JSON array of
|
|
695
|
+
* [`crate::protocol::types::HelperChannel`] and
|
|
696
|
+
* [`crate::protocol::types::ReplicaMember`] respectively.
|
|
697
|
+
*
|
|
698
|
+
* The order `list_replicas` returns is significant in exactly one situation —
|
|
699
|
+
* it selects the successor when the group's source is removed. See
|
|
700
|
+
* [`crate::protocol::DeRecChannelStore::replicas`] for the full contract.
|
|
701
|
+
*/
|
|
702
|
+
typedef struct ChannelStoreCallbacks {
|
|
703
|
+
void *user_data;
|
|
704
|
+
int32_t (*load)(void *user_data,
|
|
705
|
+
uint64_t secret_id,
|
|
706
|
+
uint64_t channel_id,
|
|
707
|
+
uint64_t replica_id,
|
|
708
|
+
uint8_t **out_ptr,
|
|
709
|
+
size_t *out_len);
|
|
710
|
+
int32_t (*save)(void *user_data,
|
|
711
|
+
uint64_t secret_id,
|
|
712
|
+
uint64_t channel_id,
|
|
713
|
+
uint64_t replica_id,
|
|
714
|
+
const uint8_t *bytes,
|
|
715
|
+
size_t len);
|
|
716
|
+
int32_t (*remove)(void *user_data,
|
|
717
|
+
uint64_t secret_id,
|
|
718
|
+
uint64_t channel_id,
|
|
719
|
+
uint64_t replica_id,
|
|
720
|
+
uint32_t *out_existed);
|
|
721
|
+
int32_t (*list_helpers)(void *user_data, uint64_t secret_id, uint8_t **out_ptr, size_t *out_len);
|
|
722
|
+
int32_t (*list_replicas)(void *user_data, uint64_t secret_id, uint8_t **out_ptr, size_t *out_len);
|
|
723
|
+
int32_t (*link_channel)(void *user_data, uint64_t secret_id, uint64_t a, uint64_t b);
|
|
724
|
+
int32_t (*linked_channels)(void *user_data,
|
|
725
|
+
uint64_t secret_id,
|
|
726
|
+
uint64_t channel_id,
|
|
727
|
+
uint8_t **out_ptr,
|
|
728
|
+
size_t *out_len);
|
|
729
|
+
void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
|
|
730
|
+
} ChannelStoreCallbacks;
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Caller-supplied callbacks for secret persistence.
|
|
734
|
+
*/
|
|
735
|
+
typedef struct SecretStoreCallbacks {
|
|
736
|
+
void *user_data;
|
|
737
|
+
int32_t (*load)(void *user_data,
|
|
738
|
+
uint64_t secret_id,
|
|
739
|
+
uint64_t channel_id,
|
|
740
|
+
uint32_t kind,
|
|
741
|
+
uint8_t **out_ptr,
|
|
742
|
+
size_t *out_len);
|
|
743
|
+
int32_t (*save)(void *user_data,
|
|
744
|
+
uint64_t secret_id,
|
|
745
|
+
uint64_t channel_id,
|
|
746
|
+
uint32_t kind,
|
|
747
|
+
const uint8_t *bytes,
|
|
748
|
+
size_t len);
|
|
749
|
+
int32_t (*remove)(void *user_data, uint64_t secret_id, uint64_t channel_id, uint32_t kind);
|
|
750
|
+
void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
|
|
751
|
+
} SecretStoreCallbacks;
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Caller-supplied callbacks for share persistence. Variable-length
|
|
755
|
+
* arrays (`channel_ids[]`, `versions[]`) cross the FFI as JSON
|
|
756
|
+
* strings, matching the `Vec<u8>` ↔ JSON-array convention used for
|
|
757
|
+
* every other wire-format buffer in this module.
|
|
758
|
+
*/
|
|
759
|
+
typedef struct ShareStoreCallbacks {
|
|
760
|
+
void *user_data;
|
|
761
|
+
int32_t (*load)(void *user_data,
|
|
762
|
+
uint64_t secret_id,
|
|
763
|
+
uint64_t channel_id,
|
|
764
|
+
const uint8_t *versions_json_ptr,
|
|
765
|
+
size_t versions_json_len,
|
|
766
|
+
uint8_t **out_ptr,
|
|
767
|
+
size_t *out_len);
|
|
768
|
+
int32_t (*load_many)(void *user_data,
|
|
769
|
+
uint64_t secret_id,
|
|
770
|
+
const uint8_t *channel_ids_json_ptr,
|
|
771
|
+
size_t channel_ids_json_len,
|
|
772
|
+
const uint8_t *versions_json_ptr,
|
|
773
|
+
size_t versions_json_len,
|
|
774
|
+
uint8_t **out_ptr,
|
|
775
|
+
size_t *out_len);
|
|
776
|
+
int32_t (*load_all)(void *user_data,
|
|
777
|
+
uint64_t secret_id,
|
|
778
|
+
const uint8_t *channel_ids_json_ptr,
|
|
779
|
+
size_t channel_ids_json_len,
|
|
780
|
+
uint8_t **out_ptr,
|
|
781
|
+
size_t *out_len);
|
|
782
|
+
int32_t (*latest_version)(void *user_data,
|
|
783
|
+
uint64_t secret_id,
|
|
784
|
+
uint32_t *out_has_version,
|
|
785
|
+
uint32_t *out_version);
|
|
786
|
+
int32_t (*save)(void *user_data,
|
|
787
|
+
uint64_t secret_id,
|
|
788
|
+
uint64_t channel_id,
|
|
789
|
+
const uint8_t *share_json_ptr,
|
|
790
|
+
size_t share_json_len);
|
|
791
|
+
int32_t (*remove_channel)(void *user_data, uint64_t secret_id, uint64_t channel_id);
|
|
792
|
+
void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
|
|
793
|
+
} ShareStoreCallbacks;
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Caller-supplied callbacks for the user-secret store. Methods cross
|
|
797
|
+
* the FFI keyed by `secret_id`; the `UserSecrets` payload travels as a
|
|
798
|
+
* JSON buffer matching [`UserSecretsRecord`].
|
|
799
|
+
*/
|
|
800
|
+
typedef struct UserSecretStoreCallbacks {
|
|
801
|
+
void *user_data;
|
|
802
|
+
/**
|
|
803
|
+
* `load_latest(secret_id, out_ptr, out_len)` — writes the JSON
|
|
804
|
+
* payload (or `out_len = 0` if absent). Caller releases the buffer
|
|
805
|
+
* via `free_buffer`.
|
|
806
|
+
*/
|
|
807
|
+
int32_t (*load_latest)(void *user_data, uint64_t secret_id, uint8_t **out_ptr, size_t *out_len);
|
|
808
|
+
/**
|
|
809
|
+
* `save_latest(secret_id, value_json_ptr, value_json_len)`.
|
|
810
|
+
*/
|
|
811
|
+
int32_t (*save_latest)(void *user_data,
|
|
812
|
+
uint64_t secret_id,
|
|
813
|
+
const uint8_t *value_json_ptr,
|
|
814
|
+
size_t value_json_len);
|
|
815
|
+
/**
|
|
816
|
+
* `remove(secret_id)` — idempotent.
|
|
817
|
+
*/
|
|
818
|
+
int32_t (*remove)(void *user_data, uint64_t secret_id);
|
|
819
|
+
void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
|
|
820
|
+
} UserSecretStoreCallbacks;
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Caller-supplied callbacks for orchestrator in-flight state
|
|
824
|
+
* ([`DeRecStateStore`]). The item and key travel as JSON buffers
|
|
825
|
+
* matching [`StateItemRecord`] / [`StateKeyRecord`].
|
|
826
|
+
*
|
|
827
|
+
* # Return codes
|
|
828
|
+
*
|
|
829
|
+
* - `load`: `0` = found (record written), `1` = not found (empty
|
|
830
|
+
* payload), other = backend failure.
|
|
831
|
+
* - `remove`: `0` = ok (`*out_removed` set to `0` or `1`), other =
|
|
832
|
+
* backend failure.
|
|
833
|
+
* - `save` / `load_all`: `0` = ok, other = backend failure.
|
|
834
|
+
*/
|
|
835
|
+
typedef struct StateStoreCallbacks {
|
|
836
|
+
void *user_data;
|
|
837
|
+
int32_t (*save)(void *user_data,
|
|
838
|
+
uint64_t secret_id,
|
|
839
|
+
const uint8_t *item_json_ptr,
|
|
840
|
+
size_t item_json_len);
|
|
841
|
+
int32_t (*load)(void *user_data,
|
|
842
|
+
uint64_t secret_id,
|
|
843
|
+
const uint8_t *key_json_ptr,
|
|
844
|
+
size_t key_json_len,
|
|
845
|
+
uint8_t **out_ptr,
|
|
846
|
+
size_t *out_len);
|
|
847
|
+
int32_t (*remove)(void *user_data,
|
|
848
|
+
uint64_t secret_id,
|
|
849
|
+
const uint8_t *key_json_ptr,
|
|
850
|
+
size_t key_json_len,
|
|
851
|
+
uint32_t *out_removed);
|
|
852
|
+
int32_t (*load_all)(void *user_data,
|
|
853
|
+
uint64_t secret_id,
|
|
854
|
+
uint32_t kind,
|
|
855
|
+
uint8_t **out_ptr,
|
|
856
|
+
size_t *out_len);
|
|
857
|
+
void (*free_buffer)(void *user_data, uint8_t *ptr, size_t len);
|
|
858
|
+
} StateStoreCallbacks;
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Caller-supplied transport callback.
|
|
862
|
+
*/
|
|
863
|
+
typedef struct TransportCallbacks {
|
|
864
|
+
void *user_data;
|
|
865
|
+
int32_t (*send)(void *user_data,
|
|
866
|
+
const uint8_t *uri_ptr,
|
|
867
|
+
size_t uri_len,
|
|
868
|
+
int32_t protocol,
|
|
869
|
+
const uint8_t *bytes,
|
|
870
|
+
size_t len);
|
|
871
|
+
} TransportCallbacks;
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Result type for [`derec_protocol_remove_expired_channels`].
|
|
875
|
+
*/
|
|
876
|
+
typedef struct DeRecRemovedChannelsResult {
|
|
877
|
+
struct DeRecError error;
|
|
878
|
+
/**
|
|
879
|
+
* On success, a heap-owned UTF-8 JSON array of removed channel ids as
|
|
880
|
+
* decimal strings — e.g. `["12","4096"]`. Decimal strings rather than
|
|
881
|
+
* JSON numbers because `u64` ids exceed `Number.MAX_SAFE_INTEGER`;
|
|
882
|
+
* this matches every other id crossing this boundary. Caller releases
|
|
883
|
+
* via [`crate::interop::ffi::common::derec_free_buffer`].
|
|
884
|
+
*/
|
|
885
|
+
struct DeRecBuffer channels;
|
|
886
|
+
} DeRecRemovedChannelsResult;
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Result type for entry points that return a `Vec<DeRecEvent>`.
|
|
890
|
+
*/
|
|
891
|
+
typedef struct DeRecProtocolEventsResult {
|
|
892
|
+
struct DeRecError error;
|
|
893
|
+
/**
|
|
894
|
+
* UTF-8 JSON array of events. See [`crate::interop::ffi::protocol::events`]
|
|
895
|
+
* for the per-variant shape. Caller releases via
|
|
896
|
+
* [`crate::interop::ffi::derec_free_buffer`].
|
|
897
|
+
*/
|
|
898
|
+
struct DeRecBuffer events_json;
|
|
899
|
+
} DeRecProtocolEventsResult;
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Result type for fingerprint accessors.
|
|
903
|
+
*/
|
|
904
|
+
typedef struct DeRecProtocolFingerprintResult {
|
|
905
|
+
struct DeRecError error;
|
|
906
|
+
/**
|
|
907
|
+
* On success, owned C string (heap-allocated). Caller releases via
|
|
908
|
+
* [`crate::interop::ffi::common::derec_free_string`].
|
|
909
|
+
*/
|
|
910
|
+
char *fingerprint;
|
|
911
|
+
} DeRecProtocolFingerprintResult;
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Result type for [`derec_protocol_create_contact`].
|
|
915
|
+
*/
|
|
916
|
+
typedef struct DeRecProtocolCreateContactResult {
|
|
917
|
+
struct DeRecError error;
|
|
918
|
+
/**
|
|
919
|
+
* prost-encoded [`derec_proto::ContactMessage`] on success.
|
|
920
|
+
* Caller releases via [`crate::interop::ffi::derec_free_buffer`].
|
|
921
|
+
*/
|
|
922
|
+
struct DeRecBuffer contact_wire_bytes;
|
|
923
|
+
} DeRecProtocolCreateContactResult;
|
|
924
|
+
|
|
925
|
+
typedef struct DeRecProtocolVersion {
|
|
926
|
+
uint32_t major;
|
|
927
|
+
uint32_t minor;
|
|
928
|
+
} DeRecProtocolVersion;
|
|
929
|
+
|
|
930
|
+
typedef struct ProduceGetShareRequestMessageResult {
|
|
931
|
+
struct DeRecError error;
|
|
932
|
+
struct DeRecBuffer request_wire_bytes;
|
|
933
|
+
} ProduceGetShareRequestMessageResult;
|
|
934
|
+
|
|
935
|
+
typedef struct ExtractGetShareRequestResult {
|
|
936
|
+
struct DeRecError error;
|
|
937
|
+
uint64_t channel_id;
|
|
938
|
+
/**
|
|
939
|
+
* Inner `GetShareRequestMessage` proto bytes for chaining into
|
|
940
|
+
* [`produce_get_share_response_message`].
|
|
941
|
+
*/
|
|
942
|
+
struct DeRecBuffer request_proto_bytes;
|
|
943
|
+
} ExtractGetShareRequestResult;
|
|
944
|
+
|
|
945
|
+
typedef struct ProduceGetShareResponseMessageResult {
|
|
946
|
+
struct DeRecError error;
|
|
947
|
+
struct DeRecBuffer response_wire_bytes;
|
|
948
|
+
} ProduceGetShareResponseMessageResult;
|
|
949
|
+
|
|
950
|
+
typedef struct ExtractGetShareResponseResult {
|
|
951
|
+
struct DeRecError error;
|
|
952
|
+
uint64_t channel_id;
|
|
953
|
+
/**
|
|
954
|
+
* Inner `GetShareResponseMessage` proto bytes. Accumulate across helpers
|
|
955
|
+
* and pass to [`recover_from_share_responses`].
|
|
956
|
+
*/
|
|
957
|
+
struct DeRecBuffer response_proto_bytes;
|
|
958
|
+
} ExtractGetShareResponseResult;
|
|
959
|
+
|
|
960
|
+
typedef struct RecoverFromShareResponsesResult {
|
|
961
|
+
struct DeRecError error;
|
|
962
|
+
struct DeRecBuffer secret_data;
|
|
963
|
+
} RecoverFromShareResponsesResult;
|
|
964
|
+
|
|
965
|
+
typedef struct ProtectSecretResult {
|
|
966
|
+
struct DeRecError error;
|
|
967
|
+
/**
|
|
968
|
+
* Committed shares in the format documented at the module level.
|
|
969
|
+
*/
|
|
970
|
+
struct DeRecBuffer shares_wire_bytes;
|
|
971
|
+
} ProtectSecretResult;
|
|
972
|
+
|
|
973
|
+
typedef struct ProduceStoreShareRequestMessageResult {
|
|
974
|
+
struct DeRecError error;
|
|
975
|
+
struct DeRecBuffer wire_bytes;
|
|
976
|
+
} ProduceStoreShareRequestMessageResult;
|
|
977
|
+
|
|
978
|
+
typedef struct ExtractStoreShareRequestResult {
|
|
979
|
+
struct DeRecError error;
|
|
980
|
+
uint64_t channel_id;
|
|
981
|
+
/**
|
|
982
|
+
* Inner `StoreShareRequestMessage` proto bytes for chaining into
|
|
983
|
+
* [`produce_store_share_response_message`].
|
|
984
|
+
*/
|
|
985
|
+
struct DeRecBuffer request_proto_bytes;
|
|
986
|
+
} ExtractStoreShareRequestResult;
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* `committed_share_bytes` is the serialized [`CommittedDeRecShare`] the
|
|
990
|
+
* helper should persist locally for later recovery responses.
|
|
991
|
+
*/
|
|
992
|
+
typedef struct ProduceStoreShareResponseMessageResult {
|
|
993
|
+
struct DeRecError error;
|
|
994
|
+
struct DeRecBuffer wire_bytes;
|
|
995
|
+
struct DeRecBuffer committed_share_bytes;
|
|
996
|
+
uint64_t secret_id;
|
|
997
|
+
uint32_t version;
|
|
998
|
+
} ProduceStoreShareResponseMessageResult;
|
|
999
|
+
|
|
1000
|
+
typedef struct ExtractStoreShareResponseResult {
|
|
1001
|
+
struct DeRecError error;
|
|
1002
|
+
uint64_t channel_id;
|
|
1003
|
+
/**
|
|
1004
|
+
* Inner `StoreShareResponseMessage` proto bytes for chaining into
|
|
1005
|
+
* [`process_store_share_response_message`].
|
|
1006
|
+
*/
|
|
1007
|
+
struct DeRecBuffer response_proto_bytes;
|
|
1008
|
+
} ExtractStoreShareResponseResult;
|
|
1009
|
+
|
|
1010
|
+
typedef struct ProcessStoreShareResponseMessageResult {
|
|
1011
|
+
struct DeRecError error;
|
|
1012
|
+
} ProcessStoreShareResponseMessageResult;
|
|
1013
|
+
|
|
1014
|
+
typedef struct ProduceUnpairRequestMessageResult {
|
|
1015
|
+
struct DeRecError error;
|
|
1016
|
+
struct DeRecBuffer request_wire_bytes;
|
|
1017
|
+
} ProduceUnpairRequestMessageResult;
|
|
1018
|
+
|
|
1019
|
+
typedef struct ExtractUnpairRequestResult {
|
|
1020
|
+
struct DeRecError error;
|
|
1021
|
+
uint64_t channel_id;
|
|
1022
|
+
/**
|
|
1023
|
+
* Decrypted memo. Release with `derec_free_string`.
|
|
1024
|
+
*/
|
|
1025
|
+
char *memo;
|
|
1026
|
+
/**
|
|
1027
|
+
* prost-encoded inner `UnpairRequestMessage` bytes. SDK consumers
|
|
1028
|
+
* decode this to inspect optional fields such as `reply_to`.
|
|
1029
|
+
*/
|
|
1030
|
+
struct DeRecBuffer request_proto_bytes;
|
|
1031
|
+
} ExtractUnpairRequestResult;
|
|
1032
|
+
|
|
1033
|
+
typedef struct ProduceUnpairResponseMessageResult {
|
|
1034
|
+
struct DeRecError error;
|
|
1035
|
+
struct DeRecBuffer response_wire_bytes;
|
|
1036
|
+
} ProduceUnpairResponseMessageResult;
|
|
1037
|
+
|
|
1038
|
+
typedef struct ExtractUnpairResponseResult {
|
|
1039
|
+
struct DeRecError error;
|
|
1040
|
+
uint64_t channel_id;
|
|
1041
|
+
/**
|
|
1042
|
+
* Inner `UnpairResponseMessage` proto bytes for chaining into
|
|
1043
|
+
* [`process_unpair_response_message`].
|
|
1044
|
+
*/
|
|
1045
|
+
struct DeRecBuffer response_proto_bytes;
|
|
1046
|
+
} ExtractUnpairResponseResult;
|
|
1047
|
+
|
|
1048
|
+
typedef struct ProcessUnpairResponseResult {
|
|
1049
|
+
struct DeRecError error;
|
|
1050
|
+
} ProcessUnpairResponseResult;
|
|
1051
|
+
|
|
1052
|
+
typedef struct ProduceVerifyShareRequestMessageResult {
|
|
1053
|
+
struct DeRecError error;
|
|
1054
|
+
struct DeRecBuffer request_wire_bytes;
|
|
1055
|
+
} ProduceVerifyShareRequestMessageResult;
|
|
1056
|
+
|
|
1057
|
+
typedef struct ExtractVerifyShareRequestResult {
|
|
1058
|
+
struct DeRecError error;
|
|
1059
|
+
uint64_t channel_id;
|
|
1060
|
+
/**
|
|
1061
|
+
* Inner `VerifyShareRequestMessage` proto bytes for chaining into
|
|
1062
|
+
* [`produce_verify_share_response_message`].
|
|
1063
|
+
*/
|
|
1064
|
+
struct DeRecBuffer request_proto_bytes;
|
|
1065
|
+
} ExtractVerifyShareRequestResult;
|
|
1066
|
+
|
|
1067
|
+
typedef struct ProduceVerifyShareResponseMessageResult {
|
|
1068
|
+
struct DeRecError error;
|
|
1069
|
+
struct DeRecBuffer response_wire_bytes;
|
|
1070
|
+
} ProduceVerifyShareResponseMessageResult;
|
|
1071
|
+
|
|
1072
|
+
typedef struct ExtractVerifyShareResponseResult {
|
|
1073
|
+
struct DeRecError error;
|
|
1074
|
+
uint64_t channel_id;
|
|
1075
|
+
/**
|
|
1076
|
+
* Inner `VerifyShareResponseMessage` proto bytes for chaining into
|
|
1077
|
+
* [`process_verify_share_response_message`].
|
|
1078
|
+
*/
|
|
1079
|
+
struct DeRecBuffer response_proto_bytes;
|
|
1080
|
+
} ExtractVerifyShareResponseResult;
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* `is_valid` is meaningful only on success. Peer rejection surfaces on
|
|
1084
|
+
* `error` (see [`crate::interop::ffi::error`]).
|
|
1085
|
+
*/
|
|
1086
|
+
typedef struct VerifyShareResponseResult {
|
|
1087
|
+
struct DeRecError error;
|
|
1088
|
+
bool is_valid;
|
|
1089
|
+
} VerifyShareResponseResult;
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
#ifdef __cplusplus
|
|
1094
|
+
extern "C" {
|
|
1095
|
+
#endif // __cplusplus
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* Releases a [`DeRecBuffer`] previously returned by the SDK.
|
|
1099
|
+
*
|
|
1100
|
+
* Safe to call with a null pointer.
|
|
1101
|
+
*
|
|
1102
|
+
* # Safety
|
|
1103
|
+
*
|
|
1104
|
+
* `ptr` must have been allocated by the DeRec SDK and `len` must match the
|
|
1105
|
+
* original allocation length.
|
|
1106
|
+
*/
|
|
1107
|
+
void derec_free_buffer(uint8_t *ptr, size_t len);
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Releases a standalone C string previously returned by the SDK.
|
|
1111
|
+
*
|
|
1112
|
+
* For strings owned by a [`crate::interop::ffi::error::DeRecError`], use
|
|
1113
|
+
* [`crate::interop::ffi::error::derec_free_error`] which releases both owned strings
|
|
1114
|
+
* in one call. Safe to call with a null pointer.
|
|
1115
|
+
*
|
|
1116
|
+
* # Safety
|
|
1117
|
+
*
|
|
1118
|
+
* `ptr` must have been allocated by the DeRec SDK.
|
|
1119
|
+
*/
|
|
1120
|
+
void derec_free_string(char *ptr);
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* # Safety
|
|
1124
|
+
*
|
|
1125
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1126
|
+
*/
|
|
1127
|
+
struct ProduceGetSecretIdsVersionsRequestMessageResult produce_get_secret_ids_versions_request_message(uint64_t channel_id,
|
|
1128
|
+
const uint8_t *shared_key_ptr,
|
|
1129
|
+
size_t shared_key_len,
|
|
1130
|
+
const uint8_t *reply_to_ptr,
|
|
1131
|
+
size_t reply_to_len);
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* # Safety
|
|
1135
|
+
*
|
|
1136
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1137
|
+
*/
|
|
1138
|
+
struct ExtractGetSecretIdsVersionsRequestResult extract_get_secret_ids_versions_request(const uint8_t *request_ptr,
|
|
1139
|
+
size_t request_len,
|
|
1140
|
+
const uint8_t *shared_key_ptr,
|
|
1141
|
+
size_t shared_key_len);
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* `secret_list_ptr` / `secret_list_len` must follow the binary format
|
|
1145
|
+
* documented at the module level.
|
|
1146
|
+
*
|
|
1147
|
+
* # Safety
|
|
1148
|
+
*
|
|
1149
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1150
|
+
*/
|
|
1151
|
+
struct ProduceGetSecretIdsVersionsResponseMessageResult produce_get_secret_ids_versions_response_message(uint64_t channel_id,
|
|
1152
|
+
const uint8_t *secret_list_ptr,
|
|
1153
|
+
size_t secret_list_len,
|
|
1154
|
+
const uint8_t *shared_key_ptr,
|
|
1155
|
+
size_t shared_key_len);
|
|
1156
|
+
|
|
1157
|
+
/**
|
|
1158
|
+
* # Safety
|
|
1159
|
+
*
|
|
1160
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1161
|
+
*/
|
|
1162
|
+
struct ExtractGetSecretIdsVersionsResponseResult extract_get_secret_ids_versions_response(const uint8_t *response_ptr,
|
|
1163
|
+
size_t response_len,
|
|
1164
|
+
const uint8_t *shared_key_ptr,
|
|
1165
|
+
size_t shared_key_len);
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
1169
|
+
* `response_proto_bytes` returned by
|
|
1170
|
+
* [`extract_get_secret_ids_versions_response`].
|
|
1171
|
+
*
|
|
1172
|
+
* # Safety
|
|
1173
|
+
*
|
|
1174
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1175
|
+
*/
|
|
1176
|
+
struct ProcessGetSecretIdsVersionsResponseMessageResult process_get_secret_ids_versions_response_message(const uint8_t *response_proto_ptr,
|
|
1177
|
+
size_t response_proto_len);
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* Overwrite `trace_id` on an already-produced envelope and return the
|
|
1181
|
+
* re-encoded bytes.
|
|
1182
|
+
*
|
|
1183
|
+
* Mirrors [`crate::derec_message::apply_trace_id`]. Useful for FFI consumers
|
|
1184
|
+
* using primitives directly: the `produce_*_request_message` family emits
|
|
1185
|
+
* envelopes with `trace_id = 0`, so callers who want correlation produce +
|
|
1186
|
+
* then call this. The orchestrator does this automatically end-to-end.
|
|
1187
|
+
*
|
|
1188
|
+
* # Safety
|
|
1189
|
+
*
|
|
1190
|
+
* `envelope_ptr` must point to a readable byte range of length `envelope_len`.
|
|
1191
|
+
*/
|
|
1192
|
+
struct ApplyTraceIdResult apply_trace_id_to_envelope(const uint8_t *envelope_ptr,
|
|
1193
|
+
size_t envelope_len,
|
|
1194
|
+
uint64_t trace_id);
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Read `trace_id` off an envelope without touching the encrypted inner
|
|
1198
|
+
* payload. Pair with [`apply_trace_id_to_envelope`] for primitive-level
|
|
1199
|
+
* request/response correlation.
|
|
1200
|
+
*
|
|
1201
|
+
* # Safety
|
|
1202
|
+
*
|
|
1203
|
+
* `envelope_ptr` must point to a readable byte range of length `envelope_len`.
|
|
1204
|
+
*/
|
|
1205
|
+
struct ReadTraceIdResult read_trace_id_from_envelope(const uint8_t *envelope_ptr,
|
|
1206
|
+
size_t envelope_len);
|
|
1207
|
+
|
|
1208
|
+
/**
|
|
1209
|
+
* Releases the owned strings carried by a [`DeRecError`]. After
|
|
1210
|
+
* returning, `error.message` and `error.peer_memo` are both null —
|
|
1211
|
+
* an accidental second call is a safe no-op.
|
|
1212
|
+
*
|
|
1213
|
+
* # Safety
|
|
1214
|
+
*
|
|
1215
|
+
* `error` must either be null (in which case this function is a
|
|
1216
|
+
* no-op) or point to a fully-initialized [`DeRecError`] produced by
|
|
1217
|
+
* the DeRec SDK. The function takes the value by pointer so it can
|
|
1218
|
+
* null out `message` and `peer_memo` after freeing them, neutralizing
|
|
1219
|
+
* the obvious double-free vector that a by-value signature creates
|
|
1220
|
+
* — callers that re-invoke `derec_free_error` on the same struct
|
|
1221
|
+
* then see a null-pointer no-op instead of corrupting the heap.
|
|
1222
|
+
*/
|
|
1223
|
+
void derec_free_error(struct DeRecError *error);
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Static NUL-terminated name for a `DEREC_CATEGORY_*` value.
|
|
1227
|
+
*
|
|
1228
|
+
* Returns `"unknown"` for unrecognized values. The returned pointer has
|
|
1229
|
+
* static lifetime and must **not** be freed.
|
|
1230
|
+
*/
|
|
1231
|
+
const char *derec_error_category_name(int32_t category);
|
|
1232
|
+
|
|
1233
|
+
/**
|
|
1234
|
+
* Static NUL-terminated name for a `DEREC_CODE_*` value.
|
|
1235
|
+
*
|
|
1236
|
+
* Returns `"unknown"` for unrecognized values. The returned pointer has
|
|
1237
|
+
* static lifetime and must **not** be freed.
|
|
1238
|
+
*/
|
|
1239
|
+
const char *derec_error_code_name(int32_t code);
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* Decodes protobuf wire bytes into the JSON mirror of `kind`.
|
|
1243
|
+
*
|
|
1244
|
+
* The returned buffer is UTF-8 JSON and must be released with
|
|
1245
|
+
* `derec_free_buffer`.
|
|
1246
|
+
*
|
|
1247
|
+
* # Safety
|
|
1248
|
+
*
|
|
1249
|
+
* `proto_ptr` must point to `proto_len` readable bytes, or be null with
|
|
1250
|
+
* `proto_len` zero.
|
|
1251
|
+
*/
|
|
1252
|
+
struct DeRecMessageJsonResult derec_decode_message_json(int32_t kind,
|
|
1253
|
+
const uint8_t *proto_ptr,
|
|
1254
|
+
size_t proto_len);
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* Encodes the JSON mirror of `kind` into protobuf wire bytes.
|
|
1258
|
+
*
|
|
1259
|
+
* The returned buffer must be released with `derec_free_buffer`.
|
|
1260
|
+
*
|
|
1261
|
+
* # Safety
|
|
1262
|
+
*
|
|
1263
|
+
* `json_ptr` must point to `json_len` readable bytes, or be null with
|
|
1264
|
+
* `json_len` zero.
|
|
1265
|
+
*/
|
|
1266
|
+
struct DeRecMessageJsonResult derec_encode_message_json(int32_t kind,
|
|
1267
|
+
const uint8_t *json_ptr,
|
|
1268
|
+
size_t json_len);
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* Single entry point for all three modes:
|
|
1272
|
+
* - `contact_mode == 0` (`INLINE_KEYS`) — keys inlined in contact.
|
|
1273
|
+
* - `contact_mode == 1` (`HASHED_KEYS`) — binding hash inlined; keys via PrePair.
|
|
1274
|
+
* - `contact_mode == 2` (`NO_KEYS`) — no key material; keys generated on the
|
|
1275
|
+
* fly by the responder when the `PrePairRequest` arrives.
|
|
1276
|
+
*
|
|
1277
|
+
* `has_nonce == 0` lets the library generate a fresh random `u64`.
|
|
1278
|
+
* `has_nonce == 1` uses the supplied `nonce` value verbatim; required for
|
|
1279
|
+
* `NO_KEYS` where callers typically pick a small human-typable value.
|
|
1280
|
+
*
|
|
1281
|
+
* On success `secret_key_material` is populated for `INLINE_KEYS` and
|
|
1282
|
+
* `HASHED_KEYS`; it is empty for `NO_KEYS` (no keys exist at
|
|
1283
|
+
* contact-creation time).
|
|
1284
|
+
*
|
|
1285
|
+
* # Safety
|
|
1286
|
+
*
|
|
1287
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1288
|
+
*/
|
|
1289
|
+
struct CreateContactMessageResult create_contact_message(uint64_t channel_id,
|
|
1290
|
+
int32_t contact_mode,
|
|
1291
|
+
const uint8_t *transport_protocol_ptr,
|
|
1292
|
+
size_t transport_protocol_len,
|
|
1293
|
+
uint32_t has_nonce,
|
|
1294
|
+
uint64_t nonce);
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* Structurally validate a proto-encoded `ContactMessage`. Returns a
|
|
1298
|
+
* successful [`DeRecError`] iff the contact's `(contact_mode, inline keys,
|
|
1299
|
+
* binding hash)` tuple satisfies the per-mode invariants enforced by the
|
|
1300
|
+
* pairing primitives. Intended for bindings to call at their parse
|
|
1301
|
+
* boundary (e.g. `FromProtoBytes`) so that the decoded value handed to
|
|
1302
|
+
* application code is guaranteed well-formed.
|
|
1303
|
+
*
|
|
1304
|
+
* Failure codes:
|
|
1305
|
+
* - [`DEREC_CODE_FFI_BAD_PROTO`] if the bytes do not decode as a
|
|
1306
|
+
* `ContactMessage`.
|
|
1307
|
+
* - The library's `InvalidContactMessage` error code on any structural
|
|
1308
|
+
* violation (unknown `contact_mode`, mode/field mismatch, wrong
|
|
1309
|
+
* binding-hash length).
|
|
1310
|
+
*
|
|
1311
|
+
* # Safety
|
|
1312
|
+
*
|
|
1313
|
+
* `contact_message_ptr` must point to a readable range of
|
|
1314
|
+
* `contact_message_len` bytes (or be null with `len == 0`).
|
|
1315
|
+
*/
|
|
1316
|
+
struct DeRecError validate_contact_message(const uint8_t *contact_message_ptr,
|
|
1317
|
+
size_t contact_message_len);
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* Encodes a JSON [`ContactMessageDto`] to `ContactMessage` proto wire bytes.
|
|
1321
|
+
* Structurally validates the input first so a locally-constructed contact
|
|
1322
|
+
* that violates the mode/field invariant is rejected at the boundary rather
|
|
1323
|
+
* than silently serialized.
|
|
1324
|
+
*
|
|
1325
|
+
* The JSON shape is [`ContactMessageDto`]'s serde representation with one
|
|
1326
|
+
* adjustment applied at this seam: `channel_id` and `nonce` are decimal
|
|
1327
|
+
* strings, matching the `u64`-as-decimal-string convention every other FFI
|
|
1328
|
+
* JSON payload uses (see [`crate::interop::ffi::protocol::flow`]) because a host
|
|
1329
|
+
* whose numbers are IEEE-754 doubles cannot round-trip a full-width `u64`.
|
|
1330
|
+
* A plain JSON number is also accepted for either field.
|
|
1331
|
+
*
|
|
1332
|
+
* # Safety
|
|
1333
|
+
*
|
|
1334
|
+
* `contact_json_ptr` must point to a readable range of `contact_json_len`
|
|
1335
|
+
* bytes (or be null with `len == 0`).
|
|
1336
|
+
*/
|
|
1337
|
+
struct EncodeContactMessageResult encode_contact_message(const uint8_t *contact_json_ptr,
|
|
1338
|
+
size_t contact_json_len);
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* Decodes proto-encoded `ContactMessage` wire bytes into the JSON
|
|
1342
|
+
* [`ContactMessageDto`] shape described on [`encode_contact_message`].
|
|
1343
|
+
* Structurally validates the decoded value before returning it to
|
|
1344
|
+
* application code so consumers can trust the mode/field invariants
|
|
1345
|
+
* documented on the wire format.
|
|
1346
|
+
*
|
|
1347
|
+
* # Safety
|
|
1348
|
+
*
|
|
1349
|
+
* `contact_wire_ptr` must point to a readable range of `contact_wire_len`
|
|
1350
|
+
* bytes (or be null with `len == 0`).
|
|
1351
|
+
*/
|
|
1352
|
+
struct DecodeContactMessageResult decode_contact_message(const uint8_t *contact_wire_ptr,
|
|
1353
|
+
size_t contact_wire_len);
|
|
1354
|
+
|
|
1355
|
+
/**
|
|
1356
|
+
* `communication_info_ptr` may be null / zero-length to indicate no
|
|
1357
|
+
* communication info; otherwise it must be serialized [`CommunicationInfo`]
|
|
1358
|
+
* proto bytes. `parameter_range_ptr` follows the same convention and
|
|
1359
|
+
* carries serialized [`derec_proto::ParameterRange`] bytes.
|
|
1360
|
+
*
|
|
1361
|
+
* # Safety
|
|
1362
|
+
*
|
|
1363
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1364
|
+
*/
|
|
1365
|
+
struct ProducePairRequestMessageResult produce_pair_request_message(int32_t sender_kind,
|
|
1366
|
+
const uint8_t *transport_protocol_ptr,
|
|
1367
|
+
size_t transport_protocol_len,
|
|
1368
|
+
const uint8_t *contact_message_ptr,
|
|
1369
|
+
size_t contact_message_len,
|
|
1370
|
+
const uint8_t *communication_info_ptr,
|
|
1371
|
+
size_t communication_info_len,
|
|
1372
|
+
const uint8_t *parameter_range_ptr,
|
|
1373
|
+
size_t parameter_range_len);
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* # Safety
|
|
1377
|
+
*
|
|
1378
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1379
|
+
*/
|
|
1380
|
+
struct ExtractPairRequestResult extract_pair_request(const uint8_t *request_ptr,
|
|
1381
|
+
size_t request_len,
|
|
1382
|
+
const uint8_t *secret_key_material_ptr,
|
|
1383
|
+
size_t secret_key_material_len);
|
|
1384
|
+
|
|
1385
|
+
/**
|
|
1386
|
+
* `request_proto_ptr` / `request_proto_len` must be the `request_proto_bytes`
|
|
1387
|
+
* returned by [`extract_pair_request`]. `communication_info_ptr` may be null /
|
|
1388
|
+
* zero-length to indicate no communication info.
|
|
1389
|
+
*
|
|
1390
|
+
* `parameter_range_ptr` may be null / zero-length to indicate no
|
|
1391
|
+
* parameter range; otherwise it must be serialized
|
|
1392
|
+
* [`derec_proto::ParameterRange`] proto bytes.
|
|
1393
|
+
*
|
|
1394
|
+
* # Safety
|
|
1395
|
+
*
|
|
1396
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1397
|
+
*/
|
|
1398
|
+
struct ProducePairResponseMessageResult produce_pair_response_message(uint64_t channel_id,
|
|
1399
|
+
const uint8_t *request_proto_ptr,
|
|
1400
|
+
size_t request_proto_len,
|
|
1401
|
+
const uint8_t *secret_key_material_ptr,
|
|
1402
|
+
size_t secret_key_material_len,
|
|
1403
|
+
const uint8_t *communication_info_ptr,
|
|
1404
|
+
size_t communication_info_len,
|
|
1405
|
+
const uint8_t *parameter_range_ptr,
|
|
1406
|
+
size_t parameter_range_len);
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* # Safety
|
|
1410
|
+
*
|
|
1411
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1412
|
+
*/
|
|
1413
|
+
struct ExtractPairResponseResult extract_pair_response(const uint8_t *response_ptr,
|
|
1414
|
+
size_t response_len,
|
|
1415
|
+
const uint8_t *secret_key_material_ptr,
|
|
1416
|
+
size_t secret_key_material_len);
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
1420
|
+
* `response_proto_bytes` returned by [`extract_pair_response`].
|
|
1421
|
+
*
|
|
1422
|
+
* # Safety
|
|
1423
|
+
*
|
|
1424
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1425
|
+
*/
|
|
1426
|
+
struct ProcessPairResponseMessageResult process_pair_response_message(const uint8_t *contact_message_ptr,
|
|
1427
|
+
size_t contact_message_len,
|
|
1428
|
+
const uint8_t *response_proto_ptr,
|
|
1429
|
+
size_t response_proto_len,
|
|
1430
|
+
const uint8_t *secret_key_material_ptr,
|
|
1431
|
+
size_t secret_key_material_len);
|
|
1432
|
+
|
|
1433
|
+
/**
|
|
1434
|
+
* Builds a plaintext `PrePairRequestMessage` envelope. Used by the scanner
|
|
1435
|
+
* when the contact was sent with `contact_mode == HASHED_KEYS`. The envelope
|
|
1436
|
+
* is unencrypted — no shared key exists yet — so the caller does not pass
|
|
1437
|
+
* secret key material here.
|
|
1438
|
+
*
|
|
1439
|
+
* # Safety
|
|
1440
|
+
*
|
|
1441
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1442
|
+
*/
|
|
1443
|
+
struct ProducePrePairRequestMessageResult produce_pre_pair_request_message(const uint8_t *transport_protocol_ptr,
|
|
1444
|
+
size_t transport_protocol_len,
|
|
1445
|
+
const uint8_t *contact_message_ptr,
|
|
1446
|
+
size_t contact_message_len);
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* Decodes a plaintext `PrePairRequestMessage` envelope.
|
|
1450
|
+
*
|
|
1451
|
+
* # Safety
|
|
1452
|
+
*
|
|
1453
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1454
|
+
*/
|
|
1455
|
+
struct ExtractPrePairRequestResult extract_pre_pair_request(const uint8_t *envelope_ptr,
|
|
1456
|
+
size_t envelope_len);
|
|
1457
|
+
|
|
1458
|
+
/**
|
|
1459
|
+
* Builds a plaintext `PrePairResponseMessage` envelope republishing the
|
|
1460
|
+
* initiator's public keys. The keys come from `secret_key_material` (which
|
|
1461
|
+
* retains them alongside the secrets in `HASHED_KEYS` flows).
|
|
1462
|
+
*
|
|
1463
|
+
* `request_proto_ptr` / `request_proto_len` must be the `request_proto_bytes`
|
|
1464
|
+
* returned by [`extract_pre_pair_request`].
|
|
1465
|
+
*
|
|
1466
|
+
* # Safety
|
|
1467
|
+
*
|
|
1468
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1469
|
+
*/
|
|
1470
|
+
struct ProducePrePairResponseMessageResult produce_pre_pair_response_message(uint64_t channel_id,
|
|
1471
|
+
const uint8_t *request_proto_ptr,
|
|
1472
|
+
size_t request_proto_len,
|
|
1473
|
+
const uint8_t *secret_key_material_ptr,
|
|
1474
|
+
size_t secret_key_material_len);
|
|
1475
|
+
|
|
1476
|
+
/**
|
|
1477
|
+
* Decodes a plaintext `PrePairResponseMessage` envelope.
|
|
1478
|
+
*
|
|
1479
|
+
* # Safety
|
|
1480
|
+
*
|
|
1481
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1482
|
+
*/
|
|
1483
|
+
struct ExtractPrePairResponseResult extract_pre_pair_response(const uint8_t *envelope_ptr,
|
|
1484
|
+
size_t envelope_len);
|
|
1485
|
+
|
|
1486
|
+
/**
|
|
1487
|
+
* Scanner-side: validates a decoded `PrePairResponseMessage` against the
|
|
1488
|
+
* original `ContactMessage`'s SHA-384 binding hash. On success returns the
|
|
1489
|
+
* validated public keys and echoed nonce. On any failure (non-Ok status,
|
|
1490
|
+
* hash mismatch, nonce mismatch, missing fields) returns an error and
|
|
1491
|
+
* empty buffers.
|
|
1492
|
+
*
|
|
1493
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
1494
|
+
* `response_proto_bytes` returned by [`extract_pre_pair_response`].
|
|
1495
|
+
*
|
|
1496
|
+
* # Safety
|
|
1497
|
+
*
|
|
1498
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1499
|
+
*/
|
|
1500
|
+
struct ProcessPrePairResponseMessageResult process_pre_pair_response_message(const uint8_t *contact_message_ptr,
|
|
1501
|
+
size_t contact_message_len,
|
|
1502
|
+
const uint8_t *response_proto_ptr,
|
|
1503
|
+
size_t response_proto_len);
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* Constructs a [`crate::protocol::DeRecProtocol`] with scalar config
|
|
1507
|
+
* bundled as JSON, for FFI callers that cannot pass many native
|
|
1508
|
+
* arguments in a single call — e.g. Go via `purego` (no cgo), which
|
|
1509
|
+
* panics with "too many stack arguments" past a handful of
|
|
1510
|
+
* parameters. Scalar configuration is bundled into a single JSON
|
|
1511
|
+
* buffer; `communication_info` stays a separate proto-encoded
|
|
1512
|
+
* `CommunicationInfo` buffer; the 6 store/transport callback structs
|
|
1513
|
+
* are still passed as individual pointers, since purego marshals
|
|
1514
|
+
* pointer-sized arguments natively.
|
|
1515
|
+
*
|
|
1516
|
+
* `config_json` must deserialize to the following shape — all field
|
|
1517
|
+
* names `snake_case`. `secret_id`, `own_transport_uri` and
|
|
1518
|
+
* `own_transport_protocol` are the only genuinely required fields;
|
|
1519
|
+
* `threshold`, `keep_versions_count`, `auto_respond_on_failure`,
|
|
1520
|
+
* `unpair_ack`, `auto_reply_to` and `auto_accept` may each be omitted, in
|
|
1521
|
+
* which case the value matches
|
|
1522
|
+
* [`crate::protocol::DeRecProtocolBuilder::new`]'s own default for that
|
|
1523
|
+
* setting — see [`ProtocolConfig`]'s field-level `#[serde(default)]`
|
|
1524
|
+
* attributes, which read the same constants the builder does:
|
|
1525
|
+
*
|
|
1526
|
+
* ```json
|
|
1527
|
+
* {
|
|
1528
|
+
* "secret_id": "12345678901234567890",
|
|
1529
|
+
* "own_transport_uri": "https://example.com/derec",
|
|
1530
|
+
* "own_transport_protocol": 1,
|
|
1531
|
+
* "threshold": 3,
|
|
1532
|
+
* "keep_versions_count": 2,
|
|
1533
|
+
* "timeout_in_secs": 30,
|
|
1534
|
+
* "auto_respond_on_failure": false,
|
|
1535
|
+
* "unpair_ack": 0,
|
|
1536
|
+
* "auto_reply_to": false,
|
|
1537
|
+
* "auto_accept": {
|
|
1538
|
+
* "pairing": false,
|
|
1539
|
+
* "pre_pair": false,
|
|
1540
|
+
* "store_share": false,
|
|
1541
|
+
* "verify_share": false,
|
|
1542
|
+
* "discovery": false,
|
|
1543
|
+
* "get_share": false,
|
|
1544
|
+
* "unpair": false,
|
|
1545
|
+
* "update_channel_info": false
|
|
1546
|
+
* },
|
|
1547
|
+
* "remove_expired_channels": { "enabled": true, "timeout_in_secs": 300 },
|
|
1548
|
+
* "replica_id": null
|
|
1549
|
+
* }
|
|
1550
|
+
* ```
|
|
1551
|
+
*
|
|
1552
|
+
* - `secret_id`: decimal-string `u64`.
|
|
1553
|
+
* - `own_transport_uri`: may be `""` for the deferred-config path;
|
|
1554
|
+
* `derec_protocol_set_own_transport` must be called before pairing
|
|
1555
|
+
* in that case.
|
|
1556
|
+
* - `own_transport_protocol`: [`derec_proto::Protocol`] discriminant.
|
|
1557
|
+
* - `threshold` / `keep_versions_count`: optional; omitted means
|
|
1558
|
+
* [`crate::protocol::DEFAULT_THRESHOLD`] /
|
|
1559
|
+
* [`crate::protocol::DEFAULT_KEEP_VERSIONS_COUNT`].
|
|
1560
|
+
* - `unpair_ack`: `0` = Required, `1` = NotRequired; optional, omitted
|
|
1561
|
+
* means `0`.
|
|
1562
|
+
* - `auto_respond_on_failure` / `auto_reply_to`: optional, omitted means
|
|
1563
|
+
* `false`.
|
|
1564
|
+
* - `auto_accept`: one boolean per flow; the whole object is optional,
|
|
1565
|
+
* omitted means every flow `false`.
|
|
1566
|
+
* - `remove_expired_channels`: automatic removal of expired `Pending`
|
|
1567
|
+
* channels. Optional — omitted means `{ "enabled": true,
|
|
1568
|
+
* "timeout_in_secs": 300 }`. Both fields are always sent; when
|
|
1569
|
+
* `enabled` is `false` the timeout is ignored by the library.
|
|
1570
|
+
* - `replica_id`: decimal-string `u64`, or absent/`null` for "no
|
|
1571
|
+
* replica id".
|
|
1572
|
+
*
|
|
1573
|
+
* # Safety
|
|
1574
|
+
*
|
|
1575
|
+
* - `config_json_ptr` must be valid for reads of `config_json_len`
|
|
1576
|
+
* bytes.
|
|
1577
|
+
* - `communication_info_ptr` must be valid for reads of
|
|
1578
|
+
* `communication_info_len` bytes when the length is non-zero.
|
|
1579
|
+
* - All 6 callback pointers must be valid for reads of their pointee
|
|
1580
|
+
* struct, and must outlive the returned handle.
|
|
1581
|
+
* - The caller must invoke [`derec_protocol_free`] exactly once to
|
|
1582
|
+
* release the returned handle.
|
|
1583
|
+
*/
|
|
1584
|
+
struct DeRecProtocolNewResult derec_protocol_new(const uint8_t *config_json_ptr,
|
|
1585
|
+
size_t config_json_len,
|
|
1586
|
+
const uint8_t *communication_info_ptr,
|
|
1587
|
+
size_t communication_info_len,
|
|
1588
|
+
const struct ChannelStoreCallbacks *channel_store_cb,
|
|
1589
|
+
const struct SecretStoreCallbacks *secret_store_cb,
|
|
1590
|
+
const struct ShareStoreCallbacks *share_store_cb,
|
|
1591
|
+
const struct UserSecretStoreCallbacks *user_secret_store_cb,
|
|
1592
|
+
const struct StateStoreCallbacks *state_store_cb,
|
|
1593
|
+
const struct TransportCallbacks *transport_cb);
|
|
1594
|
+
|
|
1595
|
+
/**
|
|
1596
|
+
* Release a handle previously returned by [`derec_protocol_new`].
|
|
1597
|
+
* Safe to call with a null pointer.
|
|
1598
|
+
*
|
|
1599
|
+
* # Safety
|
|
1600
|
+
*
|
|
1601
|
+
* `handle` must satisfy ALL of:
|
|
1602
|
+
*
|
|
1603
|
+
* - It is a pointer previously returned by [`derec_protocol_new`],
|
|
1604
|
+
* or it is null.
|
|
1605
|
+
* - It has not already been freed (no double-free).
|
|
1606
|
+
* - **No other thread is executing any `derec_protocol_*` function on
|
|
1607
|
+
* this handle while this call is in flight.** The interior
|
|
1608
|
+
* [`std::sync::Mutex`] protects against aliased `&mut` references
|
|
1609
|
+
* *within* the live allocation, but it cannot protect the
|
|
1610
|
+
* allocation itself from being dropped — a concurrent
|
|
1611
|
+
* `derec_protocol_process` / `accept` / `set_*` call that holds
|
|
1612
|
+
* the lock would be reading freed memory the moment this function
|
|
1613
|
+
* returns. Host bindings (.NET `Dispose`, Node.js / WASM
|
|
1614
|
+
* teardown) are responsible for draining or cancelling in-flight
|
|
1615
|
+
* calls before invoking `derec_protocol_free`.
|
|
1616
|
+
*/
|
|
1617
|
+
void derec_protocol_free(struct DeRecProtocolHandle *handle);
|
|
1618
|
+
|
|
1619
|
+
/**
|
|
1620
|
+
* Replace this node's local `communication_info` map. Does not contact
|
|
1621
|
+
* peers — follow up with `start(FlowKind::UpdateChannelInfo)` to
|
|
1622
|
+
* propagate. The body is the same JSON wire shape used elsewhere on
|
|
1623
|
+
* the FFI: a UTF-8 JSON object with string keys + string values.
|
|
1624
|
+
*
|
|
1625
|
+
* # Safety
|
|
1626
|
+
*
|
|
1627
|
+
* `handle` must be a valid pointer returned by
|
|
1628
|
+
* [`super::derec_protocol_new`]. `info_json_ptr`/`info_json_len` must
|
|
1629
|
+
* describe a readable byte range. Concurrent calls on the same
|
|
1630
|
+
* handle from different threads are safe: the handle's internal
|
|
1631
|
+
* mutex serializes them.
|
|
1632
|
+
*/
|
|
1633
|
+
struct DeRecError derec_protocol_set_communication_info(struct DeRecProtocolHandle *handle,
|
|
1634
|
+
const uint8_t *info_json_ptr,
|
|
1635
|
+
size_t info_json_len);
|
|
1636
|
+
|
|
1637
|
+
/**
|
|
1638
|
+
* Replace this node's local transport endpoint. See
|
|
1639
|
+
* [`crate::protocol::DeRecProtocol::set_own_transport`] for the
|
|
1640
|
+
* changeover discipline (keep the old endpoint up during the
|
|
1641
|
+
* transition).
|
|
1642
|
+
*
|
|
1643
|
+
* # Safety
|
|
1644
|
+
*
|
|
1645
|
+
* `handle` must be a valid pointer returned by
|
|
1646
|
+
* [`super::derec_protocol_new`]. `uri_ptr`/`uri_len` must describe a
|
|
1647
|
+
* readable byte range. The `(uri, protocol)` pair is validated via
|
|
1648
|
+
* [`super::validate_transport`] before it is stored — see that
|
|
1649
|
+
* function's docs for the structural rules (length cap, scheme
|
|
1650
|
+
* match, enum discriminant). Concurrent calls on the same handle
|
|
1651
|
+
* from different threads are safe: the handle's internal mutex
|
|
1652
|
+
* serializes them.
|
|
1653
|
+
*/
|
|
1654
|
+
struct DeRecError derec_protocol_set_own_transport(struct DeRecProtocolHandle *handle,
|
|
1655
|
+
const uint8_t *uri_ptr,
|
|
1656
|
+
size_t uri_len,
|
|
1657
|
+
int32_t protocol);
|
|
1658
|
+
|
|
1659
|
+
/**
|
|
1660
|
+
* Remove `Pending` channels older than `older_than_secs`. See
|
|
1661
|
+
* [`crate::protocol::DeRecProtocol::remove_expired_channels`] for the
|
|
1662
|
+
* semantics, including the strict `>` age boundary.
|
|
1663
|
+
*
|
|
1664
|
+
* # Safety
|
|
1665
|
+
*
|
|
1666
|
+
* `handle` must be a valid pointer returned by
|
|
1667
|
+
* [`super::derec_protocol_new`]. Concurrent calls on the same handle
|
|
1668
|
+
* from different threads are safe: the handle's internal mutex
|
|
1669
|
+
* serializes them.
|
|
1670
|
+
*/
|
|
1671
|
+
struct DeRecRemovedChannelsResult derec_protocol_remove_expired_channels(struct DeRecProtocolHandle *handle,
|
|
1672
|
+
uint64_t older_than_secs);
|
|
1673
|
+
|
|
1674
|
+
/**
|
|
1675
|
+
* Start a new flow. `flow_kind` matches the constants in
|
|
1676
|
+
* [`crate::interop::ffi::protocol::flow`]. `params_json_*` is a UTF-8 JSON blob
|
|
1677
|
+
* shaped to the matching `*ParamsJson` struct in that module.
|
|
1678
|
+
*
|
|
1679
|
+
* # Safety
|
|
1680
|
+
*
|
|
1681
|
+
* `handle` must be a valid pointer returned by
|
|
1682
|
+
* [`super::derec_protocol_new`]. `params_json_ptr`/`params_json_len`
|
|
1683
|
+
* must describe a readable byte range.
|
|
1684
|
+
*/
|
|
1685
|
+
struct DeRecProtocolEventsResult derec_protocol_start(struct DeRecProtocolHandle *handle,
|
|
1686
|
+
uint32_t flow_kind,
|
|
1687
|
+
const uint8_t *params_json_ptr,
|
|
1688
|
+
size_t params_json_len);
|
|
1689
|
+
|
|
1690
|
+
/**
|
|
1691
|
+
* Process an inbound `DeRecMessage` envelope. See
|
|
1692
|
+
* [`crate::protocol::DeRecProtocol::process`].
|
|
1693
|
+
*
|
|
1694
|
+
* # Safety
|
|
1695
|
+
*
|
|
1696
|
+
* `handle` must be a valid pointer returned by
|
|
1697
|
+
* [`super::derec_protocol_new`]. `message_ptr`/`message_len` must
|
|
1698
|
+
* describe a readable byte range.
|
|
1699
|
+
*/
|
|
1700
|
+
struct DeRecProtocolEventsResult derec_protocol_process(struct DeRecProtocolHandle *handle,
|
|
1701
|
+
const uint8_t *message_ptr,
|
|
1702
|
+
size_t message_len);
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Advance time-driven state without an inbound message. See
|
|
1706
|
+
* [`crate::protocol::DeRecProtocol::tick`].
|
|
1707
|
+
*
|
|
1708
|
+
* Intended for a scheduler — a timer, a cron job, a queue heartbeat —
|
|
1709
|
+
* in deployments where nothing else would ever evaluate timeouts. Safe
|
|
1710
|
+
* to call on an idle protocol: it returns an empty event array.
|
|
1711
|
+
*
|
|
1712
|
+
* # Safety
|
|
1713
|
+
*
|
|
1714
|
+
* `handle` must be a valid pointer returned by
|
|
1715
|
+
* [`super::derec_protocol_new`].
|
|
1716
|
+
*/
|
|
1717
|
+
struct DeRecProtocolEventsResult derec_protocol_tick(struct DeRecProtocolHandle *handle);
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* Accept a pending action from an `ActionRequired` event. See
|
|
1721
|
+
* [`crate::protocol::DeRecProtocol::accept`]. The `action_bytes` blob
|
|
1722
|
+
* is the exact payload the caller received in the event — the FFI
|
|
1723
|
+
* wire format is the encoding produced by
|
|
1724
|
+
* [`crate::protocol::utils::pending_action_wire::serialize`].
|
|
1725
|
+
*
|
|
1726
|
+
* # Safety
|
|
1727
|
+
*
|
|
1728
|
+
* `handle` must be a valid pointer returned by
|
|
1729
|
+
* [`super::derec_protocol_new`]. `action_ptr`/`action_len` must
|
|
1730
|
+
* describe a readable byte range.
|
|
1731
|
+
*/
|
|
1732
|
+
struct DeRecProtocolEventsResult derec_protocol_accept(struct DeRecProtocolHandle *handle,
|
|
1733
|
+
const uint8_t *action_ptr,
|
|
1734
|
+
size_t action_len);
|
|
1735
|
+
|
|
1736
|
+
/**
|
|
1737
|
+
* Reject a pending action from an `ActionRequired` event. See
|
|
1738
|
+
* [`crate::protocol::DeRecProtocol::reject`]. `status` matches
|
|
1739
|
+
* `derec_proto::StatusEnum` and `memo_ptr`/`memo_len` is an optional
|
|
1740
|
+
* UTF-8 string body (`memo_len == 0` for absent).
|
|
1741
|
+
*
|
|
1742
|
+
* # Safety
|
|
1743
|
+
*
|
|
1744
|
+
* `handle` must be a valid pointer returned by
|
|
1745
|
+
* [`super::derec_protocol_new`]. `action_ptr`/`action_len` must
|
|
1746
|
+
* describe a readable byte range.
|
|
1747
|
+
*/
|
|
1748
|
+
struct DeRecError derec_protocol_reject(struct DeRecProtocolHandle *handle,
|
|
1749
|
+
const uint8_t *action_ptr,
|
|
1750
|
+
size_t action_len,
|
|
1751
|
+
int32_t status,
|
|
1752
|
+
const uint8_t *memo_ptr,
|
|
1753
|
+
size_t memo_len);
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* Rebuild this protocol's `secret_id` namespace from a recovered
|
|
1757
|
+
* `Secret`. See [`crate::protocol::DeRecProtocol::restore`] for the
|
|
1758
|
+
* full contract and error semantics.
|
|
1759
|
+
*
|
|
1760
|
+
* `params_json_*` is a UTF-8 JSON blob of the shape:
|
|
1761
|
+
*
|
|
1762
|
+
* ```json
|
|
1763
|
+
* {
|
|
1764
|
+
* "version": 7,
|
|
1765
|
+
* "recovered_secret": {
|
|
1766
|
+
* "helpers": [{ "channel_id": "11", "transport_uri": "...",
|
|
1767
|
+
* "shared_key": [..32 bytes..],
|
|
1768
|
+
* "communication_info": {} }],
|
|
1769
|
+
* "secrets": [{ "id": [..], "name": "...", "data": [..] }],
|
|
1770
|
+
* "replicas": {
|
|
1771
|
+
* "channel_id": "21",
|
|
1772
|
+
* "members": [{ "replica_id": "51966", "transport_uri": "...",
|
|
1773
|
+
* "role": "Source", "communication_info": {} }],
|
|
1774
|
+
* "shared_key": [..32 bytes..]
|
|
1775
|
+
* }
|
|
1776
|
+
* }
|
|
1777
|
+
* }
|
|
1778
|
+
* ```
|
|
1779
|
+
*
|
|
1780
|
+
* Field names mirror `SecretWire` in `protocol/events/wire.rs` — the
|
|
1781
|
+
* same shape `SecretRecovered` carries. `channel_id` and `replica_id`
|
|
1782
|
+
* are decimal `u64` strings (empty / absent means zero).
|
|
1783
|
+
*
|
|
1784
|
+
* `replicas` is an **object**, not an array, and is omitted entirely when
|
|
1785
|
+
* the `secret_id` has no replica group. Every member of the group shares
|
|
1786
|
+
* the one `channel_id` and the one `shared_key` it carries, so neither is
|
|
1787
|
+
* repeated per member; a member is identified by `replica_id` alone, and
|
|
1788
|
+
* the group's source is the member whose `role` is `"Source"`.
|
|
1789
|
+
*
|
|
1790
|
+
* # Safety
|
|
1791
|
+
*
|
|
1792
|
+
* `handle` must be a valid pointer returned by
|
|
1793
|
+
* [`super::derec_protocol_new`]. `params_json_ptr`/`params_json_len`
|
|
1794
|
+
* must describe a readable byte range.
|
|
1795
|
+
*/
|
|
1796
|
+
struct DeRecProtocolEventsResult derec_protocol_restore(struct DeRecProtocolHandle *handle,
|
|
1797
|
+
const uint8_t *params_json_ptr,
|
|
1798
|
+
size_t params_json_len);
|
|
1799
|
+
|
|
1800
|
+
/**
|
|
1801
|
+
* Derive the human-readable fingerprint for a paired channel. See
|
|
1802
|
+
* [`crate::protocol::DeRecProtocol::get_fingerprint`].
|
|
1803
|
+
*
|
|
1804
|
+
* # Safety
|
|
1805
|
+
*
|
|
1806
|
+
* `handle` must be a valid pointer returned by
|
|
1807
|
+
* [`super::derec_protocol_new`]. Concurrent calls on the same handle
|
|
1808
|
+
* from different threads are safe: the handle's internal mutex
|
|
1809
|
+
* serializes them.
|
|
1810
|
+
*/
|
|
1811
|
+
struct DeRecProtocolFingerprintResult derec_protocol_get_fingerprint(struct DeRecProtocolHandle *handle,
|
|
1812
|
+
uint64_t channel_id);
|
|
1813
|
+
|
|
1814
|
+
/**
|
|
1815
|
+
* Verify a fingerprint against the channel's locally-derived one. See
|
|
1816
|
+
* [`crate::protocol::DeRecProtocol::verify_fingerprint`].
|
|
1817
|
+
*
|
|
1818
|
+
* Writes `*out_matched = 1` if and only if the comparison
|
|
1819
|
+
* affirmatively succeeded. On every other outcome — null-pointer
|
|
1820
|
+
* rejection, malformed UTF-8 in `fingerprint_ptr`, a backend error,
|
|
1821
|
+
* or a legitimate mismatch — `*out_matched` is set to `0`. Callers
|
|
1822
|
+
* MUST also inspect the returned [`DeRecError`] to distinguish a
|
|
1823
|
+
* successful mismatch from a failure that could not produce a
|
|
1824
|
+
* verdict; treating `out_matched == 0` as "definitely not matched"
|
|
1825
|
+
* is safe only after confirming the envelope reports
|
|
1826
|
+
* [`DEREC_CATEGORY_OK`](crate::interop::ffi::error::DEREC_CATEGORY_OK).
|
|
1827
|
+
*
|
|
1828
|
+
* The fail-closed write happens immediately after the null-pointer
|
|
1829
|
+
* check, so a caller that allocates the output on the stack and
|
|
1830
|
+
* reads it without checking the error envelope still gets `0`,
|
|
1831
|
+
* never a stale `1` from uninitialized memory. This neutralizes
|
|
1832
|
+
* the "sloppy caller skips the error envelope and reads stale
|
|
1833
|
+
* stack" footgun on the MITM-protection gate.
|
|
1834
|
+
*
|
|
1835
|
+
* # Safety
|
|
1836
|
+
*
|
|
1837
|
+
* `handle` and `out_matched` must be valid pointers. `fingerprint_ptr`
|
|
1838
|
+
* must be a valid pointer to a NUL-terminated C string. Concurrent
|
|
1839
|
+
* calls on the same handle from different threads are safe: the
|
|
1840
|
+
* handle's internal mutex serializes them.
|
|
1841
|
+
*/
|
|
1842
|
+
struct DeRecError derec_protocol_verify_fingerprint(struct DeRecProtocolHandle *handle,
|
|
1843
|
+
uint64_t channel_id,
|
|
1844
|
+
const char *fingerprint_ptr,
|
|
1845
|
+
uint32_t *out_matched);
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* Generate an out-of-band contact message used to bootstrap pairing.
|
|
1849
|
+
* See [`crate::protocol::DeRecProtocol::create_contact`].
|
|
1850
|
+
*
|
|
1851
|
+
* `has_channel_id == 0` lets the library mint the channel id; `1`
|
|
1852
|
+
* supplies it via `channel_id`.
|
|
1853
|
+
*
|
|
1854
|
+
* # Safety
|
|
1855
|
+
*
|
|
1856
|
+
* `handle` must be a valid pointer returned by
|
|
1857
|
+
* [`super::derec_protocol_new`]. Concurrent calls on the same handle
|
|
1858
|
+
* from different threads are safe: the handle's internal mutex
|
|
1859
|
+
* serializes them.
|
|
1860
|
+
*/
|
|
1861
|
+
struct DeRecProtocolCreateContactResult derec_protocol_create_contact(struct DeRecProtocolHandle *handle,
|
|
1862
|
+
uint32_t has_channel_id,
|
|
1863
|
+
uint64_t channel_id,
|
|
1864
|
+
int32_t contact_mode,
|
|
1865
|
+
uint32_t has_nonce,
|
|
1866
|
+
uint64_t nonce);
|
|
1867
|
+
|
|
1868
|
+
struct DeRecProtocolVersion derec_protocol_version(void);
|
|
1869
|
+
|
|
1870
|
+
/**
|
|
1871
|
+
* # Safety
|
|
1872
|
+
*
|
|
1873
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1874
|
+
*/
|
|
1875
|
+
struct ProduceGetShareRequestMessageResult produce_get_share_request_message(uint64_t channel_id,
|
|
1876
|
+
uint64_t secret_id,
|
|
1877
|
+
uint32_t version,
|
|
1878
|
+
const uint8_t *shared_key_ptr,
|
|
1879
|
+
size_t shared_key_len,
|
|
1880
|
+
const uint8_t *reply_to_ptr,
|
|
1881
|
+
size_t reply_to_len);
|
|
1882
|
+
|
|
1883
|
+
/**
|
|
1884
|
+
* # Safety
|
|
1885
|
+
*
|
|
1886
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1887
|
+
*/
|
|
1888
|
+
struct ExtractGetShareRequestResult extract_get_share_request(const uint8_t *request_ptr,
|
|
1889
|
+
size_t request_len,
|
|
1890
|
+
const uint8_t *shared_key_ptr,
|
|
1891
|
+
size_t shared_key_len);
|
|
1892
|
+
|
|
1893
|
+
/**
|
|
1894
|
+
* `request_proto_ptr` / `request_proto_len` must be the `request_proto_bytes`
|
|
1895
|
+
* returned by [`extract_get_share_request`].
|
|
1896
|
+
*
|
|
1897
|
+
* `stored_share_proto_ptr` / `stored_share_proto_len` must be the serialized
|
|
1898
|
+
* inner `StoreShareRequestMessage` the helper persisted at sharing time —
|
|
1899
|
+
* typically the `request_proto_bytes` returned by `extract_store_share_request`.
|
|
1900
|
+
*
|
|
1901
|
+
* # Safety
|
|
1902
|
+
*
|
|
1903
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1904
|
+
*/
|
|
1905
|
+
struct ProduceGetShareResponseMessageResult produce_get_share_response_message(uint64_t channel_id,
|
|
1906
|
+
const uint8_t *request_proto_ptr,
|
|
1907
|
+
size_t request_proto_len,
|
|
1908
|
+
const uint8_t *stored_share_proto_ptr,
|
|
1909
|
+
size_t stored_share_proto_len,
|
|
1910
|
+
const uint8_t *shared_key_ptr,
|
|
1911
|
+
size_t shared_key_len);
|
|
1912
|
+
|
|
1913
|
+
/**
|
|
1914
|
+
* # Safety
|
|
1915
|
+
*
|
|
1916
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1917
|
+
*/
|
|
1918
|
+
struct ExtractGetShareResponseResult extract_get_share_response(const uint8_t *response_ptr,
|
|
1919
|
+
size_t response_len,
|
|
1920
|
+
const uint8_t *shared_key_ptr,
|
|
1921
|
+
size_t shared_key_len);
|
|
1922
|
+
|
|
1923
|
+
/**
|
|
1924
|
+
* `responses_ptr` / `responses_len` must follow the binary format documented
|
|
1925
|
+
* at the module level.
|
|
1926
|
+
*
|
|
1927
|
+
* # Safety
|
|
1928
|
+
*
|
|
1929
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1930
|
+
*/
|
|
1931
|
+
struct RecoverFromShareResponsesResult recover_from_share_responses(const uint8_t *responses_ptr,
|
|
1932
|
+
size_t responses_len,
|
|
1933
|
+
uint64_t secret_id,
|
|
1934
|
+
uint32_t version);
|
|
1935
|
+
|
|
1936
|
+
/**
|
|
1937
|
+
* # Safety
|
|
1938
|
+
*
|
|
1939
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1940
|
+
*/
|
|
1941
|
+
struct ProtectSecretResult protect_secret(uint64_t secret_id,
|
|
1942
|
+
const uint8_t *secret_data_ptr,
|
|
1943
|
+
size_t secret_data_len,
|
|
1944
|
+
const uint64_t *channels_ptr,
|
|
1945
|
+
size_t channels_len,
|
|
1946
|
+
size_t threshold,
|
|
1947
|
+
uint32_t version);
|
|
1948
|
+
|
|
1949
|
+
/**
|
|
1950
|
+
* # Safety
|
|
1951
|
+
*
|
|
1952
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1953
|
+
*/
|
|
1954
|
+
struct ProduceStoreShareRequestMessageResult produce_store_share_request_message(uint64_t channel_id,
|
|
1955
|
+
uint32_t version,
|
|
1956
|
+
uint64_t secret_id,
|
|
1957
|
+
const uint8_t *committed_share_ptr,
|
|
1958
|
+
size_t committed_share_len,
|
|
1959
|
+
const uint32_t *keep_list_ptr,
|
|
1960
|
+
size_t keep_list_len,
|
|
1961
|
+
const uint8_t *description_ptr,
|
|
1962
|
+
size_t description_len,
|
|
1963
|
+
const uint8_t *shared_key_ptr,
|
|
1964
|
+
size_t shared_key_len,
|
|
1965
|
+
const uint8_t *reply_to_ptr,
|
|
1966
|
+
size_t reply_to_len);
|
|
1967
|
+
|
|
1968
|
+
/**
|
|
1969
|
+
* # Safety
|
|
1970
|
+
*
|
|
1971
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1972
|
+
*/
|
|
1973
|
+
struct ExtractStoreShareRequestResult extract_store_share_request(const uint8_t *request_ptr,
|
|
1974
|
+
size_t request_len,
|
|
1975
|
+
const uint8_t *shared_key_ptr,
|
|
1976
|
+
size_t shared_key_len);
|
|
1977
|
+
|
|
1978
|
+
/**
|
|
1979
|
+
* `request_proto_ptr` / `request_proto_len` must be the `request_proto_bytes`
|
|
1980
|
+
* returned by [`extract_store_share_request`].
|
|
1981
|
+
*
|
|
1982
|
+
* # Safety
|
|
1983
|
+
*
|
|
1984
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1985
|
+
*/
|
|
1986
|
+
struct ProduceStoreShareResponseMessageResult produce_store_share_response_message(uint64_t channel_id,
|
|
1987
|
+
const uint8_t *request_proto_ptr,
|
|
1988
|
+
size_t request_proto_len,
|
|
1989
|
+
const uint8_t *shared_key_ptr,
|
|
1990
|
+
size_t shared_key_len);
|
|
1991
|
+
|
|
1992
|
+
/**
|
|
1993
|
+
* # Safety
|
|
1994
|
+
*
|
|
1995
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
1996
|
+
*/
|
|
1997
|
+
struct ExtractStoreShareResponseResult extract_store_share_response(const uint8_t *response_ptr,
|
|
1998
|
+
size_t response_len,
|
|
1999
|
+
const uint8_t *shared_key_ptr,
|
|
2000
|
+
size_t shared_key_len);
|
|
2001
|
+
|
|
2002
|
+
/**
|
|
2003
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
2004
|
+
* `response_proto_bytes` returned by [`extract_store_share_response`].
|
|
2005
|
+
*
|
|
2006
|
+
* # Safety
|
|
2007
|
+
*
|
|
2008
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2009
|
+
*/
|
|
2010
|
+
struct ProcessStoreShareResponseMessageResult process_store_share_response_message(uint32_t version,
|
|
2011
|
+
const uint8_t *response_proto_ptr,
|
|
2012
|
+
size_t response_proto_len);
|
|
2013
|
+
|
|
2014
|
+
/**
|
|
2015
|
+
* # Safety
|
|
2016
|
+
*
|
|
2017
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2018
|
+
*/
|
|
2019
|
+
struct ProduceUnpairRequestMessageResult produce_unpair_request_message(uint64_t channel_id,
|
|
2020
|
+
const uint8_t *memo_ptr,
|
|
2021
|
+
size_t memo_len,
|
|
2022
|
+
const uint8_t *shared_key_ptr,
|
|
2023
|
+
size_t shared_key_len,
|
|
2024
|
+
const uint8_t *reply_to_ptr,
|
|
2025
|
+
size_t reply_to_len);
|
|
2026
|
+
|
|
2027
|
+
/**
|
|
2028
|
+
* # Safety
|
|
2029
|
+
*
|
|
2030
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2031
|
+
*/
|
|
2032
|
+
struct ExtractUnpairRequestResult extract_unpair_request(const uint8_t *request_ptr,
|
|
2033
|
+
size_t request_len,
|
|
2034
|
+
const uint8_t *shared_key_ptr,
|
|
2035
|
+
size_t shared_key_len);
|
|
2036
|
+
|
|
2037
|
+
/**
|
|
2038
|
+
* # Safety
|
|
2039
|
+
*
|
|
2040
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2041
|
+
*/
|
|
2042
|
+
struct ProduceUnpairResponseMessageResult produce_unpair_response_message(uint64_t channel_id,
|
|
2043
|
+
const uint8_t *shared_key_ptr,
|
|
2044
|
+
size_t shared_key_len);
|
|
2045
|
+
|
|
2046
|
+
/**
|
|
2047
|
+
* # Safety
|
|
2048
|
+
*
|
|
2049
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2050
|
+
*/
|
|
2051
|
+
struct ExtractUnpairResponseResult extract_unpair_response(const uint8_t *response_ptr,
|
|
2052
|
+
size_t response_len,
|
|
2053
|
+
const uint8_t *shared_key_ptr,
|
|
2054
|
+
size_t shared_key_len);
|
|
2055
|
+
|
|
2056
|
+
/**
|
|
2057
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
2058
|
+
* `response_proto_bytes` returned by [`extract_unpair_response`].
|
|
2059
|
+
*
|
|
2060
|
+
* # Safety
|
|
2061
|
+
*
|
|
2062
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2063
|
+
*/
|
|
2064
|
+
struct ProcessUnpairResponseResult process_unpair_response_message(const uint8_t *response_proto_ptr,
|
|
2065
|
+
size_t response_proto_len);
|
|
2066
|
+
|
|
2067
|
+
/**
|
|
2068
|
+
* # Safety
|
|
2069
|
+
*
|
|
2070
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2071
|
+
*/
|
|
2072
|
+
struct ProduceVerifyShareRequestMessageResult produce_verify_share_request_message(uint64_t channel_id,
|
|
2073
|
+
uint64_t secret_id,
|
|
2074
|
+
uint32_t version,
|
|
2075
|
+
const uint8_t *shared_key_ptr,
|
|
2076
|
+
size_t shared_key_len,
|
|
2077
|
+
const uint8_t *reply_to_ptr,
|
|
2078
|
+
size_t reply_to_len);
|
|
2079
|
+
|
|
2080
|
+
/**
|
|
2081
|
+
* # Safety
|
|
2082
|
+
*
|
|
2083
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2084
|
+
*/
|
|
2085
|
+
struct ExtractVerifyShareRequestResult extract_verify_share_request(const uint8_t *request_ptr,
|
|
2086
|
+
size_t request_len,
|
|
2087
|
+
const uint8_t *shared_key_ptr,
|
|
2088
|
+
size_t shared_key_len);
|
|
2089
|
+
|
|
2090
|
+
/**
|
|
2091
|
+
* `request_proto_ptr` / `request_proto_len` must be the `request_proto_bytes`
|
|
2092
|
+
* returned by [`extract_verify_share_request`].
|
|
2093
|
+
*
|
|
2094
|
+
* # Safety
|
|
2095
|
+
*
|
|
2096
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2097
|
+
*/
|
|
2098
|
+
struct ProduceVerifyShareResponseMessageResult produce_verify_share_response_message(uint64_t channel_id,
|
|
2099
|
+
const uint8_t *request_proto_ptr,
|
|
2100
|
+
size_t request_proto_len,
|
|
2101
|
+
const uint8_t *shared_key_ptr,
|
|
2102
|
+
size_t shared_key_len,
|
|
2103
|
+
const uint8_t *share_content_ptr,
|
|
2104
|
+
size_t share_content_len);
|
|
2105
|
+
|
|
2106
|
+
/**
|
|
2107
|
+
* # Safety
|
|
2108
|
+
*
|
|
2109
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2110
|
+
*/
|
|
2111
|
+
struct ExtractVerifyShareResponseResult extract_verify_share_response(const uint8_t *response_ptr,
|
|
2112
|
+
size_t response_len,
|
|
2113
|
+
const uint8_t *shared_key_ptr,
|
|
2114
|
+
size_t shared_key_len);
|
|
2115
|
+
|
|
2116
|
+
/**
|
|
2117
|
+
* Verify a `VerifyShareResponseMessage` against the originating
|
|
2118
|
+
* `VerifyShareRequestMessage` and the expected share content.
|
|
2119
|
+
*
|
|
2120
|
+
* `request_proto_ptr` / `request_proto_len` must carry the proto-
|
|
2121
|
+
* encoded [`derec_proto::VerifyShareRequestMessage`] the **owner**
|
|
2122
|
+
* previously produced for this challenge (kept by the caller in a
|
|
2123
|
+
* per-`channel_id` pending-verification map). The primitive
|
|
2124
|
+
* rejects any response whose `(nonce, secret_id, version)` triple
|
|
2125
|
+
* doesn't match — that's the anti-replay gate.
|
|
2126
|
+
*
|
|
2127
|
+
* `response_proto_ptr` / `response_proto_len` must be the
|
|
2128
|
+
* `response_proto_bytes` returned by [`extract_verify_share_response`].
|
|
2129
|
+
*
|
|
2130
|
+
* # Safety
|
|
2131
|
+
*
|
|
2132
|
+
* Non-null input pointers must point to the corresponding readable byte ranges.
|
|
2133
|
+
*/
|
|
2134
|
+
struct VerifyShareResponseResult process_verify_share_response_message(const uint8_t *request_proto_ptr,
|
|
2135
|
+
size_t request_proto_len,
|
|
2136
|
+
const uint8_t *response_proto_ptr,
|
|
2137
|
+
size_t response_proto_len,
|
|
2138
|
+
const uint8_t *share_content_ptr,
|
|
2139
|
+
size_t share_content_len);
|
|
2140
|
+
|
|
2141
|
+
#ifdef __cplusplus
|
|
2142
|
+
} // extern "C"
|
|
2143
|
+
#endif // __cplusplus
|
|
2144
|
+
|
|
2145
|
+
#endif /* DEREC_FFI_H */
|