2019-09-13 13:49:11 +02:00
import o from "ospec"
2019-08-21 15:12:04 +02:00
import {
base64ToUint8Array ,
2021-11-23 16:09:12 +01:00
downcast ,
2019-08-21 15:12:04 +02:00
hexToUint8Array ,
2021-11-23 16:09:12 +01:00
isSameTypeRef ,
neverNull ,
2019-08-21 15:12:04 +02:00
stringToUtf8Uint8Array ,
uint8ArrayToBase64 ,
2022-01-07 15:58:30 +01:00
utf8Uint8ArrayToString ,
2021-11-04 14:05:23 +01:00
} from "@tutao/tutanota-utils"
2022-01-07 15:58:30 +01:00
import { CryptoFacade , CryptoFacadeImpl } from "../../../src/api/worker/crypto/CryptoFacade"
2017-08-15 13:54:22 +02:00
import { ProgrammingError } from "../../../src/api/common/error/ProgrammingError"
import { Cardinality , ValueType } from "../../../src/api/common/EntityConstants"
2018-10-23 10:57:55 +02:00
import { BucketPermissionType , PermissionType } from "../../../src/api/common/TutanotaConstants"
2022-04-14 17:31:36 +02:00
import type { Mail } from "../../../src/api/entities/tutanota/TypeRefs.js"
import { _TypeModel as MailTypeModel , MailTypeRef } from "../../../src/api/entities/tutanota/TypeRefs.js"
import * as Contact from "../../../src/api/entities/tutanota/TypeRefs.js"
import { createContact } from "../../../src/api/entities/tutanota/TypeRefs.js"
import * as UserIdReturn from "../../../src/api/entities/sys/TypeRefs.js"
import { createUserIdReturn } from "../../../src/api/entities/sys/TypeRefs.js"
import { createPermission , PermissionTypeRef } from "../../../src/api/entities/sys/TypeRefs.js"
import { createBucket } from "../../../src/api/entities/sys/TypeRefs.js"
import { createGroup , GroupTypeRef } from "../../../src/api/entities/sys/TypeRefs.js"
import { createKeyPair } from "../../../src/api/entities/sys/TypeRefs.js"
import { BucketPermissionTypeRef , createBucketPermission } from "../../../src/api/entities/sys/TypeRefs.js"
import { createUser } from "../../../src/api/entities/sys/TypeRefs.js"
import { createGroupMembership } from "../../../src/api/entities/sys/TypeRefs.js"
import { createContactAddress } from "../../../src/api/entities/tutanota/TypeRefs.js"
import { MailAddressTypeRef } from "../../../src/api/entities/tutanota/TypeRefs.js"
2022-03-09 17:43:29 +01:00
import { assertThrows } from "@tutao/tutanota-test-utils"
2021-10-15 16:50:50 +02:00
import { LoginFacadeImpl } from "../../../src/api/worker/facades/LoginFacade"
2022-04-14 17:31:36 +02:00
import { createBirthday } from "../../../src/api/entities/tutanota/TypeRefs.js"
2020-09-02 16:19:30 +02:00
import { RestClient } from "../../../src/api/worker/rest/RestClient"
2022-04-14 17:31:36 +02:00
import { createWebsocketLeaderStatus } from "../../../src/api/entities/sys/TypeRefs.js"
2021-12-07 15:30:53 +01:00
import { EntityClient } from "../../../src/api/common/EntityClient"
2022-01-07 15:58:30 +01:00
import {
aes128Decrypt ,
aes128Encrypt ,
aes128RandomKey ,
bitArrayToUint8Array ,
ENABLE_MAC ,
encryptKey ,
encryptRsaKey ,
2022-02-10 16:32:47 +01:00
hexToPrivateKey ,
hexToPublicKey ,
2022-01-07 15:58:30 +01:00
IV_BYTE_LENGTH ,
2022-02-10 16:32:47 +01:00
random
2022-01-07 15:58:30 +01:00
} from "@tutao/tutanota-crypto"
import { RsaWeb } from "../../../src/api/worker/crypto/RsaImplementation"
2021-12-07 15:30:53 +01:00
import { decryptValue , encryptValue , InstanceMapper } from "../../../src/api/worker/crypto/InstanceMapper"
import { locator } from "../../../src/api/worker/WorkerLocator"
2022-01-07 15:58:30 +01:00
import type { ModelValue } from "../../../src/api/common/EntityTypes"
2022-03-09 17:43:29 +01:00
import { IServiceExecutor } from "../../../src/api/common/ServiceRequest"
import { matchers , object , verify , when } from "testdouble"
2022-04-14 17:31:36 +02:00
import { UpdatePermissionKeyService } from "../../../src/api/entities/sys/Services.js"
import { UpdatePermissionKeyData } from "../../../src/api/entities/sys/TypeRefs.js"
2022-03-09 17:43:29 +01:00
import { getListId , isSameId } from "../../../src/api/common/utils/EntityUtils"
2017-08-15 13:54:22 +02:00
2021-11-23 16:09:12 +01:00
const rsa = new RsaWeb ( )
const rsaEncrypt = rsa . encrypt
2017-08-15 13:54:22 +02:00
o . spec ( "crypto facade" , function ( ) {
2022-01-07 15:58:30 +01:00
let rsaPrivateHexKey =
"02008e8bf43e2990a46042da8168aebec699d62e1e1fd068c5582fd1d5433cee8c8b918799e8ee1a22dd9d6e21dd959d7faed8034663225848c21b88c2733c73788875639425a87d54882285e598bf7e8c83861e8b77ab3cf62c53d35e143cee9bb8b3f36850aebd1548c1881dc7485bb51aa13c5a0391b88a8d7afce88ecd4a7e231ca7cfd063216d1d573ad769a6bb557c251ad34beb393a8fff4a886715315ba9eac0bc31541999b92fcb33d15efd2bd50bf77637d3fc5ba1c21082f67281957832ac832fbad6c383779341555993bd945659d7797b9c993396915e6decee9da2d5e060c27c3b5a9bc355ef4a38088af53e5f795ccc837f45d0583052547a736f02002a7622214a3c5dda96cf83f0ececc3381c06ccce69446c54a299fccef49d929c1893ae1326a9fe6cc9727f00048b4ff7833d26806d40a31bbf1bf3e063c779c61c41b765a854fd1338456e691bd1d48571343413479cf72fa920b34b9002fbbbff4ea86a3042fece17683686a055411357a824a01f8e3b277dd54c690d59fd4c8258009707d917ce43d4a337dc58bb55394c4f87b902e7f78fa0abe35e35444bda46bfbc38cf87c60fbe5c4beff49f8e6ddbf50d6caafeb92a6ccef75474879bdb82c9c9c5c35611207dbdb7601c87b254927f4d9fd25ba7694987b5ca70c8184058a91e86cb974a2b7694d6bb08a349b953e4c9a017d9eecada49eb2981dfe10100c7905e44c348447551bea10787da3aa869bbe45f10cff87688e2696474bd18405432f4846dcee886d2a967a61c1adb9a9bc08d75cee678053bf41262f0d9882c230bd5289518569714b961cec3072ed2900f52c9cdc802ee4e63781a3c4acaee4347bd9ab701399a0b96cdf22a75501f7f232069e7f00f5649be5ac3d73edd970100b6dbc3e909e1b69ab3f5dd6a55d7cc68d2b803d3da16941410ab7a5b963e5c50316a52380d4b571633d870ca746b4d6f36e0a9d90cf96a2ddb9c61d5bc9dbe74473f0be99f3642100c1b8ad9d592c6a28fa6570ccbb3f7bb86be8056f76473b978a55d458343dba3d0dcaf152d225f20ccd384706dda9dd2fb0f5f6976e603e901002fd80cc1af8fc3d9dc9f373bf6f5fada257f46610446d7ea9326b4ddc09f1511571e6040df929b6cb754a5e4cd18234e0dc93c20e2599eaca29301557728afdce50a1130898e2c344c63a56f4c928c472f027d76a43f2f74b2966654e3df8a8754d9fe3af964f1ca5cbceae3040adc0ab1105ad5092624872b66d79bdc1ed6410100295bc590e4ea4769f04030e747293b138e6d8e781140c01755b9e33fe9d88afa9c62a6dc04adc0b1c5e23388a71249fe589431f664c7d8eb2c5bcf890f53426b7c5dd72ced14d1965d96b12e19ef4bbc22ef858ae05c01314a05b673751b244d93eb1b1088e3053fa512f50abe1da314811f6a3a1faeadb9b58d419052132e59010032611a3359d91ce3567675726e48aca0601def22111f73a9fea5faeb9a95ec37754d2e52d7ae9444765c39c66264c02b38d096df1cebe6ea9951676663301e577fa5e3aec29a660e0fff36389671f47573d2259396874c33069ddb25dd5b03dcbf803272e68713c320ef7db05765f1088473c9788642e4b80a8eb40968fc0d7c"
let rsaPublicHexKey =
"02008e8bf43e2990a46042da8168aebec699d62e1e1fd068c5582fd1d5433cee8c8b918799e8ee1a22dd9d6e21dd959d7faed8034663225848c21b88c2733c73788875639425a87d54882285e598bf7e8c83861e8b77ab3cf62c53d35e143cee9bb8b3f36850aebd1548c1881dc7485bb51aa13c5a0391b88a8d7afce88ecd4a7e231ca7cfd063216d1d573ad769a6bb557c251ad34beb393a8fff4a886715315ba9eac0bc31541999b92fcb33d15efd2bd50bf77637d3fc5ba1c21082f67281957832ac832fbad6c383779341555993bd945659d7797b9c993396915e6decee9da2d5e060c27c3b5a9bc355ef4a38088af53e5f795ccc837f45d0583052547a736f"
2021-12-07 15:30:53 +01:00
let login
let restClient
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
let crypto : CryptoFacade
2017-11-23 13:30:17 +01:00
o . before ( function ( ) {
2021-10-15 16:50:50 +02:00
const suspensionHandler = downcast ( { } )
restClient = new RestClient ( suspensionHandler )
2022-03-09 17:43:29 +01:00
login = new LoginFacadeImpl (
object ( ) ,
restClient ,
object ( ) ,
downcast ( { } ) ,
instanceMapper ,
( ) = > object ( ) ,
2022-04-11 13:36:20 +02:00
async ( ) = > {
} ,
2022-03-09 17:43:29 +01:00
serviceExecutor ,
2022-04-11 13:36:20 +02:00
async ( ) = > false ,
)
2021-12-07 15:30:53 +01:00
locator . login = login
2020-09-02 16:19:30 +02:00
locator . restClient = restClient
2021-11-23 16:09:12 +01:00
locator . rsa = rsa
2021-12-15 16:07:07 +01:00
locator . instanceMapper = instanceMapper
2017-11-23 13:30:17 +01:00
} )
2022-03-09 17:43:29 +01:00
o . beforeEach ( function ( ) {
serviceExecutor = object ( )
entityClient = object ( )
crypto = new CryptoFacadeImpl (
login ,
entityClient ,
restClient ,
rsa ,
serviceExecutor ,
)
} )
2017-08-15 13:54:22 +02:00
o . afterEach ( function ( ) {
2021-12-07 15:30:53 +01:00
login . resetSession ( )
2017-08-15 13:54:22 +02:00
} )
2022-01-13 13:24:37 +01:00
function createValueType ( type , encrypted , cardinality ) : ModelValue & { name : string , since : number } {
2017-08-15 13:54:22 +02:00
return {
2022-01-07 15:58:30 +01:00
name : "test" ,
id : 426 ,
since : 6 ,
type : type ,
cardinality : cardinality ,
final : true ,
encrypted : encrypted ,
2022-01-13 13:24:37 +01:00
}
2017-08-15 13:54:22 +02:00
}
o . spec ( "decrypt value" , function ( ) {
2020-11-04 15:52:09 +01:00
o ( "decrypt string / number value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let sk = aes128RandomKey ( )
let value = "this is a string value"
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
o (
decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ,
) . equals ( value )
2017-09-25 16:22:38 +02:00
value = "516546"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
o (
decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ,
) . equals ( value )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt string / number value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
let value = "this is a string value"
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
o (
decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ,
) . equals ( value )
2017-08-15 13:54:22 +02:00
value = "516546"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
o (
decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ,
) . equals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt boolean value without mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "0"
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-08-15 13:54:22 +02:00
value = "1"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
value = "32498"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt boolean value with mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "0"
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-09-25 16:22:38 +02:00
value = "1"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-09-25 16:22:38 +02:00
value = "32498"
2022-01-07 15:58:30 +01:00
encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt date value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( ) . getTime ( ) . toString ( )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
false ,
) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( new Date ( parseInt ( value ) ) )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt date value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( ) . getTime ( ) . toString ( )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( new Date ( parseInt ( value ) ) )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt bytes value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , value , random . generateRandomData ( IV_BYTE_LENGTH ) , true , false ) ,
)
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2017-09-25 16:22:38 +02:00
o ( decryptedValue instanceof Uint8Array ) . equals ( true )
o ( Array . from ( decryptedValue ) ) . deepEquals ( Array . from ( value ) )
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt bytes value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , value , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2017-08-15 13:54:22 +02:00
o ( decryptedValue instanceof Uint8Array ) . equals ( true )
o ( Array . from ( decryptedValue ) ) . deepEquals ( Array . from ( value ) )
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt compressedString" , function ( ) {
2019-08-21 15:12:04 +02:00
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
2019-09-03 15:09:55 +02:00
let value = base64ToUint8Array ( "QHRlc3Q=" )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , value , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-08-21 15:12:04 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
o ( decryptedValue ) . equals ( "test" )
} )
2019-09-03 15:09:55 +02:00
o ( "decrypt compressedString w resize" , function ( ) {
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = base64ToUint8Array ( "X3RleHQgBQD//1FQdGV4dCA=" )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , value , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-09-03 15:09:55 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
2022-01-07 15:58:30 +01:00
o ( decryptedValue ) . equals (
"text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text " ,
)
2019-09-03 15:09:55 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt empty compressedString" , function ( ) {
2019-08-21 15:12:04 +02:00
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
2022-01-07 15:58:30 +01:00
let encryptedValue = uint8ArrayToBase64 (
aes128Encrypt ( sk , new Uint8Array ( [ ] ) , random . generateRandomData ( IV_BYTE_LENGTH ) , true , true ) ,
)
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-08-21 15:12:04 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
o ( decryptedValue ) . equals ( "" )
} )
2020-11-04 15:52:09 +01:00
o ( "do not decrypt null values" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2022-01-07 15:58:30 +01:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Date , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
2022-01-07 15:58:30 +01:00
o ( decryptValue ( "test" , createValueType ( ValueType . Bytes , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
o ( decryptValue ( "test" , createValueType ( ValueType . Number , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
} )
o ( "throw error on ONE null values (String)" , makeTestForErrorOnNull ( ValueType . String ) )
o ( "throw error on ONE null values (Date)" , makeTestForErrorOnNull ( ValueType . Date ) )
o ( "throw error on ONE null values (Bytes)" , makeTestForErrorOnNull ( ValueType . Bytes ) )
o ( "throw error on ONE null values (Boolean)" , makeTestForErrorOnNull ( ValueType . Boolean ) )
o ( "throw error on ONE null values (Number)" , makeTestForErrorOnNull ( ValueType . Number ) )
function makeTestForErrorOnNull ( type ) {
return async ( ) = > {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2022-01-07 15:58:30 +01:00
const e = await assertThrows ( ProgrammingError , ( ) = > decryptValue ( "test" , createValueType ( type , true , Cardinality . One ) , null , sk ) )
o ( e . message ) . equals ( "Value test with cardinality ONE can not be null" )
2017-08-15 13:54:22 +02:00
}
}
o ( "convert unencrypted Date to JS type" , function ( ) {
let value = new Date ( ) . getTime ( ) . toString ( )
2022-01-07 15:58:30 +01:00
o ( decryptValue ( "test" , createValueType ( ValueType . Date , false , Cardinality . One ) , value , null ) ) . deepEquals (
new Date ( parseInt ( value ) ) ,
)
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Bytes to JS type" , function ( ) {
let valueBytes = random . generateRandomData ( 15 )
let value = uint8ArrayToBase64 ( valueBytes )
2022-01-07 15:58:30 +01:00
o (
Array . from ( decryptValue ( "test" , createValueType ( ValueType . Bytes , false , Cardinality . One ) , value , null ) ) ,
) . deepEquals ( Array . from ( valueBytes ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Boolean to JS type" , function ( ) {
let value = "0"
2022-01-07 15:58:30 +01:00
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals (
false ,
)
2017-08-15 13:54:22 +02:00
value = "1"
2022-01-07 15:58:30 +01:00
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals (
true ,
)
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Number to JS type" , function ( ) {
let value = ""
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "0"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "1"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
2019-08-21 15:12:04 +02:00
o ( "convert unencrypted compressedString to JS type" , function ( ) {
let value = ""
2022-01-07 15:58:30 +01:00
o (
decryptValue ( "test" , createValueType ( ValueType . CompressedString , false , Cardinality . One ) , value , null ) ,
) . equals ( "" )
2019-09-03 15:09:55 +02:00
value = "QHRlc3Q="
2022-01-07 15:58:30 +01:00
o (
decryptValue ( "test" , createValueType ( ValueType . CompressedString , false , Cardinality . One ) , value , null ) ,
) . equals ( "test" )
2019-08-21 15:12:04 +02:00
} )
2017-08-15 13:54:22 +02:00
} )
o . spec ( "encryptValue" , function ( ) {
2020-11-04 15:52:09 +01:00
o ( "encrypt string / number value" , function ( ) {
2017-08-15 13:54:22 +02:00
var valueType = createValueType ( ValueType . String , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "this is a string value"
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2022-01-07 15:58:30 +01:00
let expected = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ) ,
base64ToUint8Array ( encryptedValue ) . slice ( ENABLE_MAC ? 1 : 0 , ENABLE_MAC ? 17 : 16 ) ,
true ,
ENABLE_MAC ,
) ,
)
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt boolean value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = false
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2022-01-07 15:58:30 +01:00
let expected = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ? "1" : "0" ) ,
base64ToUint8Array ( encryptedValue ) . slice ( ENABLE_MAC ? 1 : 0 , ENABLE_MAC ? 17 : 16 ) ,
true ,
ENABLE_MAC ,
) ,
)
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-08-15 13:54:22 +02:00
value = true
2021-07-09 14:38:10 +02:00
encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2022-01-07 15:58:30 +01:00
expected = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value ? "1" : "0" ) ,
base64ToUint8Array ( encryptedValue ) . slice ( ENABLE_MAC ? 1 : 0 , ENABLE_MAC ? 17 : 16 ) ,
true ,
ENABLE_MAC ,
) ,
)
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt date value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( )
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2022-01-07 15:58:30 +01:00
let expected = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( value . getTime ( ) . toString ( ) ) ,
base64ToUint8Array ( encryptedValue ) . slice ( ENABLE_MAC ? 1 : 0 , ENABLE_MAC ? 17 : 16 ) ,
true ,
ENABLE_MAC ,
) ,
)
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt bytes value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2022-01-07 15:58:30 +01:00
let expected = uint8ArrayToBase64 (
aes128Encrypt (
sk ,
value ,
base64ToUint8Array ( encryptedValue ) . slice ( ENABLE_MAC ? 1 : 0 , ENABLE_MAC ? 17 : 16 ) ,
true ,
ENABLE_MAC ,
) ,
)
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( Array . from ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) ) . deepEquals ( Array . from ( value ) )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "do not encrypt null values" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2022-01-07 15:58:30 +01:00
o ( encryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Date , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
2022-01-07 15:58:30 +01:00
o ( encryptValue ( "test" , createValueType ( ValueType . Bytes , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
o ( encryptValue ( "test" , createValueType ( ValueType . Number , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals (
null ,
)
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "accept null _id and _permissions value during encryption" , function ( ) {
2017-08-15 13:54:22 +02:00
let vt = {
2022-01-07 15:58:30 +01:00
name : "_id" ,
id : 426 ,
since : 6 ,
type : ValueType . GeneratedId ,
cardinality : Cardinality.One ,
final : true ,
encrypted : false ,
2017-08-15 13:54:22 +02:00
}
2019-09-13 13:49:11 +02:00
o ( encryptValue ( vt . name , vt , null , null ) ) . equals ( null )
2022-01-07 15:58:30 +01:00
vt . name = "_permissions"
2019-09-13 13:49:11 +02:00
o ( encryptValue ( vt . name , vt , null , null ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
2022-01-07 15:58:30 +01:00
o ( "throw error on ONE null values (enc String)" , makeTestForErrorOnNull ( ValueType . String ) )
o ( "throw error on ONE null values (enc Date)" , makeTestForErrorOnNull ( ValueType . Date ) )
o ( "throw error on ONE null values (enc Bytes)" , makeTestForErrorOnNull ( ValueType . Bytes ) )
o ( "throw error on ONE null values (enc Boolean)" , makeTestForErrorOnNull ( ValueType . Boolean ) )
o ( "throw error on ONE null values (enc Number)" , makeTestForErrorOnNull ( ValueType . Number ) )
2017-08-15 13:54:22 +02:00
2022-01-07 15:58:30 +01:00
function makeTestForErrorOnNull ( type ) {
return async ( ) = > {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2022-01-07 15:58:30 +01:00
const e = await assertThrows ( ProgrammingError , async ( ) = > encryptValue ( "test" , createValueType ( type , true , Cardinality . One ) , null , sk ) )
o ( e . message ) . equals ( "Value test with cardinality ONE can not be null" )
2017-08-15 13:54:22 +02:00
}
}
o ( "convert unencrypted Date to DB type" , function ( ) {
let value = new Date ( )
2022-01-07 15:58:30 +01:00
o ( encryptValue ( "test" , createValueType ( ValueType . Date , false , Cardinality . One ) , value , null ) ) . equals (
value . getTime ( ) . toString ( ) ,
)
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Bytes to DB type" , function ( ) {
let valueBytes = random . generateRandomData ( 15 )
2022-01-07 15:58:30 +01:00
o (
encryptValue ( "test" , createValueType ( ValueType . Bytes , false , Cardinality . One ) , valueBytes , null ) ,
) . equals ( uint8ArrayToBase64 ( valueBytes ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Boolean to DB type" , function ( ) {
let value = false
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = true
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Number to DB type" , function ( ) {
let value = "0"
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "1"
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
} )
function createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName ) {
let mail = {
_format : "0" ,
_area : "0" ,
_owner : "ownerId" ,
_ownerGroup : "ownerGroupId" ,
_ownerEncSessionKey : encryptKey ( gk , sk ) ,
_id : "mailId" ,
_permissions : "permissionListId" ,
receivedDate : new Date ( 1470039025474 ) . getTime ( ) . toString ( ) ,
sentDate : new Date ( 1470039021474 ) . getTime ( ) . toString ( ) ,
state : "" ,
trashed : false ,
unread : true ,
2022-01-07 15:58:30 +01:00
subject : uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( subject ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
ENABLE_MAC ,
) ,
) ,
2017-08-15 13:54:22 +02:00
replyType : "" ,
2022-01-07 15:58:30 +01:00
confidential : uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( confidential ? "1" : "0" ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
ENABLE_MAC ,
) ,
) ,
2017-08-15 13:54:22 +02:00
sender : {
_id : "senderId" ,
address : "hello@tutao.de" ,
2022-01-07 15:58:30 +01:00
name : uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( senderName ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
ENABLE_MAC ,
) ,
) ,
2017-08-15 13:54:22 +02:00
} ,
bccRecipients : [ ] ,
ccRecipients : [ ] ,
2018-10-30 16:43:45 +01:00
toRecipients : [
{
_id : "recipientId" ,
address : "support@yahoo.com" ,
2022-01-07 15:58:30 +01:00
name : uint8ArrayToBase64 (
aes128Encrypt (
sk ,
stringToUtf8Uint8Array ( recipientName ) ,
random . generateRandomData ( IV_BYTE_LENGTH ) ,
true ,
ENABLE_MAC ,
) ,
) ,
} ,
2018-10-30 16:43:45 +01:00
] ,
2022-01-07 15:58:30 +01:00
replyTos : [ ] ,
2017-08-15 13:54:22 +02:00
}
2022-01-07 15:58:30 +01:00
return mail
2017-08-15 13:54:22 +02:00
}
2022-01-07 15:58:30 +01:00
o ( "decrypt instance" , function ( ) {
2019-09-13 13:49:11 +02:00
o . timeout ( 1000 )
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
2022-01-07 15:58:30 +01:00
return instanceMapper . decryptAndMapToInstance < Mail > ( MailTypeModel , mail , sk ) . then ( decrypted = > {
o ( isSameTypeRef ( decrypted . _type , MailTypeRef ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
o ( decrypted . receivedDate . getTime ( ) ) . equals ( 1470039025474 )
o ( decrypted . sentDate . getTime ( ) ) . equals ( 1470039021474 )
o ( decrypted . confidential ) . equals ( confidential )
o ( decrypted . subject ) . equals ( subject )
o ( decrypted . replyType ) . equals ( "0" )
// aggregates
2018-10-23 10:57:55 +02:00
o ( isSameTypeRef ( decrypted . sender . _type , MailAddressTypeRef ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
o ( decrypted . sender . name ) . equals ( senderName )
o ( decrypted . sender . address ) . equals ( "hello@tutao.de" )
o ( decrypted . toRecipients [ 0 ] . name ) . equals ( recipientName )
o ( decrypted . toRecipients [ 0 ] . address ) . equals ( "support@yahoo.com" )
} )
} )
2021-03-04 17:41:40 +01:00
o ( "encrypt instance" , async function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
let address = createContactAddress ( )
address . type = "0"
address . address = "Entenhausen"
address . customTypeName = "0"
let contact = Contact . createContact ( )
contact . _area = "0"
contact . _owner = "123"
contact . title = "Dr."
contact . firstName = "Max"
contact . lastName = "Meier"
contact . comment = "what?"
contact . company = "WIW"
contact . autoTransmitPassword = "stop bugging me!"
contact . addresses = [ address ]
2021-12-15 16:07:07 +01:00
const result : any = await instanceMapper . encryptAndMapToLiteral ( Contact . _TypeModel , contact , sk )
2021-03-04 17:41:40 +01:00
o ( result . _format ) . equals ( "0" )
o ( result . _ownerGroup ) . equals ( null )
o ( result . _ownerEncSessionKey ) . equals ( null )
2022-01-07 15:58:30 +01:00
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . type ) ) ) ) . equals (
contact . addresses [ 0 ] . type ,
)
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . address ) ) ) ) . equals (
contact . addresses [ 0 ] . address ,
)
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . customTypeName ) ) ) ) . equals (
contact . addresses [ 0 ] . customTypeName ,
)
2021-03-04 17:41:40 +01:00
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . title ) ) ) ) . equals ( contact . title )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . firstName ) ) ) ) . equals ( contact . firstName )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . lastName ) ) ) ) . equals ( contact . lastName )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . comment ) ) ) ) . equals ( contact . comment )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . company ) ) ) ) . equals ( contact . company )
2022-01-07 15:58:30 +01:00
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . autoTransmitPassword ) ) ) ) . equals (
contact . autoTransmitPassword ,
)
2017-08-15 13:54:22 +02:00
} )
2022-01-07 15:58:30 +01:00
o ( "map unencrypted to instance" , async function ( ) {
let userIdLiteral = {
_format : "0" ,
userId : "KOBqO7a----0" ,
}
const userIdReturn : UserIdReturn.UserIdReturn = await instanceMapper . decryptAndMapToInstance ( UserIdReturn . _TypeModel , userIdLiteral , null )
o ( userIdReturn . _format ) . equals ( "0" )
o ( userIdReturn . userId ) . equals ( "KOBqO7a----0" )
2017-08-15 13:54:22 +02:00
} )
2022-01-07 15:58:30 +01:00
o ( "map unencrypted to DB literal" , function ( ) {
2017-08-15 13:54:22 +02:00
let userIdReturn = createUserIdReturn ( )
userIdReturn . _format = "0"
userIdReturn . userId = "KOBqO7a----0"
2022-01-07 15:58:30 +01:00
let userIdLiteral = {
_format : "0" ,
userId : "KOBqO7a----0" ,
}
return instanceMapper . encryptAndMapToLiteral ( UserIdReturn . _TypeModel , userIdReturn , null ) . then ( result = > {
2017-08-15 13:54:22 +02:00
o ( result ) . deepEquals ( userIdLiteral )
} )
} )
2022-03-09 17:43:29 +01:00
o ( "resolve session key: unencrypted instance" , async function ( ) {
const userIdLiteral = {
2022-01-07 15:58:30 +01:00
_format : "0" ,
userId : "KOBqO7a----0" ,
}
2022-03-09 17:43:29 +01:00
o ( await crypto . resolveSessionKey ( UserIdReturn . _TypeModel , userIdLiteral ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
2022-01-07 15:58:30 +01:00
o ( "resolve session key: _ownerEncSessionKey instance" , async function ( ) {
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
2022-01-07 15:58:30 +01:00
const gk = aes128RandomKey ( )
const sk = aes128RandomKey ( )
login . groupKeys = {
ownerGroupId : gk ,
}
2021-12-07 15:30:53 +01:00
login . _user = createUser ( )
2022-03-09 17:43:29 +01:00
login . _user . userGroup = createGroupMembership ( {
2022-01-07 15:58:30 +01:00
group : "ownerGroupId" ,
2022-03-09 17:43:29 +01:00
} )
const mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
const sessionKey : Aes128Key = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
2022-01-07 15:58:30 +01:00
o ( sessionKey ) . deepEquals ( sk )
2017-08-15 13:54:22 +02:00
} )
2020-11-13 10:31:35 +01:00
o ( "resolve session key: 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
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let bk = aes128RandomKey ( )
let privateKey = hexToPrivateKey ( rsaPrivateHexKey )
let publicKey = hexToPublicKey ( rsaPublicHexKey )
2022-03-09 17:43:29 +01:00
const keyPair = createKeyPair ( {
_id : "keyPairId" ,
symEncPrivKey : encryptRsaKey ( gk , privateKey ) ,
pubKey : hexToUint8Array ( rsaPublicHexKey )
} )
const userGroup = createGroup ( {
_id : "userGroupId" ,
keys : [ keyPair ]
} )
const mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
2022-01-07 15:58:30 +01:00
// @ts-ignore
2017-08-15 13:54:22 +02:00
mail . _ownerEncSessionKey = null
2022-03-09 17:43:29 +01:00
const bucket = createBucket ( {
bucketPermissions : "bucketPermissionListId"
} )
const permission = createPermission ( {
_id : [ "permissionListId" , "permissionId" ] ,
_ownerGroup : userGroup._id ,
bucketEncSessionKey : encryptKey ( bk , sk ) ,
bucket ,
type : PermissionType . Public ,
} )
2020-11-13 10:31:35 +01:00
const pubEncBucketKey = await rsaEncrypt ( publicKey , bitArrayToUint8Array ( bk ) )
2022-03-09 17:43:29 +01:00
const bucketPermission = createBucketPermission ( {
_id : [ "bucketPermissionListId" , "bucketPermissionId" ] ,
_ownerGroup : userGroup._id ,
type : BucketPermissionType . Public ,
group : userGroup._id ,
pubEncBucketKey ,
} )
const mem = createGroupMembership ( {
group : userGroup._id ,
} )
2021-12-07 15:30:53 +01:00
login . _user = createUser ( )
login . _user . userGroup = mem
2022-01-07 15:58:30 +01:00
login . groupKeys [ "userGroupId" ] = gk
login . _leaderStatus = createWebsocketLeaderStatus ( {
leaderStatus : true ,
} )
2022-03-09 17:43:29 +01:00
when ( entityClient . loadAll ( BucketPermissionTypeRef , getListId ( bucketPermission ) ) ) . thenResolve ( [ bucketPermission ] )
when ( entityClient . loadAll ( PermissionTypeRef , getListId ( permission ) ) ) . thenResolve ( [ permission ] )
when ( entityClient . load ( GroupTypeRef , userGroup . _id ) ) . thenResolve ( userGroup )
when ( serviceExecutor . post ( UpdatePermissionKeyService , matchers . argThat ( ( p : UpdatePermissionKeyData ) = > {
console . log ( "KEY DATA" , p )
return isSameId ( p . permission , permission . _id ) &&
isSameId ( p . bucketPermission , bucketPermission . _id )
} ) ) ) . thenResolve ( undefined )
const sessionKey = neverNull ( await crypto . resolveSessionKey ( MailTypeModel , mail ) )
o ( sessionKey ) . deepEquals ( sk )
2017-08-15 13:54:22 +02:00
} )
2022-01-07 15:58:30 +01:00
o ( "decryption errors should be written to _errors field" , async function ( ) {
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let bk = aes128RandomKey ( )
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
2022-01-07 15:58:30 +01:00
mail . subject = "asdf"
const instance : Mail = await instanceMapper . decryptAndMapToInstance ( MailTypeModel , mail , sk )
o ( typeof instance . _errors [ "subject" ] ) . equals ( "string" )
2017-08-15 13:54:22 +02:00
} )
2020-04-29 15:55:56 +02:00
o . spec ( "instance migrations" , function ( ) {
o . beforeEach ( function ( ) {
2022-03-09 17:43:29 +01:00
when ( entityClient . update ( matchers . anything ( ) ) ) . thenResolve ( undefined )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration without birthday" , async function ( ) {
2020-04-29 15:55:56 +02:00
const contact = createContact ( )
2022-03-09 17:43:29 +01:00
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( null )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 0 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration without existing birthday" , async function ( ) {
const contact = createContact ( {
birthdayIso : "2019-05-01" ,
} )
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 0 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration without existing birthday and oldBirthdayDate" , async function ( ) {
const contact = createContact ( {
_id : [ "listid" , "id" ] ,
birthdayIso : "2019-05-01" ,
oldBirthdayDate : new Date ( 2000 , 4 , 1 )
} )
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 1 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration with existing birthday and oldBirthdayAggregate" , async function ( ) {
const contact = createContact ( {
_id : [ "listid" , "id" ] ,
birthdayIso : "2019-05-01" ,
oldBirthdayAggregate : createBirthday ( {
day : "01" ,
month : "05" ,
year : "2000" ,
2022-01-07 15:58:30 +01:00
} )
2022-03-09 17:43:29 +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 )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 1 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration from oldBirthdayAggregate" , async function ( ) {
const contact = createContact ( {
_id : [ "listid" , "id" ] ,
oldBirthdayDate : new Date ( 1800 , 4 , 1 ) ,
oldBirthdayAggregate : createBirthday ( {
day : "01" ,
month : "05" ,
year : "2000" ,
2022-01-07 15:58:30 +01:00
} )
2022-03-09 17:43:29 +01:00
} )
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "2000-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 1 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration from oldBirthdayDate" , async function ( ) {
const contact = createContact ( {
_id : [ "listid" , "id" ] ,
birthdayIso : null ,
oldBirthdayDate : new Date ( 1800 , 4 , 1 ) ,
oldBirthdayAggregate : null ,
} )
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "1800-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 1 } )
2020-04-29 15:55:56 +02:00
} )
2022-03-09 17:43:29 +01:00
o ( "contact migration from oldBirthdayAggregate without year" , async function ( ) {
const contact = createContact ( {
_id : [ "listid" , "id" ] ,
birthdayIso : null ,
oldBirthdayDate : null ,
oldBirthdayAggregate : createBirthday ( {
day : "01" ,
month : "05" ,
year : null
} ) ,
} )
const migratedContact = await crypto . applyMigrationsForInstance ( contact )
o ( migratedContact . birthdayIso ) . equals ( "--05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
verify ( entityClient . update ( matchers . anything ( ) ) , { times : 1 } )
2020-04-29 15:55:56 +02:00
} )
} )
2022-01-07 15:58:30 +01:00
} )