@wireapp/core-crypto 0.5.2 → 0.6.0-pre.2
Sign up to get free protection for your applications and to get access to all the features.
package/README.md
CHANGED
@@ -55,9 +55,10 @@ rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
|
|
55
55
|
|
56
56
|
### MacOS
|
57
57
|
|
58
|
-
Install macOS rust targets
|
58
|
+
Install macOS rust targets
|
59
59
|
```ignore
|
60
60
|
rustup target add x86_64-apple-darwin
|
61
|
+
rustup target add aarch64-apple-darwin
|
61
62
|
```
|
62
63
|
|
63
64
|
### Linux
|
package/package.json
CHANGED
Binary file
|
@@ -68,16 +68,6 @@ export declare type ClientId = Uint8Array;
|
|
68
68
|
* Alias for proposal reference. It is a byte array of size 16.
|
69
69
|
*/
|
70
70
|
export declare type ProposalRef = Uint8Array;
|
71
|
-
/**
|
72
|
-
* Alias for an MLS generic commit.
|
73
|
-
* It contains:
|
74
|
-
* * MLS Commit that needs to be fanned out to other (existing) members of the conversation
|
75
|
-
* * (Optional) MLS Welcome message that needs to be fanned out to the clients newly added to the conversation (if any)
|
76
|
-
* * TLS-serialized MLS PublicGroupState (GroupInfo in draft-15) which is required for joining a group by external commit + some metadatas for optimizations
|
77
|
-
* (For final version. Requires to be implemented in the Delivery Service)
|
78
|
-
* This is a freeform, uninspected buffer.
|
79
|
-
*/
|
80
|
-
export declare type TlsCommitBundle = Uint8Array;
|
81
71
|
/**
|
82
72
|
* Data shape for the returned MLS commit & welcome message tuple upon adding clients to a conversation
|
83
73
|
*/
|
@@ -95,11 +85,11 @@ export interface MemberAddedMessages {
|
|
95
85
|
*/
|
96
86
|
welcome: Uint8Array;
|
97
87
|
/**
|
98
|
-
*
|
88
|
+
* MLS PublicGroupState (GroupInfo in draft-15) which is required for joining a group by external commit
|
99
89
|
*
|
100
90
|
* @readonly
|
101
91
|
*/
|
102
|
-
publicGroupState:
|
92
|
+
publicGroupState: PublicGroupStateBundle;
|
103
93
|
}
|
104
94
|
/**
|
105
95
|
* Data shape for a MLS generic commit + optional bundle (aka stapled commit & welcome)
|
@@ -118,11 +108,61 @@ export interface CommitBundle {
|
|
118
108
|
*/
|
119
109
|
welcome?: Uint8Array;
|
120
110
|
/**
|
121
|
-
*
|
111
|
+
* MLS PublicGroupState (GroupInfo in draft-15) which is required for joining a group by external commit
|
122
112
|
*
|
123
113
|
* @readonly
|
124
114
|
*/
|
125
|
-
publicGroupState:
|
115
|
+
publicGroupState: PublicGroupStateBundle;
|
116
|
+
}
|
117
|
+
/**
|
118
|
+
* Wraps a PublicGroupState in order to efficiently upload it to the Delivery Service.
|
119
|
+
* This is not part of MLS protocol but parts might be standardized at some point.
|
120
|
+
*/
|
121
|
+
export interface PublicGroupStateBundle {
|
122
|
+
/**
|
123
|
+
* see {@link PublicGroupStateEncryptionType}
|
124
|
+
*/
|
125
|
+
encryptionType: PublicGroupStateEncryptionType;
|
126
|
+
/**
|
127
|
+
* see {@link RatchetTreeType}
|
128
|
+
*/
|
129
|
+
ratchetTreeType: RatchetTreeType;
|
130
|
+
/**
|
131
|
+
* TLS-serialized PublicGroupState
|
132
|
+
*/
|
133
|
+
payload: Uint8Array;
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Informs whether the PublicGroupState is confidential
|
137
|
+
* see [core_crypto::mls::conversation::public_group_state::PublicGroupStateEncryptionType]
|
138
|
+
*/
|
139
|
+
export declare enum PublicGroupStateEncryptionType {
|
140
|
+
/**
|
141
|
+
* Unencrypted
|
142
|
+
*/
|
143
|
+
Plaintext = 1,
|
144
|
+
/**
|
145
|
+
* Encrypted in a JWE (not yet implemented)
|
146
|
+
*/
|
147
|
+
JweEncrypted = 2
|
148
|
+
}
|
149
|
+
/**
|
150
|
+
* Represents different ways of carrying the Ratchet Tree with some optimizations to save some space
|
151
|
+
* see [core_crypto::mls::conversation::public_group_state::RatchetTreeType]
|
152
|
+
*/
|
153
|
+
export declare enum RatchetTreeType {
|
154
|
+
/**
|
155
|
+
* Complete PublicGroupState
|
156
|
+
*/
|
157
|
+
Full = 1,
|
158
|
+
/**
|
159
|
+
* Contains the difference since previous epoch (not yet implemented)
|
160
|
+
*/
|
161
|
+
Delta = 2,
|
162
|
+
/**
|
163
|
+
* To define (not yet implemented)
|
164
|
+
*/
|
165
|
+
ByRef = 3
|
126
166
|
}
|
127
167
|
/**
|
128
168
|
* Params for CoreCrypto initialization
|
@@ -166,19 +206,26 @@ export interface Invitee {
|
|
166
206
|
*/
|
167
207
|
kp: Uint8Array;
|
168
208
|
}
|
169
|
-
export interface
|
209
|
+
export interface ConversationInitBundle {
|
170
210
|
/**
|
171
|
-
*
|
211
|
+
* Conversation ID of the conversation created
|
172
212
|
*
|
173
213
|
* @readonly
|
174
214
|
*/
|
175
|
-
|
215
|
+
conversationId: ConversationId;
|
176
216
|
/**
|
177
|
-
* TLS-serialized MLS Commit that needs to be fanned out
|
217
|
+
* TLS-serialized MLS External Commit that needs to be fanned out
|
178
218
|
*
|
179
219
|
* @readonly
|
180
220
|
*/
|
181
221
|
commit: Uint8Array;
|
222
|
+
/**
|
223
|
+
* MLS Public Group State (aka Group Info) which becomes valid when the external commit is accepted by the Delivery Service
|
224
|
+
* with {@link CoreCrypto.mergePendingGroupFromExternalCommit}
|
225
|
+
*
|
226
|
+
* @readonly
|
227
|
+
*/
|
228
|
+
publicGroupState: PublicGroupStateBundle;
|
182
229
|
}
|
183
230
|
/**
|
184
231
|
* This is a wrapper for all the possible outcomes you can get after decrypting a message
|
@@ -207,6 +254,10 @@ export interface DecryptedMessage {
|
|
207
254
|
* Client identifier of the sender of the message being decrypted. Only present for application messages.
|
208
255
|
*/
|
209
256
|
senderClientId?: ClientId;
|
257
|
+
/**
|
258
|
+
* true when the decrypted message resulted in an epoch change i.e. it was a commit
|
259
|
+
*/
|
260
|
+
hasEpochChanged: boolean;
|
210
261
|
}
|
211
262
|
/**
|
212
263
|
* Returned by all methods creating proposals. Contains a proposal message and an identifier to roll back the proposal
|
@@ -305,7 +356,7 @@ export interface CoreCryptoCallbacks {
|
|
305
356
|
* in the given conversationId. Think of it as a "isAdmin" callback conceptually
|
306
357
|
*
|
307
358
|
* This callback exists because there are many business cases where CoreCrypto doesn't have enough knowledge
|
308
|
-
* (such as what can
|
359
|
+
* (such as what can exist on a backend) to inform the decision
|
309
360
|
*
|
310
361
|
* @param conversationId - id of the group/conversation
|
311
362
|
* @param clientId - id of the client performing an operation requiring authorization
|
@@ -313,10 +364,25 @@ export interface CoreCryptoCallbacks {
|
|
313
364
|
*/
|
314
365
|
authorize: (conversationId: Uint8Array, clientId: Uint8Array) => boolean;
|
315
366
|
/**
|
316
|
-
*
|
367
|
+
* A mix between {@link authorize} and {@link clientIsExistingGroupUser}. We currently use this callback to verify
|
368
|
+
* external commits to join a group ; in such case, the client has to:
|
369
|
+
* * first, belong to a user which is already in the MLS group (similar to {@link clientIsExistingGroupUser})
|
370
|
+
* * then, this user should be authorized to "write" in the given conversation (similar to {@link authorize})
|
371
|
+
*
|
372
|
+
* @param conversationId - id of the group/conversation
|
373
|
+
* @param externalClientId - id of the client performing an operation requiring authorization
|
374
|
+
* @param existingClients - all the clients currently within the MLS group
|
375
|
+
* @returns true if the external client is authorized to write to the conversation
|
376
|
+
*/
|
377
|
+
userAuthorize: (conversationId: Uint8Array, externalClientId: Uint8Array, existingClients: Uint8Array[]) => boolean;
|
378
|
+
/**
|
379
|
+
* Callback to ensure that the given `clientId` belongs to one of the provided `existingClients`
|
317
380
|
* This basically allows to defer the client ID parsing logic to the caller - because CoreCrypto is oblivious to such things
|
381
|
+
*
|
382
|
+
* @param clientId - id of a client
|
383
|
+
* @param existingClients - all the clients currently within the MLS group
|
318
384
|
*/
|
319
|
-
|
385
|
+
clientIsExistingGroupUser: (clientId: Uint8Array, existingClients: Uint8Array[]) => boolean;
|
320
386
|
}
|
321
387
|
/**
|
322
388
|
* Wrapper for the WASM-compiled version of CoreCrypto
|
@@ -515,72 +581,6 @@ export declare class CoreCrypto {
|
|
515
581
|
* @returns A {@link CommitBundle} or `undefined` when there was no pending proposal to commit
|
516
582
|
*/
|
517
583
|
commitPendingProposals(conversationId: ConversationId): Promise<CommitBundle | undefined>;
|
518
|
-
/**
|
519
|
-
* Adds new clients to a conversation, assuming the current client has the right to add new clients to the conversation.
|
520
|
-
* The returned {@link CommitBundle} is a TLS struct that needs to be fanned out to Delivery Service in order to validate the commit.
|
521
|
-
* It also contains a Welcome message the Delivery Service will forward to invited clients and
|
522
|
-
* an updated PublicGroupState required by clients willing to join the group by an external commit.
|
523
|
-
*
|
524
|
-
* **CAUTION**: {@link CoreCrypto.commitAccepted} **HAS TO** be called afterwards **ONLY IF** the Delivery Service responds
|
525
|
-
* '200 OK' to the {@link CommitBundle} upload. It will "merge" the commit locally i.e. increment the local group
|
526
|
-
* epoch, use new encryption secrets etc...
|
527
|
-
*
|
528
|
-
* @param conversationId - The ID of the conversation
|
529
|
-
* @param clients - Array of {@link Invitee} (which are Client ID / KeyPackage pairs)
|
530
|
-
*
|
531
|
-
* @returns A {@link CommitBundle} byte array to fan out to the Delivery Service
|
532
|
-
*/
|
533
|
-
finalAddClientsToConversation(conversationId: ConversationId, clients: Invitee[]): Promise<TlsCommitBundle>;
|
534
|
-
/**
|
535
|
-
* Removes the provided clients from a conversation; Assuming those clients exist and the current client is allowed
|
536
|
-
* to do so, otherwise this operation does nothing.
|
537
|
-
*
|
538
|
-
* The returned {@link CommitBundle} is a TLS struct that needs to be fanned out to Delivery Service in order to validate the commit.
|
539
|
-
* It also contains a Welcome message the Delivery Service will forward to invited clients and
|
540
|
-
* an updated PublicGroupState required by clients willing to join the group by an external commit.
|
541
|
-
*
|
542
|
-
* **CAUTION**: {@link CoreCrypto.commitAccepted} **HAS TO** be called afterwards **ONLY IF** the Delivery Service responds
|
543
|
-
* '200 OK' to the {@link CommitBundle} upload. It will "merge" the commit locally i.e. increment the local group
|
544
|
-
* epoch, use new encryption secrets etc...
|
545
|
-
*
|
546
|
-
* @param conversationId - The ID of the conversation
|
547
|
-
* @param clientIds - Array of Client IDs to remove.
|
548
|
-
*
|
549
|
-
* @returns A {@link CommitBundle} byte array to fan out to the Delivery Service, or `undefined` if for any reason, the operation would result in an empty commit
|
550
|
-
*/
|
551
|
-
finalRemoveClientsFromConversation(conversationId: ConversationId, clientIds: ClientId[]): Promise<TlsCommitBundle>;
|
552
|
-
/**
|
553
|
-
* Creates an update commit which forces every client to update their keypackages in the conversation
|
554
|
-
*
|
555
|
-
* The returned {@link CommitBundle} is a TLS struct that needs to be fanned out to Delivery Service in order to validate the commit.
|
556
|
-
* It also contains a Welcome message the Delivery Service will forward to invited clients and
|
557
|
-
* an updated PublicGroupState required by clients willing to join the group by an external commit.
|
558
|
-
*
|
559
|
-
* **CAUTION**: {@link CoreCrypto.commitAccepted} **HAS TO** be called afterwards **ONLY IF** the Delivery Service responds
|
560
|
-
* '200 OK' to the {@link CommitBundle} upload. It will "merge" the commit locally i.e. increment the local group
|
561
|
-
* epoch, use new encryption secrets etc...
|
562
|
-
*
|
563
|
-
* @param conversationId - The ID of the conversation
|
564
|
-
*
|
565
|
-
* @returns A {@link CommitBundle} byte array to fan out to the Delivery Service
|
566
|
-
*/
|
567
|
-
finalUpdateKeyingMaterial(conversationId: ConversationId): Promise<TlsCommitBundle>;
|
568
|
-
/**
|
569
|
-
* Commits the local pending proposals and returns the {@link CommitBundle} object containing what can result from this operation.
|
570
|
-
*
|
571
|
-
* The returned {@link CommitBundle} is a TLS struct that needs to be fanned out to Delivery Service in order to validate the commit.
|
572
|
-
* It also contains a Welcome message the Delivery Service will forward to invited clients and
|
573
|
-
* an updated PublicGroupState required by clients willing to join the group by an external commit.
|
574
|
-
*
|
575
|
-
* **CAUTION**: {@link CoreCrypto.commitAccepted} **HAS TO** be called afterwards **ONLY IF** the Delivery Service responds
|
576
|
-
* '200 OK' to the {@link CommitBundle} upload. It will "merge" the commit locally i.e. increment the local group
|
577
|
-
* epoch, use new encryption secrets etc...
|
578
|
-
*
|
579
|
-
* @param conversationId - The ID of the conversation
|
580
|
-
*
|
581
|
-
* @returns A {@link CommitBundle} byte array to fan out to the Delivery Service or `undefined` when there was no pending proposal to commit
|
582
|
-
*/
|
583
|
-
finalCommitPendingProposals(conversationId: ConversationId): Promise<TlsCommitBundle | undefined>;
|
584
584
|
/**
|
585
585
|
* Creates a new proposal for the provided Conversation ID
|
586
586
|
*
|
@@ -599,23 +599,35 @@ export declare class CoreCrypto {
|
|
599
599
|
*/
|
600
600
|
exportGroupState(conversationId: ConversationId): Promise<Uint8Array>;
|
601
601
|
/**
|
602
|
-
* Allows to create an external commit to "apply" to join a group through its public group state
|
602
|
+
* Allows to create an external commit to "apply" to join a group through its public group state.
|
603
603
|
*
|
604
|
-
*
|
604
|
+
* If the Delivery Service accepts the external commit, you have to {@link CoreCrypto.mergePendingGroupFromExternalCommit}
|
605
|
+
* in order to get back a functional MLS group. On the opposite, if it rejects it, you can either retry by just
|
606
|
+
* calling again {@link CoreCrypto.joinByExternalCommit}, no need to {@link CoreCrypto.clearPendingGroupFromExternalCommit}.
|
607
|
+
* If you want to abort the operation (too many retries or the user decided to abort), you can use
|
608
|
+
* {@link CoreCrypto.clearPendingGroupFromExternalCommit} in order not to bloat the user's storage but nothing
|
609
|
+
* bad can happen if you forget to except some storage space wasted.
|
605
610
|
*
|
606
|
-
* @param publicGroupState -
|
607
|
-
* @returns see {@link
|
611
|
+
* @param publicGroupState - a TLS encoded PublicGroupState fetched from the Delivery Service
|
612
|
+
* @returns see {@link ConversationInitBundle}
|
608
613
|
*/
|
609
|
-
joinByExternalCommit(publicGroupState: Uint8Array): Promise<
|
614
|
+
joinByExternalCommit(publicGroupState: Uint8Array): Promise<ConversationInitBundle>;
|
610
615
|
/**
|
611
|
-
* This
|
612
|
-
*
|
613
|
-
* This step makes the group operational and ready to encrypt/decrypt message
|
616
|
+
* This merges the commit generated by {@link CoreCrypto.joinByExternalCommit}, persists the group permanently
|
617
|
+
* and deletes the temporary one. This step makes the group operational and ready to encrypt/decrypt message
|
614
618
|
*
|
615
619
|
* @param conversationId - The ID of the conversation
|
616
620
|
* @param configuration - Configuration of the group, see {@link ConversationConfiguration}
|
617
621
|
*/
|
618
622
|
mergePendingGroupFromExternalCommit(conversationId: ConversationId, configuration: ConversationConfiguration): Promise<void>;
|
623
|
+
/**
|
624
|
+
* In case the external commit generated by {@link CoreCrypto.joinByExternalCommit} is rejected by the Delivery Service, and we
|
625
|
+
* want to abort this external commit once for all, we can wipe out the pending group from the keystore in order
|
626
|
+
* not to waste space
|
627
|
+
*
|
628
|
+
* @param conversationId - The ID of the conversation
|
629
|
+
*/
|
630
|
+
clearPendingGroupFromExternalCommit(conversationId: ConversationId): Promise<void>;
|
619
631
|
/**
|
620
632
|
* Allows to mark the latest commit produced as "accepted" and be able to safely merge it
|
621
633
|
* into the local group state
|
@@ -646,6 +658,24 @@ export declare class CoreCrypto {
|
|
646
658
|
* @param conversationId - The group's ID
|
647
659
|
*/
|
648
660
|
clearPendingCommit(conversationId: ConversationId): Promise<void>;
|
661
|
+
/**
|
662
|
+
* Derives a new key from the group
|
663
|
+
*
|
664
|
+
* @param conversationId - The group's ID
|
665
|
+
* @param keyLength - the length of the key to be derived. If the value is higher than the
|
666
|
+
* bounds of `u16` or the context hash * 255, an error will be returned
|
667
|
+
*
|
668
|
+
* @returns A `Uint8Array` representing the derived key
|
669
|
+
*/
|
670
|
+
exportSecretKey(conversationId: ConversationId, keyLength: number): Promise<Uint8Array>;
|
671
|
+
/**
|
672
|
+
* Returns all clients from group's members
|
673
|
+
*
|
674
|
+
* @param conversationId - The group's ID
|
675
|
+
*
|
676
|
+
* @returns A list of clients from the members of the group
|
677
|
+
*/
|
678
|
+
getClientIds(conversationId: ConversationId): Promise<ClientId[]>;
|
649
679
|
/**
|
650
680
|
* Allows {@link CoreCrypto} to act as a CSPRNG provider
|
651
681
|
* @note The underlying CSPRNG algorithm is ChaCha20 and takes in account the external seed provider either at init time or provided with {@link CoreCrypto.reseedRng}
|
@@ -661,6 +691,82 @@ export declare class CoreCrypto {
|
|
661
691
|
* @param seed - **exactly 32** bytes buffer seed
|
662
692
|
*/
|
663
693
|
reseedRng(seed: Uint8Array): Promise<void>;
|
694
|
+
/**
|
695
|
+
* Initiailizes the proteus client
|
696
|
+
*/
|
697
|
+
proteusInit(): Promise<void>;
|
698
|
+
/**
|
699
|
+
* Create a Proteus session using a prekey
|
700
|
+
*
|
701
|
+
* @param sessionId - ID of the Proteus session
|
702
|
+
* @param prekey - CBOR-encoded Proteus prekey of the other client
|
703
|
+
*/
|
704
|
+
proteusSessionFromPrekey(sessionId: string, prekey: Uint8Array): Promise<void>;
|
705
|
+
/**
|
706
|
+
* Create a Proteus session from a handshake message
|
707
|
+
*
|
708
|
+
* @param sessionId - ID of the Proteus session
|
709
|
+
* @param envelope - CBOR-encoded Proteus message
|
710
|
+
*/
|
711
|
+
proteusSessionFromMessage(sessionId: string, envelope: Uint8Array): Promise<void>;
|
712
|
+
/**
|
713
|
+
* Locally persists a session to the keystore
|
714
|
+
*
|
715
|
+
* @param sessionId - ID of the Proteus session
|
716
|
+
*/
|
717
|
+
proteusSessionSave(sessionId: string): Promise<void>;
|
718
|
+
/**
|
719
|
+
* Deletes a session
|
720
|
+
* Note: this also deletes the persisted data within the keystore
|
721
|
+
*
|
722
|
+
* @param sessionId - ID of the Proteus session
|
723
|
+
*/
|
724
|
+
proteusSessionDelete(sessionId: string): Promise<void>;
|
725
|
+
/**
|
726
|
+
* Decrypt an incoming message for an existing Proteus session
|
727
|
+
*
|
728
|
+
* @param sessionId - ID of the Proteus session
|
729
|
+
* @param ciphertext - CBOR encoded, encrypted proteus message
|
730
|
+
* @returns The decrypted payload contained within the message
|
731
|
+
*/
|
732
|
+
proteusDecrypt(sessionId: string, ciphertext: Uint8Array): Promise<Uint8Array>;
|
733
|
+
/**
|
734
|
+
* Encrypt a message for a given Proteus session
|
735
|
+
*
|
736
|
+
* @param sessionId - ID of the Proteus session
|
737
|
+
* @param plaintext - payload to encrypt
|
738
|
+
* @returns The CBOR-serialized encrypted message
|
739
|
+
*/
|
740
|
+
proteusEncrypt(sessionId: string, plaintext: Uint8Array): Promise<Uint8Array>;
|
741
|
+
/**
|
742
|
+
* Batch encryption for proteus messages
|
743
|
+
* This is used to minimize FFI roundtrips when used in the context of a multi-client session (i.e. conversation)
|
744
|
+
*
|
745
|
+
* @param sessions - List of Proteus session IDs to encrypt the message for
|
746
|
+
* @param plaintext - payload to encrypt
|
747
|
+
* @returns A map indexed by each session ID and the corresponding CBOR-serialized encrypted message for this session
|
748
|
+
*/
|
749
|
+
proteusEncryptBatched(sessions: string[], plaintext: Uint8Array): Promise<Map<string, Uint8Array>>;
|
750
|
+
/**
|
751
|
+
* Creates a new prekey with the requested ID.
|
752
|
+
*
|
753
|
+
* @param prekeyId - ID of the PreKey to generate. This cannot be bigger than a u16
|
754
|
+
* @returns: A CBOR-serialized version of the PreKeyBundle corresponding to the newly generated and stored PreKey
|
755
|
+
*/
|
756
|
+
proteusNewPrekey(prekeyId: number): Promise<Uint8Array>;
|
757
|
+
/**
|
758
|
+
* Proteus public key fingerprint
|
759
|
+
* It's basically the public key encoded as an hex string
|
760
|
+
*
|
761
|
+
* @returns Hex-encoded public key string
|
762
|
+
*/
|
763
|
+
proteusFingerprint(): Promise<string>;
|
764
|
+
/**
|
765
|
+
* Imports all the data stored by Cryptobox into the CoreCrypto keystore
|
766
|
+
*
|
767
|
+
* @param storeName - The name of the IndexedDB store where the data is stored
|
768
|
+
*/
|
769
|
+
proteusCryptoboxMigrate(storeName: string): Promise<void>;
|
664
770
|
/**
|
665
771
|
* Returns the current version of {@link CoreCrypto}
|
666
772
|
*
|