1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MLSTransactionParent.h"
8 #include "MLSTransactionMessage.h"
9 #include "mozilla/dom/quota/QuotaManager.h"
10 #include "mozilla/security/mls/mls_gk_ffi_generated.h"
11 #include "MLSLogging.h"
12 #include "mozilla/Base64.h"
15 #include "nsIPrincipal.h"
19 using mozilla::dom::quota::QuotaManager
;
21 namespace mozilla::dom
{
23 /* static */ nsresult
MLSTransactionParent::CreateDirectoryIfNotExists(
25 nsresult rv
= aDir
->Create(nsIFile::DIRECTORY_TYPE
, 0755);
26 if (rv
== NS_ERROR_FILE_ALREADY_EXISTS
) {
27 // Evaluate if the file is a directory
28 bool isDirectory
= false;
29 rv
= aDir
->IsDirectory(&isDirectory
);
30 if (NS_WARN_IF(NS_FAILED(rv
))) {
34 // Check if the file is actually a directory
36 return NS_ERROR_FILE_NOT_DIRECTORY
;
43 /* static */ nsresult
MLSTransactionParent::ConstructDatabasePrefixPath(
44 nsCOMPtr
<nsIFile
>& aFile
) {
45 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
46 ("MLSTransactionParent::ConstructDatabasePath()"));
48 // Get the base path from the quota manager
49 QuotaManager
* quotaManager
= QuotaManager::Get();
50 if (NS_WARN_IF(!quotaManager
)) {
51 return NS_ERROR_FAILURE
;
54 // Create an nsIFile object from the path
56 NS_NewLocalFile(quotaManager
->GetBasePath(), getter_AddRefs(aFile
));
57 if (NS_WARN_IF(NS_FAILED(rv
))) {
61 // Append the hardcoded "mls" directory name to the path
62 rv
= aFile
->AppendNative("mls"_ns
);
63 if (NS_WARN_IF(NS_FAILED(rv
))) {
70 /* static */ nsresult
MLSTransactionParent::ConstructDatabaseFullPath(
71 nsCOMPtr
<nsIFile
>& aFile
, nsIPrincipal
* aPrincipal
,
72 nsCString
& aDatabasePath
) {
73 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
74 ("MLSTransactionParent::ConstructDatabaseFullPath()"));
76 // Get StorageOriginKey
77 nsAutoCString originKey
;
78 nsresult rv
= aPrincipal
->GetStorageOriginKey(originKey
);
79 if (NS_WARN_IF(NS_FAILED(rv
))) {
84 nsAutoCString originAttrSuffix
;
85 rv
= aPrincipal
->GetOriginSuffix(originAttrSuffix
);
86 if (NS_WARN_IF(NS_FAILED(rv
))) {
90 // Set the base path and origin
91 nsAutoCString origin
= originKey
+ originAttrSuffix
;
93 // Encode the origin with its suffix
94 nsAutoCString encodedOrigin
;
95 rv
= mozilla::Base64Encode(origin
, encodedOrigin
);
96 if (NS_WARN_IF(NS_FAILED(rv
))) {
100 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
101 ("MLSTransactionParent::ConstructDatabasePath() - origin: %s",
104 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
105 ("MLSTransactionParent::ConstructDatabasePath() - encodedOrigin: "
107 encodedOrigin
.get()));
109 // Append the origin to the path
110 rv
= aFile
->AppendNative(encodedOrigin
);
111 if (NS_WARN_IF(NS_FAILED(rv
))) {
115 // Get the updated path back into the nsCString
116 nsAutoString databasePathUTF16
;
117 rv
= aFile
->GetPath(databasePathUTF16
);
118 if (NS_WARN_IF(NS_FAILED(rv
))) {
122 aDatabasePath
= NS_ConvertUTF16toUTF8(databasePathUTF16
);
123 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
124 ("MLSTransactionParent::ConstructDatabasePath() - databasePath: %s",
125 aDatabasePath
.get()));
130 void MLSTransactionParent::ActorDestroy(ActorDestroyReason
) {
131 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
132 ("MLSTransactionParent::ActorDestroy()"));
135 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestStateDelete(
136 RequestStateDeleteResolver
&& aResolver
) {
137 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
138 ("MLSTransactionParent::RecvRequestStateDelete()"));
140 // Call to the MLS rust code
141 nsresult rv
= security::mls::mls_state_delete(&mDatabasePath
);
143 aResolver(NS_SUCCEEDED(rv
));
147 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupStateDelete(
148 const nsTArray
<uint8_t>& aGroupIdentifier
,
149 const nsTArray
<uint8_t>& aIdentifier
,
150 RequestGroupStateDeleteResolver
&& aResolver
) {
151 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
152 ("MLSTransactionParent::RecvRequestGroupStateDelete()"));
154 // Call to the MLS rust code
155 security::mls::GkGroupIdEpoch groupIdEpoch
;
156 nsresult rv
= security::mls::mls_state_delete_group(
157 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
158 aIdentifier
.Elements(), aIdentifier
.Length(), &groupIdEpoch
);
160 // Return Nothing if failed
161 if (NS_WARN_IF(NS_FAILED(rv
))) {
162 aResolver(Nothing());
166 // Return the result if success
167 aResolver(Some(std::move(groupIdEpoch
)));
171 mozilla::ipc::IPCResult
172 MLSTransactionParent::RecvRequestGenerateIdentityKeypair(
173 RequestGenerateIdentityKeypairResolver
&& aResolver
) {
174 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
175 ("MLSTransactionParent::RecvRequestGenerateIdentityKeypair()"));
177 // Call to the MLS rust code
178 nsTArray
<uint8_t> signatureIdentifier
;
179 nsresult rv
= security::mls::mls_generate_signature_keypair(
180 &mDatabasePath
, &signatureIdentifier
);
182 // Return Nothing if failed
183 if (NS_WARN_IF(NS_FAILED(rv
))) {
184 aResolver(Nothing());
188 // Return the result if success
189 aResolver(Some(RawBytes
{std::move(signatureIdentifier
)}));
193 mozilla::ipc::IPCResult
194 MLSTransactionParent::RecvRequestGenerateCredentialBasic(
195 const nsTArray
<uint8_t>& aCredContent
,
196 RequestGenerateCredentialBasicResolver
&& aResolver
) {
197 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
198 ("MLSTransactionParent::RecvRequestGenerateCredentialBasic()"));
200 // Call to the MLS rust code
201 nsTArray
<uint8_t> credential
;
202 nsresult rv
= security::mls::mls_generate_credential_basic(
203 aCredContent
.Elements(), aCredContent
.Length(), &credential
);
205 // Return Nothing if failed
206 if (NS_WARN_IF(NS_FAILED(rv
))) {
207 aResolver(Nothing());
211 // Return the result if success
212 aResolver(Some(RawBytes
{std::move(credential
)}));
217 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGenerateKeyPackage(
218 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aCredential
,
219 RequestGenerateKeyPackageResolver
&& aResolver
) {
220 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
221 ("MLSTransactionParent::RecvRequestGenerateKeyPackage()"));
223 // Call to the MLS rust code
224 nsTArray
<uint8_t> keyPackage
;
225 nsresult rv
= security::mls::mls_generate_keypackage(
226 &mDatabasePath
, aIdentifier
.Elements(), aIdentifier
.Length(),
227 aCredential
.Elements(), aCredential
.Length(), &keyPackage
);
229 // Return Nothing if failed
231 aResolver(Nothing());
235 // Return the result if success
236 aResolver(Some(RawBytes
{std::move(keyPackage
)}));
241 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupCreate(
242 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aCredential
,
243 const nsTArray
<uint8_t>& aInOptGroupIdentifier
,
244 RequestGroupCreateResolver
&& aResolver
) {
245 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
246 ("MLSTransactionParent::RecvRequestGroupCreate()"));
248 // Call to the MLS rust code
249 security::mls::GkGroupIdEpoch groupIdEpoch
;
250 nsresult rv
= security::mls::mls_group_create(
251 &mDatabasePath
, aIdentifier
.Elements(), aIdentifier
.Length(),
252 aCredential
.Elements(), aCredential
.Length(),
253 aInOptGroupIdentifier
.Elements(), aInOptGroupIdentifier
.Length(),
256 // Return Nothing if failed
257 if (NS_WARN_IF(NS_FAILED(rv
))) {
258 aResolver(Nothing());
262 // Return the result if success
263 aResolver(Some(std::move(groupIdEpoch
)));
268 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupJoin(
269 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aWelcome
,
270 RequestGroupJoinResolver
&& aResolver
) {
271 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
272 ("MLSTransactionParent::RecvRequestGroupJoin()"));
274 // Call to the MLS rust code
275 security::mls::GkGroupIdEpoch groupIdEpoch
;
276 nsresult rv
= security::mls::mls_group_join(
277 &mDatabasePath
, aIdentifier
.Elements(), aIdentifier
.Length(),
278 aWelcome
.Elements(), aWelcome
.Length(), &groupIdEpoch
);
280 // Return Nothing if failed
281 if (NS_WARN_IF(NS_FAILED(rv
))) {
282 aResolver(Nothing());
286 // Return the result if success
287 aResolver(Some(std::move(groupIdEpoch
)));
292 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupAdd(
293 const nsTArray
<uint8_t>& aGroupIdentifier
,
294 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aKeyPackage
,
295 RequestGroupAddResolver
&& aResolver
) {
296 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
297 ("MLSTransactionParent::RecvRequestGroupAdd()"));
299 // Call to the MLS rust code
300 security::mls::GkMlsCommitOutput commitOutput
;
301 nsresult rv
= security::mls::mls_group_add(
302 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
303 aIdentifier
.Elements(), aIdentifier
.Length(), aKeyPackage
.Elements(),
304 aKeyPackage
.Length(), &commitOutput
);
306 // Return Nothing if failed
307 if (NS_WARN_IF(NS_FAILED(rv
))) {
308 aResolver(Nothing());
312 // Return the result if success
313 aResolver(Some(std::move(commitOutput
)));
318 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupProposeAdd(
319 const nsTArray
<uint8_t>& aGroupIdentifier
,
320 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aKeyPackage
,
321 RequestGroupProposeAddResolver
&& aResolver
) {
322 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
323 ("MLSTransactionParent::RecvRequestGroupProposeAdd()"));
325 // Call to the MLS rust code
326 nsTArray
<uint8_t> proposal
;
327 nsresult rv
= security::mls::mls_group_propose_add(
328 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
329 aIdentifier
.Elements(), aIdentifier
.Length(), aKeyPackage
.Elements(),
330 aKeyPackage
.Length(), &proposal
);
332 // Return Nothing if failed
333 if (NS_WARN_IF(NS_FAILED(rv
))) {
334 aResolver(Nothing());
338 // Return the result if success
339 aResolver(Some(RawBytes
{std::move(proposal
)}));
344 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupRemove(
345 const nsTArray
<uint8_t>& aGroupIdentifier
,
346 const nsTArray
<uint8_t>& aIdentifier
,
347 const nsTArray
<uint8_t>& aRemIdentifier
,
348 RequestGroupRemoveResolver
&& aResolver
) {
349 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
350 ("MLSTransactionParent::RecvRequestGroupRemove()"));
352 // Call to the MLS rust code
353 security::mls::GkMlsCommitOutput commitOutput
;
354 nsresult rv
= security::mls::mls_group_remove(
355 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
356 aIdentifier
.Elements(), aIdentifier
.Length(), aRemIdentifier
.Elements(),
357 aRemIdentifier
.Length(), &commitOutput
);
359 // Return Nothing if failed
360 if (NS_WARN_IF(NS_FAILED(rv
))) {
361 aResolver(Nothing());
365 // Return the result if success
366 aResolver(Some(std::move(commitOutput
)));
371 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupProposeRemove(
372 const nsTArray
<uint8_t>& aGroupIdentifier
,
373 const nsTArray
<uint8_t>& aIdentifier
,
374 const nsTArray
<uint8_t>& aRemIdentifier
,
375 RequestGroupProposeRemoveResolver
&& aResolver
) {
376 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
377 ("MLSTransactionParent::RecvRequestGroupProposeRemove()"));
379 nsTArray
<uint8_t> proposal
;
380 nsresult rv
= security::mls::mls_group_propose_remove(
381 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
382 aIdentifier
.Elements(), aIdentifier
.Length(), aRemIdentifier
.Elements(),
383 aRemIdentifier
.Length(), &proposal
);
385 // Return Nothing if failed
386 if (NS_WARN_IF(NS_FAILED(rv
))) {
387 aResolver(Nothing());
391 // Return the result if success
392 aResolver(Some(RawBytes
{std::move(proposal
)}));
397 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupClose(
398 const nsTArray
<uint8_t>& aGroupIdentifier
,
399 const nsTArray
<uint8_t>& aIdentifier
,
400 RequestGroupCloseResolver
&& aResolver
) {
401 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
402 ("MLSTransactionParent::RecvRequestGroupClose()"));
404 // Call to the MLS rust code
405 security::mls::GkMlsCommitOutput commitOutput
;
406 nsresult rv
= security::mls::mls_group_close(
407 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
408 aIdentifier
.Elements(), aIdentifier
.Length(), &commitOutput
);
410 // Return Nothing if failed
411 if (NS_WARN_IF(NS_FAILED(rv
))) {
412 aResolver(Nothing());
416 // Return the result if success
417 aResolver(Some(std::move(commitOutput
)));
422 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGroupDetails(
423 const nsTArray
<uint8_t>& aGroupIdentifier
,
424 const nsTArray
<uint8_t>& aIdentifier
,
425 RequestGroupDetailsResolver
&& aResolver
) {
426 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
427 ("MLSTransactionParent::RecvRequestGroupDetails()"));
429 // Call to the MLS rust code
430 security::mls::GkGroupMembers members
;
431 nsresult rv
= security::mls::mls_group_members(
432 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
433 aIdentifier
.Elements(), aIdentifier
.Length(), &members
);
435 // Return Nothing if failed
436 if (NS_WARN_IF(NS_FAILED(rv
))) {
437 aResolver(Nothing());
441 // Return the result if success
442 aResolver(Some(std::move(members
)));
447 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestReceive(
448 const nsTArray
<uint8_t>& aClientIdentifier
,
449 const nsTArray
<uint8_t>& aMessage
, RequestReceiveResolver
&& aResolver
) {
450 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
451 ("MLSTransactionParent::RecvRequestReceive()"));
453 // Call to the MLS rust code
455 nsTArray
<uint8_t> group_id_bytes
;
457 nsresult rv
= security::mls::mls_receive(
458 &mDatabasePath
, aClientIdentifier
.Elements(), aClientIdentifier
.Length(),
459 aMessage
.Elements(), aMessage
.Length(), &group_id_bytes
, &received
);
461 // Return Nothing if failed
462 if (NS_WARN_IF(NS_FAILED(rv
))) {
463 aResolver(GkReceived());
467 // Return the result if success
473 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestApplyPendingCommit(
474 const nsTArray
<uint8_t>& aGroupIdentifier
,
475 const nsTArray
<uint8_t>& aClientIdentifier
,
476 RequestApplyPendingCommitResolver
&& aResolver
) {
477 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
478 ("MLSTransactionParent::RecvRequestApplyPendingCommit()"));
480 // Call to the MLS rust code
482 nsresult rv
= security::mls::mls_receive_ack(
483 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
484 aClientIdentifier
.Elements(), aClientIdentifier
.Length(), &received
);
486 // Return Nothing if failed
487 if (NS_WARN_IF(NS_FAILED(rv
))) {
488 aResolver(GkReceived());
492 // Return the result if success
498 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestSend(
499 const nsTArray
<uint8_t>& aGroupIdentifier
,
500 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aMessage
,
501 RequestSendResolver
&& aResolver
) {
502 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
503 ("MLSTransactionParent::RecvRequestSend()"));
505 // Call to the MLS rust code
506 nsTArray
<uint8_t> outputMessage
;
507 nsresult rv
= security::mls::mls_send(
508 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
509 aIdentifier
.Elements(), aIdentifier
.Length(), aMessage
.Elements(),
510 aMessage
.Length(), &outputMessage
);
512 // Return Nothing if failed
513 if (NS_WARN_IF(NS_FAILED(rv
))) {
514 aResolver(Nothing());
518 // Return the result if success
519 aResolver(Some(RawBytes
{std::move(outputMessage
)}));
524 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestExportSecret(
525 const nsTArray
<uint8_t>& aGroupIdentifier
,
526 const nsTArray
<uint8_t>& aIdentifier
, const nsTArray
<uint8_t>& aLabel
,
527 const nsTArray
<uint8_t>& aContext
, uint64_t aLen
,
528 RequestExportSecretResolver
&& aResolver
) {
529 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
530 ("MLSTransactionParent::RecvRequestExportSecret()"));
532 // Call to the MLS rust code
533 security::mls::GkExporterOutput exporterOutput
;
534 nsresult rv
= security::mls::mls_derive_exporter(
535 &mDatabasePath
, aGroupIdentifier
.Elements(), aGroupIdentifier
.Length(),
536 aIdentifier
.Elements(), aIdentifier
.Length(), aLabel
.Elements(),
537 aLabel
.Length(), aContext
.Elements(), aContext
.Length(), aLen
,
540 // Return Nothing if failed
541 if (NS_WARN_IF(NS_FAILED(rv
))) {
542 aResolver(Nothing());
546 // Return the result if success
547 aResolver(Some(std::move(exporterOutput
)));
552 mozilla::ipc::IPCResult
MLSTransactionParent::RecvRequestGetGroupIdentifier(
553 const nsTArray
<uint8_t>& aMessage
,
554 RequestGetGroupIdentifierResolver
&& aResolver
) {
555 MOZ_LOG(gMlsLog
, mozilla::LogLevel::Debug
,
556 ("MLSTransactionParent::RecvRequestGetGroupIdentifier()"));
558 nsTArray
<uint8_t> groupId
;
559 nsresult rv
= security::mls::mls_get_group_id(aMessage
.Elements(),
560 aMessage
.Length(), &groupId
);
562 // Return Nothing if failed
563 if (NS_WARN_IF(NS_FAILED(rv
))) {
564 aResolver(Nothing());
568 // Return the result if success
569 aResolver(Some(RawBytes
{std::move(groupId
)}));
574 } // namespace mozilla::dom