@@ -3,6 +3,7 @@ use crate::crypto::aes::Iv;
3
3
use crate :: crypto:: asymmetric_crypto_facade:: AsymmetricCryptoFacade ;
4
4
use crate :: crypto:: asymmetric_crypto_facade:: { AsymmetricCryptoError , DecapsulatedAesKey } ;
5
5
use crate :: crypto:: key:: { GenericAesKey , KeyLoadError } ;
6
+ use crate :: crypto:: public_key_provider:: PublicKeyIdentifier ;
6
7
use crate :: crypto:: randomizer_facade:: RandomizerFacade ;
7
8
use crate :: crypto:: rsa:: RSAEncryptionError ;
8
9
use crate :: crypto:: tuta_crypt:: PQError ;
@@ -12,12 +13,14 @@ use crate::entities::entity_facade::{
12
13
BUCKET_KEY_FIELD , ID_FIELD , OWNER_ENC_SESSION_KEY_FIELD , OWNER_GROUP_FIELD ,
13
14
OWNER_KEY_VERSION_FIELD ,
14
15
} ;
15
- use crate :: entities:: generated:: sys:: BucketKey ;
16
+ use crate :: entities:: generated:: sys:: { BucketKey , InstanceSessionKey } ;
16
17
use crate :: instance_mapper:: InstanceMapper ;
17
18
#[ cfg_attr( test, mockall_double:: double) ]
18
19
use crate :: key_loader_facade:: KeyLoaderFacade ;
19
20
use crate :: metamodel:: TypeModel ;
20
- use crate :: tutanota_constants:: { CryptoProtocolVersion , EncryptionAuthStatus } ;
21
+ use crate :: tutanota_constants:: {
22
+ CryptoProtocolVersion , EncryptionAuthStatus , PublicKeyIdentifierType ,
23
+ } ;
21
24
use crate :: util:: { convert_version_to_u64, ArrayCastingError } ;
22
25
use crate :: GeneratedId ;
23
26
use crate :: IdTupleGenerated ;
@@ -145,7 +148,7 @@ impl CryptoFacade {
145
148
} ) ;
146
149
} ;
147
150
148
- let mut _auth_status : Option < EncryptionAuthStatus > = None ; // TODO: implement
151
+ let mut encryption_auth_status : Option < EncryptionAuthStatus > = None ; // TODO: implement
149
152
let DecapsulatedAesKey {
150
153
decrypted_aes_key : decrypted_bucket_key,
151
154
sender_identity_pub_key : _sender_identity_key,
@@ -163,7 +166,7 @@ impl CryptoFacade {
163
166
} else if let Some ( _group_enc_bucket_key) = & bucket_key. groupEncBucketKey {
164
167
// TODO: to be used with secure external
165
168
let _key_group = bucket_key. keyGroup . as_ref ( ) . unwrap_or ( owner_group) ;
166
- _auth_status = Some ( EncryptionAuthStatus :: AESNoAuthentication ) ;
169
+ encryption_auth_status = Some ( EncryptionAuthStatus :: AESNoAuthentication ) ;
167
170
todo ! ( "secure external resolveWithGroupReference" )
168
171
} else {
169
172
return Err ( SessionKeyResolutionError {
@@ -174,6 +177,21 @@ impl CryptoFacade {
174
177
} ) ;
175
178
} ;
176
179
180
+ // we can only authenticate once we have the session key
181
+ // because we need to check if the confidential flag is set, which is encrypted still
182
+ // we need to do it here at the latest because we must write the flag when updating the session key on the instance
183
+ // self.authenticateMainInstance(
184
+ // typeModel,
185
+ // encryptionAuthStatus,
186
+ // pqMessageSenderKey,
187
+ // bucketKey.protocolVersion == CryptoProtocolVersion.TUTA_CRYPT ? parseKeyVersion(bucketKey.senderKeyVersion ?? "0") : null,
188
+ // instance,
189
+ // resolvedSessionKeyForInstance,
190
+ // instanceSessionKeyWithOwnerEncSessionKey,
191
+ // decryptedSessionKey,
192
+ // bucketKey.keyGroup,
193
+ // ).await?;
194
+
177
195
let mut session_key_for_this_instance = None ;
178
196
179
197
for instance_session_key in bucket_key. bucketEncSessionKeys {
@@ -208,6 +226,83 @@ impl CryptoFacade {
208
226
owner_key_version : versioned_owner_group_key. version ,
209
227
} )
210
228
}
229
+
230
+ async fn authenticate_main_instance (
231
+ type_model : TypeModel ,
232
+ encryption_auth_status : Option < EncryptionAuthStatus > ,
233
+ pq_message_sender_key : Option < & [ u8 ] > ,
234
+ pq_message_sender_key_version : Option < u64 > ,
235
+ entity : & ParsedEntity ,
236
+ resolved_session_key_for_instance : GenericAesKey ,
237
+ instance_session_key_with_owner_enc_session_key : InstanceSessionKey ,
238
+ decrypted_session_key : GenericAesKey ,
239
+ key_group : Option < GeneratedId > ,
240
+ ) -> ( ) {
241
+ // we only authenticate mail instances
242
+
243
+ // TODO type_model.is_same_type_by_attr()
244
+ // const isMailInstance = isSameTypeRefByAttr(MailTypeRef, typeModel.app, typeModel.name)
245
+ // if (isMailInstance) {
246
+ // if (!encryptionAuthStatus) {
247
+ // if (!pqMessageSenderKey) {
248
+ // // This message was encrypted with RSA. We check if TutaCrypt could have been used instead.
249
+ // const recipientGroup = assertNotNull(
250
+ // keyGroup,
251
+ // "trying to authenticate an asymmetrically encrypted message, but we can't determine the recipient's group ID",
252
+ // )
253
+ // const currentKeyPair = await this.keyLoaderFacade.loadCurrentKeyPair(recipientGroup)
254
+ // encryptionAuthStatus = EncryptionAuthStatus.RSA_NO_AUTHENTICATION
255
+ // if (isPqKeyPairs(currentKeyPair.object)) {
256
+ // const keyRotationFacade = this.keyRotationFacade()
257
+ // const rotatedGroups = await keyRotationFacade.getGroupIdsThatPerformedKeyRotations()
258
+ // if (!rotatedGroups.includes(recipientGroup)) {
259
+ // encryptionAuthStatus = EncryptionAuthStatus::RsaDespiteTutacrypt
260
+ // }
261
+ // }
262
+ // } else {
263
+ // const mail = this.isLiteralInstance(instance)
264
+ // ? ((await this.instanceMapper.decryptAndMapToInstance(typeModel, instance, resolvedSessionKeyForInstance)) as Mail)
265
+ // : (instance as Mail)
266
+ // const senderMailAddress = mail.confidential ? mail.sender.address : SYSTEM_GROUP_MAIL_ADDRESS
267
+ // encryptionAuthStatus = await this.tryAuthenticateSenderOfMainInstance(
268
+ // senderMailAddress,
269
+ // pqMessageSenderKey,
270
+ // // must not be null if this is a TutaCrypt message with a pqMessageSenderKey
271
+ // assertNotNull(pqMessageSenderKeyVersion),
272
+ // )
273
+ // }
274
+ // }
275
+ // instanceSessionKeyWithOwnerEncSessionKey.encryptionAuthStatus = aesEncrypt(decryptedSessionKey, stringToUtf8Uint8Array(encryptionAuthStatus))
276
+ // }
277
+ }
278
+
279
+ async fn try_authenticate_sender_of_main_instance (
280
+ & self ,
281
+ sender_mail_address : String ,
282
+ pq_message_sender_key : & [ u8 ] ,
283
+ pq_message_sender_key_version : u64 ,
284
+ ) -> EncryptionAuthStatus {
285
+ let result = self
286
+ . asymmetric_crypto_facade
287
+ . authenticate_sender (
288
+ PublicKeyIdentifier {
289
+ identifier : sender_mail_address,
290
+ identifier_type : PublicKeyIdentifierType :: MailAddress ,
291
+ } ,
292
+ pq_message_sender_key,
293
+ pq_message_sender_key_version,
294
+ )
295
+ . await ;
296
+ match result {
297
+ Err ( _e) => {
298
+ // TODO log the error
299
+ // we do not want to fail mail decryption here, e.g. in case an alias was removed we would get a permanent NotFoundError.
300
+ // in those cases we will just show a warning banner but still want to display the mail
301
+ EncryptionAuthStatus :: TutacryptAuthenticationFailed
302
+ } ,
303
+ Ok ( encryption_auth_status) => encryption_auth_status,
304
+ }
305
+ }
211
306
}
212
307
213
308
/// Resolves the id field of an entity into a generated id
0 commit comments