public async Task CreateAsync(ulong startTimestamp, ulong endTimestamp, string region, IEnumerable <TemporaryExposureKeyModel> keys) { var current = keys; while (current.Any()) { var exportKeyModels = current.Take(MaxKeysPerFile).ToImmutableArray(); var exportKeys = exportKeyModels.Select(_ => _.ToKey()); current = current.Skip(MaxKeysPerFile); var exportModel = await TekExportRepository.CreateAsync(); exportModel.BatchSize = exportKeyModels.Length; exportModel.StartTimestamp = startTimestamp; exportModel.EndTimestamp = endTimestamp; exportModel.Region = region; var signatureKey = await SignService.GetX509PublicKeyAsync(); var signatureInfo = SignatureService.Create(signatureKey); var bin = new TemporaryExposureKeyExport(); bin.Keys.AddRange(exportKeys); bin.BatchNum = exportModel.BatchNum; bin.BatchSize = exportModel.BatchSize; bin.Region = exportModel.Region; bin.StartTimestamp = exportModel.StartTimestamp; bin.EndTimestamp = exportModel.EndTimestamp; bin.SignatureInfos.Add(signatureInfo); var sig = new TEKSignatureList(); using var binStream = new MemoryStream(); bin.WriteTo(binStream); await binStream.FlushAsync(); binStream.Seek(0, SeekOrigin.Begin); var signature = await CreateSignatureAsync(binStream, bin.BatchNum, bin.BatchSize); signature.SignatureInfo = signatureInfo; sig.Signatures.Add(signature); using (var s = new MemoryStream()) { using (var z = new System.IO.Compression.ZipArchive(s, System.IO.Compression.ZipArchiveMode.Create, true)) { var binEntry = z.CreateEntry(ExportBinFileName); using (var binFile = binEntry.Open()) { binStream.Seek(0, SeekOrigin.Begin); await binStream.CopyToAsync(binFile); await binFile.FlushAsync(); } var sigEntry = z.CreateEntry(ExportSigFileName); using (var sigFile = sigEntry.Open()) { sig.WriteTo(sigFile); await sigFile.FlushAsync(); } } s.Seek(0, SeekOrigin.Begin); await WriteToBlobAsync(s, exportModel, bin, sig); } await TekExportRepository.UpdateAsync(exportModel); } }