2023-06-29 18:26:45 +02:00
import o from "@tutao/otest"
2024-04-17 10:34:33 +02:00
import { arrayEquals , hexToUint8Array , neverNull , stringToUtf8Uint8Array , uint8ArrayToBase64 , utf8Uint8ArrayToString } from "@tutao/tutanota-utils"
2023-01-12 16:48:28 +01:00
import { CryptoFacade } from "../../../../../src/api/worker/crypto/CryptoFacade.js"
2024-04-17 10:34:33 +02:00
import {
BucketPermissionType ,
CryptoProtocolVersion ,
EncryptionAuthStatus ,
GroupType ,
PermissionType ,
} from "../../../../../src/api/common/TutanotaConstants.js"
2022-04-19 16:51:08 +02:00
import {
2023-11-10 16:59:39 +01:00
BirthdayTypeRef ,
2022-04-19 16:51:08 +02:00
ContactTypeRef ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
FileTypeRef ,
2023-12-18 11:36:38 +01:00
InternalRecipientKeyData ,
2023-01-17 15:42:18 +01:00
Mail ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
MailDetailsBlobTypeRef ,
2023-01-12 16:48:28 +01:00
MailTypeRef ,
2022-05-12 16:51:15 +02:00
} from "../../../../../src/api/entities/tutanota/TypeRefs.js"
2022-04-19 16:51:08 +02:00
import {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
BucketKey ,
BucketKeyTypeRef ,
2022-04-19 16:51:08 +02:00
BucketPermissionTypeRef ,
2023-11-10 16:59:39 +01:00
BucketTypeRef ,
2023-12-18 11:36:38 +01:00
createBucket ,
createBucketKey ,
createBucketPermission ,
createGroup ,
createInstanceSessionKey ,
createKeyPair ,
createPermission ,
createPublicKeyGetIn ,
createPublicKeyGetOut ,
createTypeInfo ,
2024-04-17 10:34:33 +02:00
CustomerAccountTerminationRequestTypeRef ,
2023-12-18 11:36:38 +01:00
Group ,
2023-11-10 16:59:39 +01:00
GroupMembershipTypeRef ,
2022-04-19 16:51:08 +02:00
GroupTypeRef ,
2023-12-18 11:36:38 +01:00
InstanceSessionKey ,
2023-11-10 16:59:39 +01:00
InstanceSessionKeyTypeRef ,
KeyPairTypeRef ,
2022-04-19 16:51:08 +02:00
PermissionTypeRef ,
2023-12-18 11:36:38 +01:00
PublicKeyGetIn ,
2023-11-10 16:59:39 +01:00
TypeInfoTypeRef ,
2022-04-19 16:51:08 +02:00
UpdatePermissionKeyData ,
2023-12-18 11:36:38 +01:00
User ,
2023-11-10 16:59:39 +01:00
UserTypeRef ,
2022-05-12 16:51:15 +02:00
} from "../../../../../src/api/entities/sys/TypeRefs.js"
2024-04-17 10:34:33 +02:00
import { spy } from "@tutao/tutanota-test-utils"
2023-01-12 16:48:28 +01:00
import { RestClient } from "../../../../../src/api/worker/rest/RestClient.js"
import { EntityClient } from "../../../../../src/api/common/EntityClient.js"
2022-01-07 15:58:30 +01:00
import {
2023-12-18 11:36:38 +01:00
Aes256Key ,
aes256RandomKey ,
2023-09-26 18:03:30 +02:00
aesDecrypt ,
2023-09-13 11:42:57 +02:00
aesEncrypt ,
2024-04-17 10:34:33 +02:00
AesKey ,
2022-01-07 15:58:30 +01:00
bitArrayToUint8Array ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
decryptKey ,
2023-12-18 11:36:38 +01:00
EccKeyPair ,
2022-01-07 15:58:30 +01:00
ENABLE_MAC ,
encryptKey ,
encryptRsaKey ,
2023-12-18 11:36:38 +01:00
generateEccKeyPair ,
2022-01-07 15:58:30 +01:00
IV_BYTE_LENGTH ,
2023-12-18 11:36:38 +01:00
kyberPrivateKeyToBytes ,
kyberPublicKeyToBytes ,
2024-01-30 18:18:19 +01:00
pqKeyPairsToPublicKeys ,
2022-12-27 15:37:40 +01:00
random ,
2023-12-18 11:36:38 +01:00
rsaPrivateKeyToHex ,
rsaPublicKeyToHex ,
2022-01-07 15:58:30 +01:00
} from "@tutao/tutanota-crypto"
2023-01-12 16:48:28 +01:00
import { RsaWeb } from "../../../../../src/api/worker/crypto/RsaImplementation.js"
2024-04-17 10:34:33 +02:00
import { InstanceMapper } from "../../../../../src/api/worker/crypto/InstanceMapper.js"
import type { TypeModel } from "../../../../../src/api/common/EntityTypes.js"
2023-01-12 16:48:28 +01:00
import { IServiceExecutor } from "../../../../../src/api/common/ServiceRequest.js"
2023-12-18 11:36:38 +01:00
import { instance , matchers , object , verify , when } from "testdouble"
import { PublicKeyService , UpdatePermissionKeyService } from "../../../../../src/api/entities/sys/Services.js"
2023-01-12 16:48:28 +01:00
import { getListId , isSameId } from "../../../../../src/api/common/utils/EntityUtils.js"
2023-12-18 11:36:38 +01:00
import { HttpMethod , resolveTypeReference , typeModels } from "../../../../../src/api/common/EntityFunctions.js"
2023-01-12 16:48:28 +01:00
import { UserFacade } from "../../../../../src/api/worker/facades/UserFacade.js"
import { SessionKeyNotFoundError } from "../../../../../src/api/common/error/SessionKeyNotFoundError.js"
import { OwnerEncSessionKeysUpdateQueue } from "../../../../../src/api/worker/crypto/OwnerEncSessionKeysUpdateQueue.js"
2023-12-18 11:36:38 +01:00
import { WASMKyberFacade } from "../../../../../src/api/worker/facades/KyberFacade.js"
import { PQFacade } from "../../../../../src/api/worker/facades/PQFacade.js"
import { encodePQMessage , PQBucketKeyEncapsulation , PQMessage } from "../../../../../src/api/worker/facades/PQMessage.js"
2023-11-09 17:04:42 +01:00
import { createTestEntity } from "../../../TestUtils.js"
2023-12-18 17:30:21 +01:00
import { RSA_TEST_KEYPAIR } from "../facades/RsaPqPerformanceTest.js"
2024-01-31 18:55:21 +01:00
import { DefaultEntityRestCache } from "../../../../../src/api/worker/rest/DefaultEntityRestCache.js"
2024-04-23 11:06:40 +02:00
import { loadLibOQSWASM } from "../WASMTestUtils.js"
2024-04-17 10:34:33 +02:00
import { KeyLoaderFacade } from "../../../../../src/api/worker/facades/KeyLoaderFacade.js"
2023-01-12 16:48:28 +01:00
2023-12-18 11:36:38 +01:00
const { captor , anything , argThat } = matchers
2017-08-15 13:54:22 +02:00
2021-11-23 16:09:12 +01:00
const rsa = new RsaWeb ( )
const rsaEncrypt = rsa . encrypt
2023-12-18 11:36:38 +01:00
const kyberFacade = new WASMKyberFacade ( await loadLibOQSWASM ( ) )
const pqFacade : PQFacade = new PQFacade ( kyberFacade )
/ * *
* Helper to have all the mocked items available in the test case .
* /
type TestUser = {
user : User
name : string
userGroup : Group
mailGroup : Group
2024-04-17 10:34:33 +02:00
userGroupKey : AesKey
mailGroupKey : AesKey
}
async function prepareBucketKeyInstance (
bucketEncMailSessionKey : Uint8Array ,
fileSessionKeys : Array < AesKey > ,
bk : number [ ] ,
pubEncBucketKey : Uint8Array ,
recipientUser : TestUser ,
instanceMapper : InstanceMapper ,
mailLiteral : Record < string , any > ,
recipientKeyVersion : NumberString = "0" ,
senderKeyVersion : NumberString = "0" ,
) {
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
const mailInstanceSessionKey = createTestEntity ( InstanceSessionKeyTypeRef , {
typeInfo : createTestEntity ( TypeInfoTypeRef , {
application : MailTypeModel.app ,
typeId : String ( MailTypeModel . id ) ,
} ) ,
symEncSessionKey : bucketEncMailSessionKey ,
instanceList : "mailListId" ,
instanceId : "mailId" ,
} )
const FileTypeModel = await resolveTypeReference ( FileTypeRef )
const bucketEncSessionKeys = fileSessionKeys . map ( ( fileSessionKey , index ) = > {
return createTestEntity ( InstanceSessionKeyTypeRef , {
typeInfo : createTestEntity ( TypeInfoTypeRef , {
application : FileTypeModel.app ,
typeId : String ( FileTypeModel . id ) ,
} ) ,
symEncSessionKey : encryptKey ( bk , fileSessionKey ) ,
instanceList : "fileListId" ,
instanceId : "fileId" + ( index + 1 ) ,
} )
} )
bucketEncSessionKeys . push ( mailInstanceSessionKey )
const bucketKey = createTestEntity ( BucketKeyTypeRef , {
pubEncBucketKey : pubEncBucketKey ,
keyGroup : recipientUser.userGroup._id ,
bucketEncSessionKeys : bucketEncSessionKeys ,
recipientKeyVersion ,
senderKeyVersion ,
protocolVersion : CryptoProtocolVersion.TUTA_CRYPT ,
} )
const BucketKeyModel = await resolveTypeReference ( BucketKeyTypeRef )
const bucketKeyLiteral = await instanceMapper . encryptAndMapToLiteral ( BucketKeyModel , bucketKey , null )
Object . assign ( mailLiteral , { bucketKey : bucketKeyLiteral } )
return { MailTypeModel , bucketKey }
2023-12-18 11:36:38 +01:00
}
o . spec ( "CryptoFacadeTest" , function ( ) {
2023-09-26 18:03:30 +02:00
let restClient : RestClient
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2021-12-15 16:07:07 +01:00
let instanceMapper = new InstanceMapper ( )
2022-03-09 17:43:29 +01:00
let serviceExecutor : IServiceExecutor
let entityClient : EntityClient
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
let ownerEncSessionKeysUpdateQueue : OwnerEncSessionKeysUpdateQueue
2022-03-09 17:43:29 +01:00
let crypto : CryptoFacade
2022-04-12 14:23:38 +02:00
let userFacade : UserFacade
2024-04-17 10:34:33 +02:00
let keyLoaderFacade : KeyLoaderFacade
2024-01-31 18:55:21 +01:00
let cache : DefaultEntityRestCache
2017-11-23 13:30:17 +01:00
o . before ( function ( ) {
2023-09-26 18:03:30 +02:00
restClient = object ( )
2023-12-18 11:36:38 +01:00
when ( restClient . request ( anything ( ) , anything ( ) , anything ( ) ) ) . thenResolve ( undefined )
2022-04-12 14:23:38 +02:00
userFacade = object ( )
2024-04-17 10:34:33 +02:00
keyLoaderFacade = object ( )
2024-01-31 18:55:21 +01:00
cache = object ( )
2017-11-23 13:30:17 +01:00
} )
2022-03-09 17:43:29 +01:00
o . beforeEach ( function ( ) {
serviceExecutor = object ( )
entityClient = object ( )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
ownerEncSessionKeysUpdateQueue = object ( )
2024-04-17 10:34:33 +02:00
crypto = new CryptoFacade (
userFacade ,
entityClient ,
restClient ,
rsa ,
serviceExecutor ,
instanceMapper ,
ownerEncSessionKeysUpdateQueue ,
pqFacade ,
cache ,
keyLoaderFacade ,
)
2022-03-09 17:43:29 +01:00
} )
2024-04-17 10:34:33 +02:00
o ( "resolve session key: unencrypted instance" , async function ( ) {
const dummyDate = new Date ( ) . getTime ( ) . toString ( )
const customerAccountTerminationRequestLiteral = {
_format : 0 ,
terminationDate : dummyDate ,
terminationRequestDate : dummyDate ,
customer : "customerId" ,
2017-08-15 13:54:22 +02:00
}
2024-04-17 10:34:33 +02:00
const CustomerAccountTerminationTypeModel = await resolveTypeReference ( CustomerAccountTerminationRequestTypeRef )
o ( await crypto . resolveSessionKey ( CustomerAccountTerminationTypeModel , customerAccountTerminationRequestLiteral ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
2024-04-17 10:34:33 +02:00
o ( "resolve session key: _ownerEncSessionKey instance." , async function ( ) {
const recipientUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientUser , userFacade , keyLoaderFacade )
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2023-12-05 14:03:33 +01:00
const sk = aes256RandomKey ( )
2024-02-01 13:54:19 +01:00
2024-04-17 10:34:33 +02:00
const mail = createMailLiteral ( recipientUser . mailGroupKey , sk , subject , confidential , senderName , recipientUser . name , recipientUser . mailGroup . _id )
2017-08-15 13:54:22 +02:00
2024-04-17 10:34:33 +02:00
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
const sessionKey : AesKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
2017-08-15 13:54:22 +02:00
2024-04-17 10:34:33 +02:00
o ( sessionKey ) . deepEquals ( sk )
2017-08-15 13:54:22 +02:00
} )
2024-04-17 10:34:33 +02:00
o ( "resolve session key: _ownerEncSessionKey instance, fetches correct version." , async function ( ) {
const recipientUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientUser , userFacade , keyLoaderFacade )
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2023-12-05 14:03:33 +01:00
const sk = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
const groupKey_v1 = aes256RandomKey ( )
when ( keyLoaderFacade . loadSymGroupKey ( recipientUser . mailGroup . _id , 1 ) ) . thenResolve ( groupKey_v1 )
const mail = createMailLiteral ( groupKey_v1 , sk , subject , confidential , senderName , recipientUser . name , recipientUser . mailGroup . _id )
mail . _ownerKeyVersion = "1"
2022-03-09 17:43:29 +01:00
2022-04-19 16:51:08 +02:00
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
2024-04-17 10:34:33 +02:00
const sessionKey : AesKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
2022-03-09 17:43:29 +01:00
2022-01-07 15:58:30 +01:00
o ( sessionKey ) . deepEquals ( sk )
2017-08-15 13:54:22 +02:00
} )
2024-04-17 10:34:33 +02:00
o ( "resolve session key: rsa public key decryption of session key." , async function ( ) {
2021-01-25 12:50:28 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
2024-04-17 10:34:33 +02:00
const recipientUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientUser , userFacade , keyLoaderFacade )
when ( keyLoaderFacade . loadKeypair ( recipientUser . userGroup . _id , 0 ) ) . thenResolve ( RSA_TEST_KEYPAIR )
2021-01-25 12:50:28 +01:00
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2023-12-05 14:03:33 +01:00
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-12-18 17:30:21 +01:00
let privateKey = RSA_TEST_KEYPAIR . privateKey
let publicKey = RSA_TEST_KEYPAIR . publicKey
2023-11-10 16:59:39 +01:00
const keyPair = createTestEntity ( KeyPairTypeRef , {
2022-03-09 17:43:29 +01:00
_id : "keyPairId" ,
2023-12-18 11:36:38 +01:00
symEncPrivRsaKey : encryptRsaKey ( recipientUser . userGroupKey , privateKey ) ,
2023-12-18 17:30:21 +01:00
pubRsaKey : hexToUint8Array ( rsaPublicKeyToHex ( RSA_TEST_KEYPAIR . publicKey ) ) ,
2022-03-09 17:43:29 +01:00
} )
2024-04-17 10:34:33 +02:00
recipientUser . userGroup . currentKeys = keyPair
2023-12-18 11:36:38 +01:00
const mail = createMailLiteral ( null , sk , subject , confidential , senderName , recipientUser . name , recipientUser . mailGroup . _id )
2023-11-10 16:59:39 +01:00
const bucket = createTestEntity ( BucketTypeRef , {
2022-12-27 15:37:40 +01:00
bucketPermissions : "bucketPermissionListId" ,
2022-03-09 17:43:29 +01:00
} )
2023-11-10 16:59:39 +01:00
const permission = createTestEntity ( PermissionTypeRef , {
2022-03-09 17:43:29 +01:00
_id : [ "permissionListId" , "permissionId" ] ,
2023-12-18 11:36:38 +01:00
_ownerGroup : recipientUser.userGroup._id ,
2022-03-09 17:43:29 +01:00
bucketEncSessionKey : encryptKey ( bk , sk ) ,
bucket ,
type : PermissionType . Public ,
} )
2020-11-13 10:31:35 +01:00
const pubEncBucketKey = await rsaEncrypt ( publicKey , bitArrayToUint8Array ( bk ) )
2023-11-10 16:59:39 +01:00
const bucketPermission = createTestEntity ( BucketPermissionTypeRef , {
2022-03-09 17:43:29 +01:00
_id : [ "bucketPermissionListId" , "bucketPermissionId" ] ,
2023-12-18 11:36:38 +01:00
_ownerGroup : recipientUser.userGroup._id ,
2022-03-09 17:43:29 +01:00
type : BucketPermissionType . Public ,
2023-12-18 11:36:38 +01:00
group : recipientUser.userGroup._id ,
2022-03-09 17:43:29 +01:00
pubEncBucketKey ,
2024-04-17 10:34:33 +02:00
pubKeyVersion : "0" ,
2022-03-09 17:43:29 +01:00
} )
2022-04-12 14:23:38 +02:00
2022-03-09 17:43:29 +01:00
when ( entityClient . loadAll ( BucketPermissionTypeRef , getListId ( bucketPermission ) ) ) . thenResolve ( [ bucketPermission ] )
when ( entityClient . loadAll ( PermissionTypeRef , getListId ( permission ) ) ) . thenResolve ( [ permission ] )
2022-12-27 15:37:40 +01:00
when (
serviceExecutor . post (
UpdatePermissionKeyService ,
2023-12-18 11:36:38 +01:00
argThat ( ( p : UpdatePermissionKeyData ) = > {
2022-12-27 15:37:40 +01:00
return isSameId ( p . permission , permission . _id ) && isSameId ( p . bucketPermission , bucketPermission . _id )
} ) ,
) ,
) . thenResolve ( undefined )
2022-03-09 17:43:29 +01:00
2022-04-19 16:51:08 +02:00
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
2022-03-09 17:43:29 +01:00
const sessionKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
o ( sessionKey ) . deepEquals ( sk )
2017-08-15 13:54:22 +02:00
} )
2024-04-17 10:34:33 +02:00
o ( "resolve session key: pq public key decryption of session key." , async function ( ) {
2023-12-18 11:36:38 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2024-04-17 10:34:33 +02:00
const recipientTestUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientTestUser , userFacade , keyLoaderFacade )
2023-12-18 11:36:38 +01:00
let pqKeyPairs = await pqFacade . generateKeyPairs ( )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadKeypair ( recipientTestUser . userGroup . _id , 0 ) ) . thenResolve ( pqKeyPairs )
2023-12-18 11:36:38 +01:00
const senderIdentityKeyPair = generateEccKeyPair ( )
// configure test mail
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
const mail = createMailLiteral ( null , sk , subject , confidential , senderName , recipientTestUser . name , recipientTestUser . mailGroup . _id )
const bucket = createBucket ( {
bucketPermissions : "bucketPermissionListId" ,
} )
const permission = createPermission ( {
_format : "" ,
listElementApplication : null ,
listElementTypeId : null ,
ops : null ,
symEncSessionKey : null ,
2024-04-17 10:34:33 +02:00
symKeyVersion : null ,
2023-12-18 11:36:38 +01:00
_id : [ "permissionListId" , "permissionId" ] ,
_ownerGroup : recipientTestUser.mailGroup._id ,
bucketEncSessionKey : encryptKey ( bk , sk ) ,
bucket ,
type : PermissionType . Public ,
_ownerEncSessionKey : null ,
2024-04-17 10:34:33 +02:00
_ownerKeyVersion : null ,
2023-12-18 11:36:38 +01:00
_permissions : "p_id" ,
group : null ,
} )
2023-12-18 17:30:21 +01:00
const pqMessage = await pqFacade . encapsulate ( senderIdentityKeyPair , generateEccKeyPair ( ) , pqKeyPairsToPublicKeys ( pqKeyPairs ) , bitArrayToUint8Array ( bk ) )
2023-12-18 11:36:38 +01:00
const pubEncBucketKey = encodePQMessage ( pqMessage )
const bucketPermission = createBucketPermission ( {
_id : [ "bucketPermissionListId" , "bucketPermissionId" ] ,
2024-04-17 10:34:33 +02:00
_format : "" ,
_permissions : "" ,
2023-12-18 11:36:38 +01:00
_ownerGroup : recipientTestUser.mailGroup._id ,
type : BucketPermissionType . Public ,
group : recipientTestUser.userGroup._id ,
pubEncBucketKey ,
2024-04-17 10:34:33 +02:00
senderKeyVersion : "0" ,
ownerEncBucketKey : null ,
ownerKeyVersion : null ,
protocolVersion : "0" ,
pubKeyVersion : "0" ,
symEncBucketKey : null ,
symKeyVersion : null ,
} )
when ( userFacade . createAuthHeaders ( ) ) . thenReturn ( { } )
when ( restClient . request ( anything ( ) , HttpMethod . PUT , anything ( ) ) ) . thenResolve ( undefined )
when ( entityClient . loadAll ( BucketPermissionTypeRef , getListId ( bucketPermission ) ) ) . thenResolve ( [ bucketPermission ] )
when ( entityClient . loadAll ( PermissionTypeRef , getListId ( permission ) ) ) . thenResolve ( [ permission ] )
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
o ( sessionKey ) . deepEquals ( sk )
} )
o ( "resolve session key: pq public key decryption of session key, fetches correct recipient key version" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
const recipientTestUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientTestUser , userFacade , keyLoaderFacade )
const pqKeyPairs_v1 = await pqFacade . generateKeyPairs ( )
const senderIdentityKeyPair = generateEccKeyPair ( )
// configure test mail
const sk = aes256RandomKey ( )
const bk = aes256RandomKey ( )
const mail = createMailLiteral ( null , sk , subject , confidential , senderName , recipientTestUser . name , recipientTestUser . mailGroup . _id )
const bucket = createBucket ( {
bucketPermissions : "bucketPermissionListId" ,
} )
const permission = createPermission ( {
_format : "" ,
listElementApplication : null ,
listElementTypeId : null ,
ops : null ,
symEncSessionKey : null ,
symKeyVersion : null ,
_id : [ "permissionListId" , "permissionId" ] ,
_ownerGroup : recipientTestUser.mailGroup._id ,
bucketEncSessionKey : encryptKey ( bk , sk ) ,
bucket ,
type : PermissionType . Public ,
_ownerEncSessionKey : null ,
_ownerKeyVersion : null ,
_permissions : "p_id" ,
group : null ,
} )
const pqMessage = await pqFacade . encapsulate (
senderIdentityKeyPair ,
generateEccKeyPair ( ) ,
pqKeyPairsToPublicKeys ( pqKeyPairs_v1 ) ,
bitArrayToUint8Array ( bk ) ,
)
const pubEncBucketKey = encodePQMessage ( pqMessage )
const bucketPermission = createBucketPermission ( {
_id : [ "bucketPermissionListId" , "bucketPermissionId" ] ,
2023-12-18 11:36:38 +01:00
_format : "" ,
_permissions : "" ,
2024-04-17 10:34:33 +02:00
_ownerGroup : recipientTestUser.mailGroup._id ,
type : BucketPermissionType . Public ,
group : recipientTestUser.userGroup._id ,
pubEncBucketKey ,
senderKeyVersion : "0" ,
2023-12-18 11:36:38 +01:00
ownerEncBucketKey : null ,
2024-04-17 10:34:33 +02:00
ownerKeyVersion : null ,
2023-12-18 11:36:38 +01:00
protocolVersion : "0" ,
2024-04-17 10:34:33 +02:00
pubKeyVersion : "1" ,
2023-12-18 11:36:38 +01:00
symEncBucketKey : null ,
2024-04-17 10:34:33 +02:00
symKeyVersion : null ,
2023-12-18 11:36:38 +01:00
} )
when ( userFacade . createAuthHeaders ( ) ) . thenReturn ( { } )
when ( restClient . request ( anything ( ) , HttpMethod . PUT , anything ( ) ) ) . thenResolve ( undefined )
when ( entityClient . loadAll ( BucketPermissionTypeRef , getListId ( bucketPermission ) ) ) . thenResolve ( [ bucketPermission ] )
when ( entityClient . loadAll ( PermissionTypeRef , getListId ( permission ) ) ) . thenResolve ( [ permission ] )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadKeypair ( recipientTestUser . userGroup . _id , 1 ) ) . thenResolve ( pqKeyPairs_v1 )
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
verify ( keyLoaderFacade . loadKeypair ( recipientTestUser . userGroup . _id , 1 ) )
o ( sessionKey ) . deepEquals ( sk )
} )
o ( "resolve session key: pq public key decryption of session key using bucketKey" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
const recipientTestUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientTestUser , userFacade , keyLoaderFacade )
const pqKeyPairs_v1 = await pqFacade . generateKeyPairs ( )
const senderIdentityKeyPair = generateEccKeyPair ( )
// configure test mail
const sk = aes256RandomKey ( )
const bk = aes256RandomKey ( )
const mail = createMailLiteral ( null , sk , subject , confidential , senderName , recipientTestUser . name , recipientTestUser . mailGroup . _id )
const bucketEncMailSessionKey = encryptKey ( bk , sk )
const pqMessage = await pqFacade . encapsulate (
senderIdentityKeyPair ,
generateEccKeyPair ( ) ,
pqKeyPairsToPublicKeys ( pqKeyPairs_v1 ) ,
bitArrayToUint8Array ( bk ) ,
)
const pubEncBucketKey = encodePQMessage ( pqMessage )
Object . assign ( mail , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
await prepareBucketKeyInstance ( bucketEncMailSessionKey , [ ] , bk , pubEncBucketKey , recipientTestUser , instanceMapper , mail , "1" , "1" )
const publicKeyGetIn = matchers . captor ( )
when ( serviceExecutor . get ( PublicKeyService , publicKeyGetIn . capture ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : senderIdentityKeyPair.publicKey ,
pubKeyVersion : "1" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
when ( userFacade . createAuthHeaders ( ) ) . thenReturn ( { } )
when ( restClient . request ( anything ( ) , HttpMethod . PUT , anything ( ) ) ) . thenResolve ( undefined )
when ( keyLoaderFacade . loadKeypair ( recipientTestUser . userGroup . _id , 1 ) ) . thenResolve ( pqKeyPairs_v1 )
2023-12-18 11:36:38 +01:00
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
2024-04-17 10:34:33 +02:00
o ( publicKeyGetIn . value . version ) . equals ( "1" )
verify ( keyLoaderFacade . loadKeypair ( recipientTestUser . userGroup . _id , 1 ) )
2023-12-18 11:36:38 +01:00
o ( sessionKey ) . deepEquals ( sk )
} )
2024-01-31 18:55:21 +01:00
o ( "enforceSessionKeyUpdateIfNeeded: _ownerEncSessionKey already defined" , async function ( ) {
const files = [ createTestEntity ( FileTypeRef , { _ownerEncSessionKey : new Uint8Array ( ) } ) ]
await crypto . enforceSessionKeyUpdateIfNeeded ( { } , files )
verify ( ownerEncSessionKeysUpdateQueue . postUpdateSessionKeysService ( anything ( ) ) , { times : 0 } )
verify ( cache . deleteFromCacheIfExists ( anything ( ) , anything ( ) , anything ( ) ) , { times : 0 } )
} )
o ( "enforceSessionKeyUpdateIfNeeded: _ownerEncSessionKey missing" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const files = [
createTestEntity ( FileTypeRef , { _id : [ "listId" , "1" ] , _ownerEncSessionKey : new Uint8Array ( ) } ) ,
createTestEntity ( FileTypeRef , { _id : [ "listId" , "2" ] , _ownerEncSessionKey : null } ) ,
]
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
const mail = createTestEntity ( MailTypeRef , testData . mailLiteral )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
2024-04-17 10:34:33 +02:00
// const sessionKey = neverNull(await crypto.resolveSessionKey(testData.MailTypeModel, testData.mailLiteral))
2024-01-31 18:55:21 +01:00
const updatedFiles = await crypto . enforceSessionKeyUpdateIfNeeded ( mail , files )
verify ( ownerEncSessionKeysUpdateQueue . postUpdateSessionKeysService ( anything ( ) ) , { times : 1 } )
verify ( cache . deleteFromCacheIfExists ( FileTypeRef , "listId" , "2" ) )
} )
2023-12-18 11:36:38 +01:00
o ( "encryptBucketKeyForInternalRecipient with existing PQKeys for sender and recipient" , async ( ) = > {
const pqFacadeMock = instance ( PQFacade )
const cryptoFacadeTmp = new CryptoFacade (
userFacade ,
entityClient ,
restClient ,
rsa ,
serviceExecutor ,
instanceMapper ,
ownerEncSessionKeysUpdateQueue ,
pqFacadeMock ,
2024-01-31 18:55:21 +01:00
cache ,
2024-04-17 10:34:33 +02:00
keyLoaderFacade ,
2023-12-18 11:36:38 +01:00
)
let senderMailAddress = "alice@tutanota.com"
let recipientMailAddress = "bob@tutanota.com"
let senderGroupKey = aes256RandomKey ( )
let bk = aes256RandomKey ( )
const recipientKeyPairs = await pqFacade . generateKeyPairs ( )
const recipientKeyPair = createKeyPair ( {
_id : "recipientKeyPairId" ,
pubEccKey : recipientKeyPairs.eccKeyPair.publicKey ,
symEncPrivEccKey : null ,
pubKyberKey : kyberPublicKeyToBytes ( recipientKeyPairs . kyberKeyPair . publicKey ) ,
symEncPrivKyberKey : null ,
pubRsaKey : null ,
symEncPrivRsaKey : null ,
} )
const senderKeyPairs = await pqFacade . generateKeyPairs ( )
const senderKeyPair = createKeyPair ( {
_id : "senderKeyPairId" ,
pubRsaKey : null ,
symEncPrivRsaKey : null ,
pubEccKey : senderKeyPairs.eccKeyPair.publicKey ,
symEncPrivEccKey : aesEncrypt ( senderGroupKey , senderKeyPairs . eccKeyPair . privateKey ) ,
pubKyberKey : kyberPublicKeyToBytes ( senderKeyPairs . kyberKeyPair . publicKey ) ,
symEncPrivKyberKey : aesEncrypt ( senderGroupKey , kyberPrivateKeyToBytes ( senderKeyPairs . kyberKeyPair . privateKey ) ) ,
} )
const senderUserGroup = createGroup ( {
_format : "" ,
_ownerGroup : "" ,
_permissions : "" ,
admin : "admin1" ,
adminGroupEncGKey : null ,
2024-04-17 10:34:33 +02:00
adminGroupKeyVersion : null ,
2023-12-18 11:36:38 +01:00
administratedGroups : null ,
archives : [ ] ,
customer : "customer1" ,
enabled : false ,
external : false ,
groupInfo : [ "" , "" ] ,
invitations : "" ,
members : "" ,
storageCounter : "counter1" ,
type : "" ,
user : "user1" ,
_id : "userGroupId" ,
2024-04-17 10:34:33 +02:00
currentKeys : senderKeyPair ,
groupKeyVersion : "0" ,
formerGroupKeys : null ,
pubAdminGroupEncGKey : null ,
2023-12-18 11:36:38 +01:00
} )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadCurrentKeyPair ( senderUserGroup . _id ) ) . thenResolve ( { version : 0 , object : senderKeyPairs } )
2023-12-18 11:36:38 +01:00
const notFoundRecipients = [ ]
const pqEncapsulation : PQBucketKeyEncapsulation = {
kyberCipherText : new Uint8Array ( [ 1 ] ) ,
kekEncBucketKey : new Uint8Array ( [ 2 ] ) ,
}
const pqMessage : PQMessage = {
senderIdentityPubKey : senderKeyPair.pubEccKey ! ,
ephemeralPubKey : senderKeyPair.pubEccKey ! ,
encapsulation : pqEncapsulation ,
}
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : recipientMailAddress , version : null } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubKeyVersion : "0" ,
pubEccKey : recipientKeyPair.pubEccKey ,
pubKyberKey : recipientKeyPair.pubKyberKey ,
pubRsaKey : null ,
} ) ,
)
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : senderMailAddress , version : "0" } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubKeyVersion : "0" ,
pubEccKey : senderKeyPair.pubEccKey ,
pubKyberKey : senderKeyPair.pubKyberKey ,
pubRsaKey : null ,
} ) ,
)
2023-12-18 17:30:21 +01:00
when ( pqFacadeMock . encapsulate ( senderKeyPairs . eccKeyPair , anything ( ) , pqKeyPairsToPublicKeys ( recipientKeyPairs ) , bitArrayToUint8Array ( bk ) ) ) . thenResolve (
pqMessage ,
)
2023-12-18 11:36:38 +01:00
when ( entityClient . load ( GroupTypeRef , senderUserGroup . _id ) ) . thenResolve ( senderUserGroup )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . getCurrentSymGroupKey ( senderUserGroup . _id ) ) . thenResolve ( { object : senderGroupKey , version : 0 } )
2023-12-18 11:36:38 +01:00
const internalRecipientKeyData = ( await cryptoFacadeTmp . encryptBucketKeyForInternalRecipient (
senderUserGroup . _id ,
bk ,
recipientMailAddress ,
notFoundRecipients ,
) ) as InternalRecipientKeyData
2024-04-17 10:34:33 +02:00
o ( internalRecipientKeyData ! . recipientKeyVersion ) . equals ( "0" )
2023-12-18 11:36:38 +01:00
o ( internalRecipientKeyData ! . mailAddress ) . equals ( recipientMailAddress )
o ( internalRecipientKeyData ! . pubEncBucketKey ) . deepEquals ( encodePQMessage ( pqMessage ) )
verify ( serviceExecutor . put ( PublicKeyService , anything ( ) ) , { times : 0 } )
} )
o ( "encryptBucketKeyForInternalRecipient with existing PQKeys for recipient" , async ( ) = > {
const pqFacadeMock = instance ( PQFacade )
const cryptoFacadeTmp = new CryptoFacade (
userFacade ,
entityClient ,
restClient ,
rsa ,
serviceExecutor ,
instanceMapper ,
ownerEncSessionKeysUpdateQueue ,
pqFacadeMock ,
2024-01-31 18:55:21 +01:00
cache ,
2024-04-17 10:34:33 +02:00
keyLoaderFacade ,
2023-12-18 11:36:38 +01:00
)
let senderMailAddress = "alice@tutanota.com"
let recipientMailAddress = "bob@tutanota.com"
let senderGroupKey = aes256RandomKey ( )
let bk = aes256RandomKey ( )
const recipientKeyPairs = await pqFacade . generateKeyPairs ( )
const recipientKeyPair = createKeyPair ( {
_ownerGroup : "" ,
pubRsaKey : null ,
symEncPrivEccKey : null ,
symEncPrivKyberKey : null ,
symEncPrivRsaKey : null ,
_id : "recipientKeyPairId" ,
pubEccKey : recipientKeyPairs.eccKeyPair.publicKey ,
pubKyberKey : kyberPublicKeyToBytes ( recipientKeyPairs . kyberKeyPair . publicKey ) ,
} )
2023-12-18 17:30:21 +01:00
const senderKeyPairs = RSA_TEST_KEYPAIR
2023-12-18 11:36:38 +01:00
const senderKeyPair = createKeyPair ( {
_id : "senderKeyPairId" ,
_ownerGroup : "" ,
pubEccKey : null ,
pubKyberKey : null ,
symEncPrivEccKey : null ,
symEncPrivKyberKey : null ,
pubRsaKey : hexToUint8Array ( rsaPublicKeyToHex ( senderKeyPairs . publicKey ) ) ,
symEncPrivRsaKey : aesEncrypt ( senderGroupKey , hexToUint8Array ( rsaPrivateKeyToHex ( senderKeyPairs . privateKey ) ) ) ,
} )
const senderUserGroup = createGroup ( {
_format : "" ,
_ownerGroup : "" ,
_permissions : "" ,
admin : null ,
adminGroupEncGKey : null ,
2024-04-17 10:34:33 +02:00
adminGroupKeyVersion : null ,
2023-12-18 11:36:38 +01:00
administratedGroups : null ,
archives : [ ] ,
customer : null ,
enabled : false ,
external : false ,
groupInfo : [ "" , "" ] ,
invitations : "" ,
members : "" ,
storageCounter : null ,
type : "" ,
user : null ,
_id : "userGroupId" ,
2024-04-17 10:34:33 +02:00
currentKeys : senderKeyPair ,
groupKeyVersion : "0" ,
formerGroupKeys : null ,
pubAdminGroupEncGKey : null ,
2023-12-18 11:36:38 +01:00
} )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadCurrentKeyPair ( senderUserGroup . _id ) ) . thenResolve ( { version : 0 , object : senderKeyPairs } )
2023-12-18 11:36:38 +01:00
const notFoundRecipients = [ ]
const pqEncapsulation : PQBucketKeyEncapsulation = {
kyberCipherText : new Uint8Array ( [ 1 ] ) ,
kekEncBucketKey : new Uint8Array ( [ 2 ] ) ,
}
const dummyEccPubKey = generateEccKeyPair ( ) . publicKey
const pqMessage : PQMessage = {
senderIdentityPubKey : dummyEccPubKey ,
ephemeralPubKey : dummyEccPubKey ,
encapsulation : pqEncapsulation ,
}
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : recipientMailAddress , version : null } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubRsaKey : null ,
pubKeyVersion : "0" ,
pubEccKey : recipientKeyPair.pubEccKey ,
pubKyberKey : recipientKeyPair.pubKyberKey ,
} ) ,
)
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : senderMailAddress , version : null } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubKeyVersion : "0" ,
pubRsaKey : senderKeyPair.pubRsaKey ,
pubEccKey : null ,
pubKyberKey : null ,
} ) ,
)
2023-12-18 17:30:21 +01:00
when ( pqFacadeMock . encapsulate ( anything ( ) , anything ( ) , pqKeyPairsToPublicKeys ( recipientKeyPairs ) , bitArrayToUint8Array ( bk ) ) ) . thenResolve ( pqMessage )
2023-12-18 11:36:38 +01:00
when ( entityClient . load ( GroupTypeRef , senderUserGroup . _id ) ) . thenResolve ( senderUserGroup )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . getCurrentSymGroupKey ( senderUserGroup . _id ) ) . thenResolve ( { object : senderGroupKey , version : 0 } )
when ( userFacade . getCurrentUserGroupKey ( ) ) . thenReturn ( { object : senderGroupKey , version : 0 } )
2023-12-18 11:36:38 +01:00
const internalRecipientKeyData = ( await cryptoFacadeTmp . encryptBucketKeyForInternalRecipient (
senderUserGroup . _id ,
bk ,
recipientMailAddress ,
notFoundRecipients ,
) ) as InternalRecipientKeyData
2024-04-17 10:34:33 +02:00
o ( internalRecipientKeyData ! . recipientKeyVersion ) . equals ( "0" )
2023-12-18 11:36:38 +01:00
o ( internalRecipientKeyData ! . mailAddress ) . equals ( recipientMailAddress )
o ( internalRecipientKeyData ! . pubEncBucketKey ) . deepEquals ( encodePQMessage ( pqMessage ) )
const pubKeyPutIn = captor ( )
verify ( serviceExecutor . put ( PublicKeyService , pubKeyPutIn . capture ( ) ) , { times : 1 } )
const eccKeyPair = captor ( )
2023-12-18 17:30:21 +01:00
verify ( pqFacadeMock . encapsulate ( eccKeyPair . capture ( ) , anything ( ) , pqKeyPairsToPublicKeys ( recipientKeyPairs ) , bitArrayToUint8Array ( bk ) ) , { times : 1 } )
2023-12-18 11:36:38 +01:00
o ( pubKeyPutIn . value . pubEccKey ) . deepEquals ( eccKeyPair . value . publicKey )
o ( aesDecrypt ( senderGroupKey , pubKeyPutIn . value . symEncPrivEccKey ) ) . deepEquals ( eccKeyPair . value . privateKey )
} )
o ( "encryptBucketKeyForInternalRecipient with existing PQKeys for sender" , async ( ) = > {
const pqFacadeMock = instance ( PQFacade )
const cryptoFacadeTmp = new CryptoFacade (
userFacade ,
entityClient ,
restClient ,
rsa ,
serviceExecutor ,
instanceMapper ,
ownerEncSessionKeysUpdateQueue ,
pqFacadeMock ,
2024-01-31 18:55:21 +01:00
cache ,
2024-04-17 10:34:33 +02:00
keyLoaderFacade ,
2023-12-18 11:36:38 +01:00
)
let senderMailAddress = "alice@tutanota.com"
let recipientMailAddress = "bob@tutanota.com"
let senderGroupKey = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-12-18 17:30:21 +01:00
const recipientKeyPairs = RSA_TEST_KEYPAIR
2023-12-18 11:36:38 +01:00
const recipientKeyPair = createKeyPair ( {
_id : "recipientKeyPairId" ,
pubRsaKey : hexToUint8Array ( rsaPublicKeyToHex ( recipientKeyPairs . publicKey ) ) ,
symEncPrivRsaKey : aesEncrypt ( senderGroupKey , hexToUint8Array ( rsaPrivateKeyToHex ( recipientKeyPairs . privateKey ) ) ) ,
pubEccKey : null ,
pubKyberKey : null ,
symEncPrivEccKey : null ,
symEncPrivKyberKey : null ,
} )
const senderKeyPairs = await pqFacade . generateKeyPairs ( )
const senderKeyPair = createKeyPair ( {
_id : "senderKeyPairId" ,
pubEccKey : senderKeyPairs.eccKeyPair.publicKey ,
symEncPrivEccKey : aesEncrypt ( senderGroupKey , senderKeyPairs . eccKeyPair . privateKey ) ,
pubKyberKey : kyberPublicKeyToBytes ( senderKeyPairs . kyberKeyPair . publicKey ) ,
symEncPrivKyberKey : aesEncrypt ( senderGroupKey , kyberPrivateKeyToBytes ( senderKeyPairs . kyberKeyPair . privateKey ) ) ,
pubRsaKey : null ,
symEncPrivRsaKey : null ,
} )
const senderUserGroup = createGroup ( {
_id : "userGroupId" ,
2024-04-17 10:34:33 +02:00
currentKeys : senderKeyPair ,
groupKeyVersion : "0" ,
2023-12-18 11:36:38 +01:00
_permissions : "" ,
admin : null ,
adminGroupEncGKey : null ,
2024-04-17 10:34:33 +02:00
adminGroupKeyVersion : null ,
2023-12-18 11:36:38 +01:00
administratedGroups : null ,
archives : [ ] ,
customer : null ,
enabled : false ,
external : false ,
groupInfo : [ "" , "" ] ,
invitations : "" ,
members : "" ,
storageCounter : null ,
type : "" ,
user : null ,
2024-04-17 10:34:33 +02:00
formerGroupKeys : null ,
pubAdminGroupEncGKey : null ,
2023-12-18 11:36:38 +01:00
} )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadCurrentKeyPair ( senderUserGroup . _id ) ) . thenResolve ( { version : 0 , object : senderKeyPairs } )
2023-12-18 11:36:38 +01:00
const notFoundRecipients = [ ]
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : recipientMailAddress , version : null } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubKeyVersion : "0" ,
pubRsaKey : recipientKeyPair.pubRsaKey ,
pubEccKey : null ,
pubKyberKey : null ,
} ) ,
)
2024-04-17 10:34:33 +02:00
when ( serviceExecutor . get ( PublicKeyService , createPublicKeyGetIn ( { mailAddress : senderMailAddress , version : null } ) ) ) . thenResolve (
2023-12-18 11:36:38 +01:00
createPublicKeyGetOut ( {
pubKeyVersion : "0" ,
pubEccKey : senderKeyPair.pubEccKey ,
pubKyberKey : senderKeyPair.pubKyberKey ,
_ownerGroup : "" ,
pubRsaKey : null ,
} ) ,
)
when ( entityClient . load ( GroupTypeRef , senderUserGroup . _id ) ) . thenResolve ( senderUserGroup )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . getCurrentSymGroupKey ( senderUserGroup . _id ) ) . thenResolve ( { object : senderGroupKey , version : 0 } )
2023-12-18 11:36:38 +01:00
const internalRecipientKeyData = ( await cryptoFacadeTmp . encryptBucketKeyForInternalRecipient (
senderUserGroup . _id ,
bk ,
recipientMailAddress ,
notFoundRecipients ,
) ) as InternalRecipientKeyData
2024-04-17 10:34:33 +02:00
o ( internalRecipientKeyData ! . recipientKeyVersion ) . equals ( "0" )
2023-12-18 11:36:38 +01:00
o ( internalRecipientKeyData ! . mailAddress ) . equals ( recipientMailAddress )
o ( await rsa . decrypt ( recipientKeyPairs . privateKey , internalRecipientKeyData ! . pubEncBucketKey ) ) . deepEquals ( bitArrayToUint8Array ( bk ) )
verify ( pqFacadeMock , { times : 0 } )
verify ( serviceExecutor . put ( PublicKeyService , anything ( ) ) , { times : 0 } )
} )
o ( "authenticateSender | sender is authenticated for correct SenderIdentityKey" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
2024-05-06 11:08:05 +02:00
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . TUTACRYPT_AUTHENTICATION_SUCCEEDED )
2023-12-18 11:36:38 +01:00
} )
o ( "authenticateSender | sender is authenticated for correct SenderIdentityKey from system@tutanota.de" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( [ ] , false )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const pubKeyServiceCaptor = captor ( )
verify ( serviceExecutor . get ( PublicKeyService , pubKeyServiceCaptor . capture ( ) ) )
const pubKeyAddress = pubKeyServiceCaptor . value as PublicKeyGetIn
o ( pubKeyAddress . mailAddress ) . equals ( "system@tutanota.de" )
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
2024-05-06 11:08:05 +02:00
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . TUTACRYPT_AUTHENTICATION_SUCCEEDED )
2023-12-18 11:36:38 +01:00
} )
o ( "authenticateSender | sender is not authenticated for incorrect SenderIdentityKey" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
const wrongSenderIdentityKeyPair = generateEccKeyPair ( )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : wrongSenderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
2024-05-06 11:08:05 +02:00
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . TUTACRYPT_AUTHENTICATION_FAILED )
2023-12-18 11:36:38 +01:00
} )
o ( "authenticateSender | no authentication needed for sender with RSAKeypair" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) , { times : 1 } )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . RSA_NO_AUTHENTICATION )
} )
o ( "authenticateSender | no authentication needed for secure external recipient" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-05 14:03:33 +01:00
const file1SessionKey = aes256RandomKey ( )
const file2SessionKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const testData = await prepareConfidentialMailToExternalRecipient ( [ file1SessionKey , file2SessionKey ] )
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( mailSessionKey ) . deepEquals ( testData . sk )
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) , { times : 1 } )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . AES_NO_AUTHENTICATION )
} )
o ( "authenticateSender | no authentication needed for secure external sender" , async function ( ) {
//o.timeout(500) // in CI or with debugging it can take a while
const testData = await prepareConfidentialReplyFromExternalUser ( )
2024-04-17 10:34:33 +02:00
const externalUser = testData . externalUser
2023-12-18 11:36:38 +01:00
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( mailSessionKey ) . deepEquals ( testData . sk )
2024-04-17 10:34:33 +02:00
const mailCaptor = matchers . captor ( )
const userCaptor = matchers . captor ( )
verify ( keyLoaderFacade . loadSymGroupKey ( externalUser . userGroup . _id , Number ( externalUser . mailGroup . adminGroupKeyVersion ) , userCaptor . capture ( ) ) )
verify ( keyLoaderFacade . loadSymGroupKey ( externalUser . mailGroup . _id , testData . recipientKeyVersion , mailCaptor . capture ( ) ) )
o ( userCaptor . value . version ) . equals ( Number ( externalUser . userGroup . groupKeyVersion ) )
o ( mailCaptor . value . version ) . equals ( Number ( externalUser . mailGroup . groupKeyVersion ) )
2023-12-18 11:36:38 +01:00
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) , { times : 1 } )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value as Array < InstanceSessionKey >
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
const mailInstanceSessionKey = updatedInstanceSessionKeys . find ( ( instanceSessionKey ) = >
isSameId ( [ instanceSessionKey . instanceList , instanceSessionKey . instanceId ] , testData . mailLiteral . _id ) ,
)
const actualAutStatus = utf8Uint8ArrayToString ( aesDecrypt ( testData . sk , neverNull ( mailInstanceSessionKey ) . encryptionAuthStatus ! ) )
o ( actualAutStatus ) . deepEquals ( EncryptionAuthStatus . AES_NO_AUTHENTICATION )
} )
2020-04-29 15:55:56 +02:00
o . spec ( "instance migrations" , function ( ) {
2023-01-12 16:48:28 +01:00
o . beforeEach ( function ( ) {
2023-12-18 11:36:38 +01:00
when ( entityClient . update ( anything ( ) ) ) . thenResolve ( undefined )
2023-01-12 16:48:28 +01:00
} )
o ( "contact migration without birthday" , async function ( ) {
2023-11-09 17:04:42 +01:00
const contact = createTestEntity ( ContactTypeRef )
2022-03-09 17:43:29 +01:00
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 0 } )
2023-01-12 16:48:28 +01:00
} )
2022-03-09 17:43:29 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration without existing birthday" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
birthdayIso : "2019-05-01" ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 0 } )
2023-01-12 16:48:28 +01:00
} )
2022-03-09 17:43:29 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration without existing birthday and oldBirthdayDate" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
_id : [ "listid" , "id" ] ,
birthdayIso : "2019-05-01" ,
oldBirthdayDate : new Date ( 2000 , 4 , 1 ) ,
2022-03-09 17:43:29 +01:00
} )
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 1 } )
2023-01-12 16:48:28 +01:00
} )
2022-03-09 17:43:29 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration with existing birthday and oldBirthdayAggregate" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
_id : [ "listid" , "id" ] ,
birthdayIso : "2019-05-01" ,
2023-11-10 16:59:39 +01:00
oldBirthdayAggregate : createTestEntity ( BirthdayTypeRef , {
2023-01-12 16:48:28 +01:00
day : "01" ,
month : "05" ,
year : "2000" ,
} ) ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
2022-03-09 17:43:29 +01:00
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 1 } )
2023-01-12 16:48:28 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration from oldBirthdayAggregate" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
_id : [ "listid" , "id" ] ,
oldBirthdayDate : new Date ( 1800 , 4 , 1 ) ,
2023-11-10 16:59:39 +01:00
oldBirthdayAggregate : createTestEntity ( BirthdayTypeRef , {
2023-01-12 16:48:28 +01:00
day : "01" ,
month : "05" ,
year : "2000" ,
} ) ,
2022-03-09 17:43:29 +01:00
} )
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( migratedContact . birthdayIso ) . equals ( "2000-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 1 } )
2023-01-12 16:48:28 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration from oldBirthdayDate" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
_id : [ "listid" , "id" ] ,
birthdayIso : null ,
oldBirthdayDate : new Date ( 1800 , 4 , 1 ) ,
oldBirthdayAggregate : null ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( migratedContact . birthdayIso ) . equals ( "1800-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 1 } )
2023-01-12 16:48:28 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( "contact migration from oldBirthdayAggregate without year" , async function ( ) {
2023-11-10 16:59:39 +01:00
const contact = createTestEntity ( ContactTypeRef , {
2023-01-12 16:48:28 +01:00
_id : [ "listid" , "id" ] ,
birthdayIso : null ,
oldBirthdayDate : null ,
2023-11-10 16:59:39 +01:00
oldBirthdayAggregate : createTestEntity ( BirthdayTypeRef , {
2023-01-12 16:48:28 +01:00
day : "01" ,
month : "05" ,
year : null ,
} ) ,
2022-03-09 17:43:29 +01:00
} )
2023-01-12 16:48:28 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( migratedContact . birthdayIso ) . equals ( "--05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2023-12-18 11:36:38 +01:00
verify ( entityClient . update ( anything ( ) ) , { times : 1 } )
2023-01-12 16:48:28 +01:00
} )
2023-12-18 11:36:38 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
o ( "resolve session key: rsa public key decryption of mail session key using BucketKey aggregated type - Mail referencing MailBody" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
} )
o ( "resolve session key: rsa public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsDraft" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { mailDetailsDraft : [ "draftDetailsListId" , "draftDetailsId" ] } )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
} )
o (
"resolve session key: rsa public key decryption of mail session key using BucketKey aggregated type - already decoded/decrypted Mail referencing MailDetailsDraft" ,
async function ( ) {
2023-01-12 16:48:28 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-18 11:36:38 +01:00
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , {
mailDetailsDraft : [ "draftDetailsListId" , "draftDetailsId" ] ,
} )
const mailInstance = await instanceMapper . decryptAndMapToInstance < Mail > ( testData . MailTypeModel , testData . mailLiteral , testData . sk )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
// do not use testdouble here because it's hard to not break the function itself and then verify invocations
const decryptAndMapToInstance = ( instanceMapper . decryptAndMapToInstance = spy ( instanceMapper . decryptAndMapToInstance ) )
const convertBucketKeyToInstanceIfNecessary = ( crypto . convertBucketKeyToInstanceIfNecessary = spy ( crypto . convertBucketKeyToInstanceIfNecessary ) )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , mailInstance ) )
o ( decryptAndMapToInstance . invocations . length ) . equals ( 0 )
o ( convertBucketKeyToInstanceIfNecessary . invocations . length ) . equals ( 1 )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( sessionKey ) . deepEquals ( testData . sk )
2023-12-18 11:36:38 +01:00
} ,
)
o ( "resolve session key: rsa public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsBlob" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
o ( sessionKey ) . deepEquals ( testData . sk )
} )
o (
"resolve session key: rsa public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsBlob with attachments" ,
async function ( ) {
2023-01-12 16:48:28 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-05 14:03:33 +01:00
const file1SessionKey = aes256RandomKey ( )
const file2SessionKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const testData = await prepareRsaPubEncBucketKeyResolveSessionKeyTest ( [ file1SessionKey , file2SessionKey ] )
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
2023-01-12 16:48:28 +01:00
2023-12-18 11:36:38 +01:00
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( mailSessionKey ) . deepEquals ( testData . sk )
2023-01-12 16:48:28 +01:00
2023-12-18 11:36:38 +01:00
o ( testData . bucketKey . bucketEncSessionKeys . length ) . equals ( 3 ) //mail, file1, file2
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
for ( const isk of testData . bucketKey . bucketEncSessionKeys ) {
2023-12-05 14:03:33 +01:00
const expectedSessionKey = decryptKey ( testData . bk , isk . symEncSessionKey )
2023-12-18 11:36:38 +01:00
o (
2023-12-05 14:03:33 +01:00
updatedInstanceSessionKeys . some ( ( updatedKey ) = > {
let updatedSessionKey = decryptKey ( testData . mailGroupKey , updatedKey . symEncSessionKey )
return (
2023-12-18 11:36:38 +01:00
updatedKey . instanceId === isk . instanceId &&
updatedKey . instanceList === isk . instanceList &&
updatedKey . typeInfo . application === isk . typeInfo . application &&
updatedKey . typeInfo . typeId === isk . typeInfo . typeId &&
2023-12-05 14:03:33 +01:00
arrayEquals ( updatedSessionKey , expectedSessionKey )
)
} ) ,
2023-12-18 11:36:38 +01:00
) . equals ( true )
}
} ,
)
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
// ------------
2023-01-12 16:48:28 +01:00
2023-12-18 11:36:38 +01:00
o ( "resolve session key: pq public key decryption of mail session key using BucketKey aggregated type - Mail referencing MailBody" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { body : "bodyId" } )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
2023-01-12 16:48:28 +01:00
2023-12-18 11:36:38 +01:00
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
o ( sessionKey ) . deepEquals ( testData . sk )
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
o ( "resolve session key: pq public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsDraft" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { mailDetailsDraft : [ "draftDetailsListId" , "draftDetailsId" ] } )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
2023-01-12 16:48:28 +01:00
)
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
} )
o (
"resolve session key: pq public key decryption of mail session key using BucketKey aggregated type - already decoded/decrypted Mail referencing MailDetailsDraft" ,
async function ( ) {
2023-01-12 16:48:28 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-18 11:36:38 +01:00
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , {
mailDetailsDraft : [ "draftDetailsListId" , "draftDetailsId" ] ,
} )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
const mailInstance = await instanceMapper . decryptAndMapToInstance < Mail > ( testData . MailTypeModel , testData . mailLiteral , testData . sk )
// do not use testdouble here because it's hard to not break the function itself and then verify invocations
const decryptAndMapToInstance = ( instanceMapper . decryptAndMapToInstance = spy ( instanceMapper . decryptAndMapToInstance ) )
const convertBucketKeyToInstanceIfNecessary = ( crypto . convertBucketKeyToInstanceIfNecessary = spy ( crypto . convertBucketKeyToInstanceIfNecessary ) )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , mailInstance ) )
// TODO is it ok to remove this: decryptAndMapToInstance is now called when resolving the session key
// o(decryptAndMapToInstance.invocations.length).equals(0)
o ( convertBucketKeyToInstanceIfNecessary . invocations . length ) . equals ( 1 )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-01-12 16:48:28 +01:00
o ( sessionKey ) . deepEquals ( testData . sk )
2023-12-18 11:36:38 +01:00
} ,
)
2022-03-09 17:43:29 +01:00
2023-12-18 11:36:38 +01:00
o ( "resolve session key: pq public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsBlob" , async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( )
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
2023-01-12 16:48:28 +01:00
)
2023-12-18 11:36:38 +01:00
const sessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( sessionKey ) . deepEquals ( testData . sk )
2023-01-12 16:48:28 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
o (
2023-12-18 11:36:38 +01:00
"resolve session key: pq public key decryption of session key using BucketKey aggregated type - Mail referencing MailDetailsBlob with attachments" ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-05 14:03:33 +01:00
const file1SessionKey = aes256RandomKey ( )
const file2SessionKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const testData = await preparePqPubEncBucketKeyResolveSessionKeyTest ( [ file1SessionKey , file2SessionKey ] )
2023-01-12 16:48:28 +01:00
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
when ( serviceExecutor . get ( PublicKeyService , anything ( ) ) ) . thenResolve (
createPublicKeyGetOut ( {
pubEccKey : testData.senderIdentityKeyPair.publicKey ,
pubKeyVersion : "0" ,
pubKyberKey : null ,
pubRsaKey : null ,
} ) ,
)
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
2023-12-18 11:36:38 +01:00
o ( mailSessionKey ) . deepEquals ( testData . sk )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
o ( testData . bucketKey . bucketEncSessionKeys . length ) . equals ( 3 ) //mail, file1, file2
const updatedInstanceSessionKeysCaptor = captor ( )
verify ( ownerEncSessionKeysUpdateQueue . updateInstanceSessionKeys ( updatedInstanceSessionKeysCaptor . capture ( ) ) )
const updatedInstanceSessionKeys = updatedInstanceSessionKeysCaptor . value
o ( updatedInstanceSessionKeys . length ) . equals ( testData . bucketKey . bucketEncSessionKeys . length )
for ( const isk of testData . bucketKey . bucketEncSessionKeys ) {
2023-12-05 14:03:33 +01:00
const expectedSessionKey = decryptKey ( testData . bk , isk . symEncSessionKey )
2023-12-18 11:36:38 +01:00
if (
2023-12-05 14:03:33 +01:00
! updatedInstanceSessionKeys . some ( ( updatedKey ) = > {
const updatedSessionKey = decryptKey ( testData . mailGroupKey , updatedKey . symEncSessionKey )
return (
2023-12-18 11:36:38 +01:00
updatedKey . instanceId === isk . instanceId &&
updatedKey . instanceList === isk . instanceList &&
updatedKey . typeInfo . application === isk . typeInfo . application &&
updatedKey . typeInfo . typeId === isk . typeInfo . typeId &&
2023-12-05 14:03:33 +01:00
arrayEquals ( updatedSessionKey , expectedSessionKey )
)
} )
2023-12-18 11:36:38 +01:00
) {
console . log ( "===============================" )
updatedInstanceSessionKeys . some ( ( updatedKey ) = > {
2023-12-05 14:03:33 +01:00
const updatedSessionKey = decryptKey ( testData . mailGroupKey , updatedKey . symEncSessionKey )
2023-12-18 11:36:38 +01:00
console . log ( ">>>>>>>>>>>>>>>>>>>>>>>" )
console . log ( "1 " , updatedKey . instanceId , isk . instanceId )
console . log ( "2 " , updatedKey . instanceList , isk . instanceList )
console . log ( "3 " , updatedKey . typeInfo . application , isk . typeInfo . application )
console . log ( "4 " , updatedKey . typeInfo . typeId , isk . typeInfo . typeId )
2023-12-05 14:03:33 +01:00
console . log ( "5 " , updatedSessionKey , expectedSessionKey )
2023-12-18 11:36:38 +01:00
} )
}
o (
2023-12-05 14:03:33 +01:00
updatedInstanceSessionKeys . some ( ( updatedKey ) = > {
const updatedSessionKey = decryptKey ( testData . mailGroupKey , updatedKey . symEncSessionKey )
return (
2023-12-18 11:36:38 +01:00
updatedKey . instanceId === isk . instanceId &&
updatedKey . instanceList === isk . instanceList &&
updatedKey . typeInfo . application === isk . typeInfo . application &&
updatedKey . typeInfo . typeId === isk . typeInfo . typeId &&
2023-12-05 14:03:33 +01:00
arrayEquals ( updatedSessionKey , expectedSessionKey )
)
} ) ,
2023-12-18 11:36:38 +01:00
) . equals ( true )
}
} ,
)
o (
"resolve session key: external user key decryption of session key using BucketKey aggregated type encrypted with MailGroupKey - Mail referencing MailDetailsBlob with attachments" ,
async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-05 14:03:33 +01:00
const file1SessionKey = aes256RandomKey ( )
const file2SessionKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const testData = await prepareConfidentialMailToExternalRecipient ( [ file1SessionKey , file2SessionKey ] )
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
o ( mailSessionKey ) . deepEquals ( testData . sk )
} ,
)
2023-01-26 16:34:37 +01:00
o (
"resolve session key: external user key decryption of session key using BucketKey aggregated type encrypted with UserGroupKey - Mail referencing MailDetailsBlob with attachments" ,
async function ( ) {
o . timeout ( 500 ) // in CI or with debugging it can take a while
2023-12-05 14:03:33 +01:00
const file1SessionKey = aes256RandomKey ( )
const file2SessionKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const testData = await prepareConfidentialMailToExternalRecipient ( [ file1SessionKey , file2SessionKey ] , true )
2023-01-26 16:34:37 +01:00
Object . assign ( testData . mailLiteral , { mailDetails : [ "mailDetailsArchiveId" , "mailDetailsId" ] } )
const mailSessionKey = neverNull ( await crypto . resolveSessionKey ( testData . MailTypeModel , testData . mailLiteral ) )
o ( mailSessionKey ) . deepEquals ( testData . sk )
} ,
)
2023-08-08 14:52:14 +02:00
o ( "resolve session key: MailDetailsBlob" , async function ( ) {
2023-12-05 14:03:33 +01:00
const gk = aes256RandomKey ( )
const sk = aes256RandomKey ( )
2024-04-17 10:34:33 +02:00
const ownerGroup = "mailGroupId"
when ( keyLoaderFacade . getCurrentSymGroupKey ( ownerGroup ) ) . thenResolve ( { object : gk , version : 0 } )
when ( userFacade . hasGroup ( ownerGroup ) ) . thenReturn ( true )
2023-08-08 14:52:14 +02:00
when ( userFacade . isFullyLoggedIn ( ) ) . thenReturn ( true )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const MailDetailsBlobTypeModel = await resolveTypeReference ( MailDetailsBlobTypeRef )
const mailDetailsBlobLiteral = {
_id : [ "mailDetailsArchiveId" , "mailDetailsId" ] ,
2024-04-17 10:34:33 +02:00
_ownerGroup : ownerGroup ,
2023-08-08 14:52:14 +02:00
_ownerEncSessionKey : encryptKey ( gk , sk ) ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
}
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadSymGroupKey ( ownerGroup , 0 ) ) . thenResolve ( gk )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const mailDetailsBlobSessionKey = neverNull ( await crypto . resolveSessionKey ( MailDetailsBlobTypeModel , mailDetailsBlobLiteral ) )
o ( mailDetailsBlobSessionKey ) . deepEquals ( sk )
} )
2023-08-08 14:52:14 +02:00
o ( "resolve session key: MailDetailsBlob - session key not found" , async function ( ) {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const MailDetailsBlobTypeModel = await resolveTypeReference ( MailDetailsBlobTypeRef )
const mailDetailsBlobLiteral = {
_id : [ "mailDetailsArchiveId" , "mailDetailsId" ] ,
_permissions : "permissionListId" ,
}
when ( entityClient . loadAll ( PermissionTypeRef , "permissionListId" ) ) . thenResolve ( [ ] )
try {
await crypto . resolveSessionKey ( MailDetailsBlobTypeModel , mailDetailsBlobLiteral )
o ( true ) . equals ( false ) // let the test fails if there is no exception
} catch ( error ) {
o ( error . constructor ) . equals ( SessionKeyNotFoundError )
}
} )
/ * *
2023-12-18 11:36:38 +01:00
* Prepares the environment to test receiving rsa asymmetric encrypted emails that have been sent with the simplified permission system .
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
* - Creates key pair for the recipient user
* - Creates group , bucket and session keys
* - Creates mail literal and encrypts all encrypted attributes of the mail
* - Create BucketKey object on the mail
*
* @param fileSessionKeys List of session keys for the attachments . When the list is empty there are no attachments
* /
2023-12-05 14:03:33 +01:00
async function prepareRsaPubEncBucketKeyResolveSessionKeyTest ( fileSessionKeys : Array < Aes256Key > = [ ] ) : Promise < {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
mailLiteral : Record < string , any >
bucketKey : BucketKey
2023-12-05 14:03:33 +01:00
sk : Aes256Key
bk : Aes256Key
mailGroupKey : Aes256Key
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
MailTypeModel : TypeModel
} > {
2023-12-18 11:36:38 +01:00
// configure test user
2024-04-17 10:34:33 +02:00
const recipientUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientUser , userFacade , keyLoaderFacade )
2023-12-18 11:36:38 +01:00
2023-12-18 17:30:21 +01:00
let privateKey = RSA_TEST_KEYPAIR . privateKey
let publicKey = RSA_TEST_KEYPAIR . publicKey
2023-12-18 11:36:38 +01:00
const keyPair = createTestEntity ( KeyPairTypeRef , {
_id : "keyPairId" ,
symEncPrivRsaKey : encryptRsaKey ( recipientUser . userGroupKey , privateKey ) ,
2023-12-18 17:30:21 +01:00
pubRsaKey : hexToUint8Array ( rsaPublicKeyToHex ( publicKey ) ) ,
2023-12-18 11:36:38 +01:00
} )
2024-04-17 10:34:33 +02:00
recipientUser . userGroup . currentKeys = keyPair
when ( keyLoaderFacade . loadKeypair ( recipientUser . userGroup . _id , 0 ) ) . thenResolve ( RSA_TEST_KEYPAIR )
2023-12-18 11:36:38 +01:00
// configure mail
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2023-12-18 11:36:38 +01:00
2023-12-05 14:03:33 +01:00
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const mailLiteral = createMailLiteral ( null , sk , subject , confidential , senderName , recipientUser . name , recipientUser . mailGroup . _id )
const pubEncBucketKey = await rsaEncrypt ( publicKey , bitArrayToUint8Array ( bk ) )
const bucketEncMailSessionKey = encryptKey ( bk , sk )
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
typeModels . tutanota
const mailInstanceSessionKey = createInstanceSessionKey ( {
typeInfo : createTypeInfo ( {
application : MailTypeModel.app ,
typeId : String ( MailTypeModel . id ) ,
} ) ,
symEncSessionKey : bucketEncMailSessionKey ,
instanceList : "mailListId" ,
instanceId : "mailId" ,
encryptionAuthStatus : null ,
2024-04-17 10:34:33 +02:00
symKeyVersion : "0" ,
2020-04-29 15:55:56 +02:00
} )
2023-12-18 11:36:38 +01:00
const FileTypeModel = await resolveTypeReference ( FileTypeRef )
const bucketEncSessionKeys = fileSessionKeys . map ( ( fileSessionKey , index ) = > {
return createInstanceSessionKey ( {
typeInfo : createTypeInfo ( {
application : FileTypeModel.app ,
typeId : String ( FileTypeModel . id ) ,
} ) ,
symEncSessionKey : encryptKey ( bk , fileSessionKey ) ,
2024-04-17 10:34:33 +02:00
symKeyVersion : "0" ,
2023-12-18 11:36:38 +01:00
instanceList : "fileListId" ,
instanceId : "fileId" + ( index + 1 ) ,
encryptionAuthStatus : null ,
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
2023-12-18 11:36:38 +01:00
bucketEncSessionKeys . push ( mailInstanceSessionKey )
const bucketKey = createBucketKey ( {
pubEncBucketKey : pubEncBucketKey ,
keyGroup : recipientUser.userGroup._id ,
bucketEncSessionKeys : bucketEncSessionKeys ,
groupEncBucketKey : null ,
protocolVersion : "0" ,
2024-04-17 10:34:33 +02:00
senderKeyVersion : null ,
recipientKeyVersion : "0" ,
2023-12-18 11:36:38 +01:00
} )
const BucketKeyModel = await resolveTypeReference ( BucketKeyTypeRef )
const bucketKeyLiteral = await instanceMapper . encryptAndMapToLiteral ( BucketKeyModel , bucketKey , null )
Object . assign ( mailLiteral , { bucketKey : bucketKeyLiteral } )
return {
mailLiteral ,
bucketKey ,
sk ,
bk ,
mailGroupKey : recipientUser.mailGroupKey ,
MailTypeModel ,
}
}
/ * *
* Prepares the environment to test receiving pq asymmetric encrypted emails that have been sent with the simplified permission system .
* - Creates key pair for the recipient user
* - Creates group , bucket and session keys
* - Creates mail literal and encrypts all encrypted attributes of the mail
* - Create BucketKey object on the mail
*
* @param fileSessionKeys List of session keys for the attachments . When the list is empty there are no attachments
* /
async function preparePqPubEncBucketKeyResolveSessionKeyTest (
2024-04-17 10:34:33 +02:00
fileSessionKeys : Array < AesKey > = [ ] ,
2023-12-18 11:36:38 +01:00
confidential : boolean = true ,
) : Promise < {
mailLiteral : Record < string , any >
bucketKey : BucketKey
2024-04-17 10:34:33 +02:00
sk : AesKey
bk : AesKey
mailGroupKey : AesKey
2023-12-18 11:36:38 +01:00
MailTypeModel : TypeModel
senderIdentityKeyPair : EccKeyPair
} > {
// create test user
2024-04-17 10:34:33 +02:00
const recipientUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( recipientUser , userFacade , keyLoaderFacade )
2023-12-18 11:36:38 +01:00
let pqKeyPairs = await pqFacade . generateKeyPairs ( )
const recipientKeyPair = createKeyPair ( {
_id : "keyPairId" ,
pubEccKey : pqKeyPairs.eccKeyPair.publicKey ,
symEncPrivEccKey : aesEncrypt ( recipientUser . userGroupKey , pqKeyPairs . eccKeyPair . privateKey ) ,
pubKyberKey : kyberPublicKeyToBytes ( pqKeyPairs . kyberKeyPair . publicKey ) ,
symEncPrivKyberKey : aesEncrypt ( recipientUser . userGroupKey , kyberPrivateKeyToBytes ( pqKeyPairs . kyberKeyPair . privateKey ) ) ,
pubRsaKey : null ,
symEncPrivRsaKey : null ,
} )
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadKeypair ( recipientUser . userGroup . _id , 0 ) ) . thenResolve ( pqKeyPairs )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
recipientUser . userGroup . currentKeys = recipientKeyPair
2023-12-18 11:36:38 +01:00
const senderIdentityKeyPair = generateEccKeyPair ( )
// create test mail
let subject = "this is our subject"
let senderName = "TutanotaTeam"
2023-12-05 14:03:33 +01:00
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const mailLiteral = createMailLiteral (
recipientUser . mailGroupKey ,
sk ,
subject ,
confidential ,
senderName ,
recipientUser . name ,
recipientUser . mailGroup . _id ,
)
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
// @ts-ignore
mailLiteral . _ownerEncSessionKey = null
2023-12-18 17:30:21 +01:00
const pqMessage = await pqFacade . encapsulate ( senderIdentityKeyPair , generateEccKeyPair ( ) , pqKeyPairsToPublicKeys ( pqKeyPairs ) , bitArrayToUint8Array ( bk ) )
2023-12-18 11:36:38 +01:00
const pubEncBucketKey = encodePQMessage ( pqMessage )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const bucketEncMailSessionKey = encryptKey ( bk , sk )
2024-04-17 10:34:33 +02:00
const { MailTypeModel , bucketKey } = await prepareBucketKeyInstance (
bucketEncMailSessionKey ,
fileSessionKeys ,
bk ,
pubEncBucketKey ,
recipientUser ,
instanceMapper ,
mailLiteral ,
)
2022-03-09 17:43:29 +01:00
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
return {
mailLiteral ,
bucketKey ,
sk ,
bk ,
2023-12-18 11:36:38 +01:00
mailGroupKey : recipientUser.mailGroupKey ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
MailTypeModel ,
2023-12-18 11:36:38 +01:00
senderIdentityKeyPair ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
}
}
2022-03-09 17:43:29 +01:00
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
/ * *
* Prepares the environment to test receiving symmetric encrypted emails ( mails sent from internal to external user ) that have been sent with the simplified permission system .
* - Creates group , bucket and session keys
* - Creates mail literal and encrypts all encrypted attributes of the mail
* - Create BucketKey object on the mail
*
* @param fileSessionKeys List of session keys for the attachments . When the list is empty there are no attachments
2023-12-18 11:36:38 +01:00
* @param externalUserGroupEncBucketKey for legacy external user group to encrypt bucket key
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
* /
2023-12-18 11:36:38 +01:00
async function prepareConfidentialMailToExternalRecipient (
2024-04-17 10:34:33 +02:00
fileSessionKeys : Array < AesKey > = [ ] ,
2023-01-26 16:34:37 +01:00
externalUserGroupEncBucketKey = false ,
) : Promise < {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
mailLiteral : Record < string , any >
2023-12-18 11:36:38 +01:00
bucketKey : BucketKey
2024-04-17 10:34:33 +02:00
sk : AesKey
bk : AesKey
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
MailTypeModel : TypeModel
} > {
2023-12-18 11:36:38 +01:00
// create user
2024-04-17 10:34:33 +02:00
const externalUser = createTestUser ( "Bob" , entityClient )
configureLoggedInUser ( externalUser , userFacade , keyLoaderFacade )
2023-12-18 11:36:38 +01:00
// create test mail
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
2023-12-05 14:03:33 +01:00
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-01-26 16:34:37 +01:00
2023-12-18 11:36:38 +01:00
const mailLiteral = createMailLiteral ( null , sk , subject , confidential , senderName , externalUser . name , externalUser . mailGroup . _id )
2020-04-29 15:55:56 +02:00
2023-12-18 11:36:38 +01:00
const groupKeyToEncryptBucketKey = externalUserGroupEncBucketKey ? externalUser.userGroupKey : externalUser.mailGroupKey
2023-01-26 16:34:37 +01:00
const groupEncBucketKey = encryptKey ( groupKeyToEncryptBucketKey , bk )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
const bucketEncMailSessionKey = encryptKey ( bk , sk )
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
typeModels . tutanota
2023-11-10 16:59:39 +01:00
const mailInstanceSessionKey = createTestEntity ( InstanceSessionKeyTypeRef , {
typeInfo : createTestEntity ( TypeInfoTypeRef , {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
application : MailTypeModel.app ,
typeId : String ( MailTypeModel . id ) ,
} ) ,
symEncSessionKey : bucketEncMailSessionKey ,
instanceList : "mailListId" ,
instanceId : "mailId" ,
} )
const FileTypeModel = await resolveTypeReference ( FileTypeRef )
const bucketEncSessionKeys = fileSessionKeys . map ( ( fileSessionKey , index ) = > {
2023-11-10 16:59:39 +01:00
return createTestEntity ( InstanceSessionKeyTypeRef , {
typeInfo : createTestEntity ( TypeInfoTypeRef , {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
application : FileTypeModel.app ,
typeId : String ( FileTypeModel . id ) ,
2022-03-09 17:43:29 +01:00
} ) ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
symEncSessionKey : encryptKey ( bk , fileSessionKey ) ,
instanceList : "fileListId" ,
instanceId : "fileId" + ( index + 1 ) ,
2022-03-09 17:43:29 +01:00
} )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
bucketEncSessionKeys . push ( mailInstanceSessionKey )
2022-03-09 17:43:29 +01:00
2023-11-10 16:59:39 +01:00
const bucketKey = createTestEntity ( BucketKeyTypeRef , {
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
pubEncBucketKey : null ,
2023-12-18 11:36:38 +01:00
keyGroup : externalUserGroupEncBucketKey ? externalUser.userGroup._id : null ,
2023-01-26 16:34:37 +01:00
groupEncBucketKey : groupEncBucketKey ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
bucketEncSessionKeys : bucketEncSessionKeys ,
} )
const BucketKeyModel = await resolveTypeReference ( BucketKeyTypeRef )
const bucketKeyLiteral = await instanceMapper . encryptAndMapToLiteral ( BucketKeyModel , bucketKey , null )
2023-01-12 16:48:28 +01:00
Object . assign ( mailLiteral , { bucketKey : bucketKeyLiteral } )
2022-03-09 17:43:29 +01:00
2023-12-18 11:36:38 +01:00
return {
mailLiteral ,
bucketKey ,
sk ,
bk ,
MailTypeModel ,
}
}
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
/ * *
* Prepares the environment to test receiving symmetric encrypted emails from an external sender ( mails sent from external to internal user ) that have been sent with the simplified permission system .
* - Creates group , bucket and session keys
* - Creates mail literal and encrypts all encrypted attributes of the mail
* - Create BucketKey object on the mail
*
* @param fileSessionKeys List of session keys for the attachments . When the list is empty there are no attachments
* /
async function prepareConfidentialReplyFromExternalUser ( ) : Promise < {
mailLiteral : Record < string , any >
bucketKey : BucketKey
2024-04-17 10:34:33 +02:00
sk : AesKey
bk : AesKey
2023-12-18 11:36:38 +01:00
MailTypeModel : TypeModel
internalUser : TestUser
externalUser : TestUser
2024-04-17 10:34:33 +02:00
recipientKeyVersion : number
2023-12-18 11:36:38 +01:00
} > {
// Setup test users and groups
2024-04-17 10:34:33 +02:00
const internalUser = createTestUser ( "Alice" , entityClient )
const externalUser = createTestUser ( "Bob" , entityClient )
2023-12-18 11:36:38 +01:00
// Setup relationship between internal and external user
externalUser . userGroup . admin = internalUser . userGroup . _id
externalUser . userGroup . adminGroupEncGKey = encryptKey ( internalUser . userGroupKey , externalUser . userGroupKey )
2024-04-17 10:34:33 +02:00
externalUser . userGroup . adminGroupKeyVersion = "0"
2023-12-18 11:36:38 +01:00
externalUser . mailGroup . admin = externalUser . userGroup . _id
externalUser . mailGroup . adminGroupEncGKey = encryptKey ( externalUser . userGroupKey , externalUser . mailGroupKey )
2024-04-17 10:34:33 +02:00
externalUser . mailGroup . adminGroupKeyVersion = "4"
const recipientKeyVersion = "5"
externalUser . userGroup . groupKeyVersion = "7"
externalUser . mailGroup . groupKeyVersion = "8"
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
configureLoggedInUser ( internalUser , userFacade , keyLoaderFacade )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
when ( keyLoaderFacade . loadSymGroupKey ( externalUser . mailGroup . _id , Number ( recipientKeyVersion ) , anything ( ) ) ) . thenResolve ( externalUser . mailGroupKey )
when ( keyLoaderFacade . loadSymGroupKey ( externalUser . userGroup . _id , Number ( externalUser . mailGroup . adminGroupKeyVersion ) , anything ( ) ) ) . thenResolve (
externalUser . userGroupKey ,
)
// setup test mail (confidential reply from external)
2023-12-18 11:36:38 +01:00
let subject = "this is our subject"
let confidential = true
2023-12-05 14:03:33 +01:00
let sk = aes256RandomKey ( )
let bk = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
const mailLiteral = createMailLiteral ( null , sk , subject , confidential , externalUser . name , internalUser . name , internalUser . mailGroup . _id )
const keyGroup = externalUser . mailGroup . _id
const groupEncBucketKey = encryptKey ( externalUser . mailGroupKey , bk )
const bucketEncMailSessionKey = encryptKey ( bk , sk )
const MailTypeModel = await resolveTypeReference ( MailTypeRef )
typeModels . tutanota
const mailInstanceSessionKey = createTestEntity ( InstanceSessionKeyTypeRef , {
typeInfo : createTestEntity ( TypeInfoTypeRef , {
application : MailTypeModel.app ,
typeId : String ( MailTypeModel . id ) ,
} ) ,
symEncSessionKey : bucketEncMailSessionKey ,
instanceList : "mailListId" ,
instanceId : "mailId" ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
} )
2023-12-18 11:36:38 +01:00
const bucketEncSessionKeys = new Array < InstanceSessionKey > ( )
bucketEncSessionKeys . push ( mailInstanceSessionKey )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
2023-12-18 11:36:38 +01:00
const bucketKey = createTestEntity ( BucketKeyTypeRef , {
pubEncBucketKey : null ,
keyGroup : keyGroup ,
groupEncBucketKey : groupEncBucketKey ,
2024-04-17 10:34:33 +02:00
recipientKeyVersion ,
2023-12-18 11:36:38 +01:00
bucketEncSessionKeys : bucketEncSessionKeys ,
2024-04-17 10:34:33 +02:00
protocolVersion : CryptoProtocolVersion.SYMMETRIC_ENCRYPTION ,
senderKeyVersion : null ,
2023-12-18 11:36:38 +01:00
} )
const BucketKeyModel = await resolveTypeReference ( BucketKeyTypeRef )
const bucketKeyLiteral = await instanceMapper . encryptAndMapToLiteral ( BucketKeyModel , bucketKey , null )
Object . assign ( mailLiteral , { bucketKey : bucketKeyLiteral } )
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
return {
mailLiteral ,
2023-12-18 11:36:38 +01:00
bucketKey ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
sk ,
bk ,
MailTypeModel ,
2023-12-18 11:36:38 +01:00
internalUser ,
externalUser ,
2024-04-17 10:34:33 +02:00
recipientKeyVersion : Number ( recipientKeyVersion ) ,
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
}
}
2024-04-17 10:34:33 +02:00
} )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
export function createMailLiteral (
ownerGroupKey : AesKey | null ,
sessionKey ,
subject ,
confidential ,
senderName ,
recipientName ,
ownerGroupId : string ,
) : Record < string , any > {
return {
_format : "0" ,
_area : "0" ,
_owner : "ownerId" ,
_ownerGroup : ownerGroupId ,
_ownerEncSessionKey : ownerGroupKey ? encryptKey ( ownerGroupKey , sessionKey ) : null ,
_id : [ "mailListId" , "mailId" ] ,
_permissions : "permissionListId" ,
receivedDate : new Date ( 1470039025474 ) . getTime ( ) . toString ( ) ,
sentDate : new Date ( 1470039021474 ) . getTime ( ) . toString ( ) ,
state : "" ,
trashed : false ,
unread : true ,
subject : uint8ArrayToBase64 ( aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( subject ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ) ,
replyType : "" ,
confidential : uint8ArrayToBase64 (
aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( confidential ? "1" : "0" ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ,
) ,
sender : {
_id : "senderId" ,
address : "hello@tutao.de" ,
name : uint8ArrayToBase64 ( aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( senderName ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ) ,
} ,
bccRecipients : [ ] ,
ccRecipients : [ ] ,
toRecipients : [
{
_id : "recipientId" ,
address : "support@yahoo.com" ,
name : uint8ArrayToBase64 (
aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( recipientName ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ,
) ,
} ,
] ,
replyTos : [ ] ,
bucketKey : null ,
attachmentCount : "0" ,
authStatus : "0" ,
listUnsubscribe : uint8ArrayToBase64 ( aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( "" ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ) ,
method : uint8ArrayToBase64 ( aesEncrypt ( sessionKey , stringToUtf8Uint8Array ( "" ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , ENABLE_MAC ) ) ,
phishingStatus : "0" ,
recipientCount : "0" ,
}
}
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
export function createTestUser ( name : string , entityClient : EntityClient ) : TestUser {
const userGroupKey = aes256RandomKey ( )
const mailGroupKey = aes256RandomKey ( )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
const userGroup = createTestEntity ( GroupTypeRef , {
_id : "userGroup" + name ,
type : GroupType . User ,
currentKeys : null ,
groupKeyVersion : "0" ,
} )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
const mailGroup = createTestEntity ( GroupTypeRef , {
_id : "mailGroup" + name ,
type : GroupType . Mail ,
currentKeys : null ,
groupKeyVersion : "0" ,
} )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
const userGroupMembership = createTestEntity ( GroupMembershipTypeRef , {
group : userGroup._id ,
} )
const mailGroupMembership = createTestEntity ( GroupMembershipTypeRef , {
group : mailGroup._id ,
} )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
const user = createTestEntity ( UserTypeRef , {
userGroup : userGroupMembership ,
memberships : [ mailGroupMembership ] ,
} )
2023-12-18 11:36:38 +01:00
2024-04-17 10:34:33 +02:00
when ( entityClient . load ( GroupTypeRef , userGroup . _id ) ) . thenResolve ( userGroup )
when ( entityClient . load ( GroupTypeRef , mailGroup . _id ) ) . thenResolve ( mailGroup )
return {
user ,
userGroup ,
mailGroup ,
userGroupKey ,
mailGroupKey ,
name ,
2023-12-18 11:36:38 +01:00
}
2024-04-17 10:34:33 +02:00
}
/ * *
* Helper function to mock the user facade so that the given test user is considered as logged in user .
* /
export function configureLoggedInUser ( testUser : TestUser , userFacade : UserFacade , keyLoaderFacade : KeyLoaderFacade ) {
when ( userFacade . getLoggedInUser ( ) ) . thenReturn ( testUser . user )
when ( keyLoaderFacade . getCurrentSymGroupKey ( testUser . mailGroup . _id ) ) . thenResolve ( { object : testUser . mailGroupKey , version : 0 } )
when ( keyLoaderFacade . getCurrentSymGroupKey ( testUser . userGroup . _id ) ) . thenResolve ( { object : testUser . userGroupKey , version : 0 } )
when ( userFacade . hasGroup ( testUser . userGroup . _id ) ) . thenReturn ( true )
when ( userFacade . hasGroup ( testUser . mailGroup . _id ) ) . thenReturn ( true )
when ( userFacade . getCurrentUserGroupKey ( ) ) . thenReturn ( { object : testUser . userGroupKey , version : 0 } )
when ( userFacade . isLeader ( ) ) . thenReturn ( true )
when ( userFacade . isFullyLoggedIn ( ) ) . thenReturn ( true )
when ( keyLoaderFacade . loadSymGroupKey ( testUser . mailGroup . _id , 0 ) ) . thenResolve ( testUser . mailGroupKey )
when ( keyLoaderFacade . loadSymGroupKey ( testUser . userGroup . _id , 0 ) ) . thenResolve ( testUser . userGroupKey )
}