public async Task <Stream> CreateSignedFileAsync(TemporaryExposureKeyExport export) { export.SignatureInfos.AddRange(Signatures); var ms = new MemoryStream(); using (var zipFile = new ZipArchive(ms, ZipArchiveMode.Create, true)) using (var bin = await CreateBinAsync(export)) using (var sig = CreateSig(export, bin.ToArray())) { // Copy the bin contents into the entry var binEntry = zipFile.CreateEntry(BinEntryName, CompressionLevel.Optimal); using (var binStream = binEntry.Open()) { await bin.CopyToAsync(binStream); } // Copy the sig contents into the entry var sigEntry = zipFile.CreateEntry(SigEntryName, CompressionLevel.NoCompression); using (var sigStream = sigEntry.Open()) { await sig.CopyToAsync(sigStream); } } // Rewind to the front for the consumer ms.Seek(0, SeekOrigin.Begin); return(ms); }
private void SetupTemporaryExposureKeyExport() { var data = new List <TemporaryExposureKey> { new TemporaryExposureKey { CreatedOn = DateTime.UtcNow.Date, Id = Guid.NewGuid(), KeyData = Encoding.ASCII.GetBytes("keyData1"), TransmissionRiskLevel = RiskLevel.RISK_LEVEL_LOW, ReportType = ReportType.CONFIRMED_TEST, DaysSinceOnsetOfSymptoms = 1 }, new TemporaryExposureKey { CreatedOn = DateTime.UtcNow.Date.AddDays(-12), Id = Guid.NewGuid(), KeyData = Encoding.ASCII.GetBytes("keyData2"), TransmissionRiskLevel = RiskLevel.RISK_LEVEL_HIGH, ReportType = ReportType.CONFIRMED_TEST, DaysSinceOnsetOfSymptoms = 2 } }; ExposureKeyMapper mapper = new ExposureKeyMapper(_epochConverter); _exportBatch = mapper.FromEntityToProtoBatch(data); }
public async Task CreateAsync(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 = exportKeyModels.Min(_ => _.Timestamp); exportModel.EndTimestamp = exportKeyModels.Max(_ => _.Timestamp); exportModel.Region = Region; 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(SigInfo); var sig = new TEKSignatureList(); using var binStream = new MemoryStream(); bin.WriteTo(binStream); await binStream.FlushAsync(); binStream.Seek(0, SeekOrigin.Begin); var signature = CreateSignature(binStream, bin.BatchNum, bin.BatchSize); sig.Signatures.Add(signature); binStream.Seek(0, SeekOrigin.Begin); 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()) { 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); } }
public byte[] GetBytes(ExposureKeySetContentArgs content) { if (content == null) { throw new ArgumentNullException(nameof(content)); } var result = new TemporaryExposureKeyExport { Region = content.Region, BatchNum = content.BatchNum, BatchSize = content.BatchSize, EndTimestamp = content.EndTimestamp, StartTimestamp = content.StartTimestamp, SignatureInfos = { content.SignatureInfos.Select(Map).ToArray() }, Keys = { content.Keys.Select(Map).ToArray() }, }; var buffer = result.ToByteArray(); var headerBytes = Encoding.UTF8.GetBytes(content.Header); var stream = new MemoryStream(); stream.Write(headerBytes); stream.Write(buffer); return(stream.ToArray()); }
public void EqualsMethodWithClear() { // preparation var instance = new TemporaryExposureKeyExport(); instance.BatchNum = 99; instance.BatchSize = 99; instance.EndTimestamp = ulong.MaxValue; instance.Keys.Add(new TemporaryExposureKey()); instance.Region = "Region"; instance.SignatureInfos.Add(new SignatureInfo()); instance.StartTimestamp = ulong.MaxValue; var actual = instance.Clone(); // action assert actual.ClearBatchNum(); Assert.AreNotEqual(instance, actual); actual = instance.Clone(); actual.ClearBatchSize(); Assert.AreNotEqual(instance, actual); actual = instance.Clone(); actual.ClearEndTimestamp(); Assert.AreNotEqual(instance, actual); actual = instance.Clone(); actual.ClearRegion(); Assert.AreNotEqual(instance, actual); actual = instance.Clone(); actual.ClearStartTimestamp(); Assert.AreNotEqual(instance, actual); }
public MemoryStream CreateSig(TemporaryExposureKeyExport export, byte[] exportBytes) { var stream = new MemoryStream(); // Create signature list object var tk = new TEKSignatureList(); foreach (var sigInfo in Signatures) { // Generate the signature from the bin file contents var sig = SignData(exportBytes, sigInfo.PrivateKey); tk.Signatures.Add(new TEKSignature { BatchNum = export.BatchNum, BatchSize = export.BatchSize, SignatureInfo = sigInfo, Signature = ByteString.CopyFrom(sig), }); } // Write signature proto tk.WriteTo(stream); // Rewind to the front for the consumer stream.Position = 0; return(stream); }
public IEnumerator<TemporaryExposureKeyExportModel> Create( ulong startTimestamp, ulong endTimestamp, IEnumerable<TemporaryExposureKey> keys) { var current = keys; var num = 1; while (current.Any()) { var exportKeys = current.Take(MaxKeysPerFile); current = current.Skip(MaxKeysPerFile); var bin = new TemporaryExposureKeyExport(); bin.Keys.AddRange(keys); bin.BatchNum = num++; bin.BatchSize = bin.Keys.Count; bin.Region = Region; bin.StartTimestamp = startTimestamp; bin.EndTimestamp = endTimestamp; var signature = CreateSignature(bin.BatchNum, bin.BatchSize); bin.SignatureInfos.Add(signature.SignatureInfo); var sig = new Covid19Radar.Protobuf.TEKSignatureList(); sig.Signatures.Add(signature); var model = new TemporaryExposureKeyExportModel(); model.Url = WriteToBlob(bin, sig); model.startTimestamp = startTimestamp; model.endTimestamp = endTimestamp; yield return model; } }
public void EqualsMethodWithSameReference() { // preparation var instance = new TemporaryExposureKeyExport(); // action assert Assert.IsTrue(instance.Equals(instance)); }
public void CreateMethod() { // preparation var instance = new TemporaryExposureKeyExport(); // assert Assert.IsNotNull(instance); }
public void PropertiesTest() { // preparation var model = new TemporaryExposureKeyExport(); // model property access Helper.ModelTestHelper.PropetiesTest(model); }
public void EqualsMethodWithNull() { // preparation var instance = new TemporaryExposureKeyExport(); // action assert Assert.IsFalse(instance.Equals(null)); }
public void CalculateSizeMethod() { // preparation var instance = new TemporaryExposureKeyExport(); // action var actual = instance.CalculateSize(); // assert Assert.AreEqual(0, actual); }
public void EqualsMethod() { // preparation var instance = new TemporaryExposureKeyExport(); // action var actual1 = instance.Clone(); var actual2 = new TemporaryExposureKeyExport(instance); // assert Assert.AreEqual(instance, actual1); Assert.AreEqual(instance, actual2); Assert.AreEqual(instance.GetHashCode(), actual1.GetHashCode()); Assert.AreEqual(instance.GetHashCode(), actual2.GetHashCode()); }
public static async Task <MemoryStream> CreateBinAsync(TemporaryExposureKeyExport export) { var stream = new MemoryStream(); // Write header await stream.WriteAsync(TemporaryExposureKeyExport.Header); // Write export proto export.WriteTo(stream); // Rewind to the front for the consumer stream.Position = 0; return(stream); }
public byte[] GetBytes(ExposureKeySetContentArgs content) { var result = new TemporaryExposureKeyExport { Region = content.Region, BatchNum = content.BatchNum, BatchSize = content.BatchSize, EndTimestamp = content.EndTimestamp, StartTimestamp = content.StartTimestamp, //Header = content.Header, SignatureInfos = { content.SignatureInfos.Select(Map).ToArray() }, Keys = { content.Keys.Select(Map).ToArray() }, }; return(result.ToByteArray()); }
public void EqualsMethodWithSetValue() { // preparation var instance = new TemporaryExposureKeyExport(); instance.BatchNum = 99; instance.BatchSize = 99; instance.EndTimestamp = ulong.MaxValue; instance.Keys.Add(new TemporaryExposureKey()); instance.Region = "Region"; instance.SignatureInfos.Add(new SignatureInfo()); instance.StartTimestamp = ulong.MaxValue; // action var actual1 = instance.Clone(); var actual2 = new TemporaryExposureKeyExport(instance); var actual3 = new TemporaryExposureKeyExport(); var actual4 = new TemporaryExposureKeyExport(); using var memory = new MemoryStream(); using var codedOut = new CodedOutputStream(memory, true); instance.WriteTo(codedOut); codedOut.Flush(); memory.Position = 0; using var codedIn = new CodedInputStream(memory, true); actual3.MergeFrom(codedIn); actual4.MergeFrom(actual3); // assert Assert.AreEqual(instance, actual1); Assert.AreEqual(instance, actual2); Assert.AreEqual(instance, actual3); Assert.AreEqual(instance, actual4); Assert.AreEqual(instance.GetHashCode(), actual1.GetHashCode()); Assert.AreEqual(instance.GetHashCode(), actual2.GetHashCode()); Assert.AreEqual(instance.GetHashCode(), actual3.GetHashCode()); Assert.AreEqual(instance.GetHashCode(), actual4.GetHashCode()); Assert.AreEqual(instance.CalculateSize(), actual1.CalculateSize()); Assert.AreEqual(instance.CalculateSize(), actual2.CalculateSize()); Assert.AreEqual(instance.CalculateSize(), actual3.CalculateSize()); Assert.AreEqual(instance.CalculateSize(), actual4.CalculateSize()); Assert.AreEqual(instance.ToString(), actual1.ToString()); Assert.AreEqual(instance.ToString(), actual2.ToString()); Assert.AreEqual(instance.ToString(), actual3.ToString()); Assert.AreEqual(instance.ToString(), actual4.ToString()); }
private void SetupTemporaryExposureKeyExport() { var data = new List <TemporaryExposureKey> { new TemporaryExposureKey() { CreatedOn = DateTime.UtcNow.Date, Id = Guid.NewGuid(), KeyData = Encoding.ASCII.GetBytes("keyData1"), TransmissionRiskLevel = RiskLevel.RISK_LEVEL_LOW, }, new TemporaryExposureKey() { CreatedOn = DateTime.UtcNow.Date.AddDays(-12), Id = Guid.NewGuid(), KeyData = Encoding.ASCII.GetBytes("keyData2"), TransmissionRiskLevel = RiskLevel.RISK_LEVEL_HIGH, } }; ExposureKeyMapper mapper = new ExposureKeyMapper(); _exportBatch = mapper.FromEntityToProtoBatch(data); }
public byte[] GetBytes(ExposureKeySetContentArgs content) { var result = new TemporaryExposureKeyExport { Region = content.Region, BatchNum = content.BatchNum, BatchSize = content.BatchSize, EndTimestamp = content.EndTimestamp, StartTimestamp = content.StartTimestamp, SignatureInfos = { content.SignatureInfos.Select(Map).ToArray() }, Keys = { content.Keys.Select(Map).ToArray() }, //NOT IN THE GENERATED PROTOBUF Header = content.Header, }; var buffer = result.ToByteArray(); var headerBytes = Encoding.UTF8.GetBytes(content.Header); var stream = new MemoryStream(); stream.Write(headerBytes); stream.Write(buffer); return(stream.ToArray()); }
public static TemporaryExposureKeyExport GenerateTemporaryExposureKeyExport(int daysBack) { var rnd = new Random(); var keys = GenerateTemporaryExposureKeys(daysBack); var keysByTime = keys.OrderBy(k => k.RollingStartIntervalNumber); var start = DateTimeOffset.FromUnixTimeSeconds(keysByTime.First().RollingStartIntervalNumber); var end = DateTimeOffset.FromUnixTimeSeconds(keysByTime.Last().RollingStartIntervalNumber); var export = new TemporaryExposureKeyExport { BatchNum = 1, BatchSize = 1, StartTimestamp = (ulong)keysByTime.First().RollingStartIntervalNumber, EndTimestamp = (ulong)keysByTime.Last().RollingStartIntervalNumber, Region = "default", Keys = { keys } }; return(export); }
public static async Task <Stream> CreateSignedFileAsync(TemporaryExposureKeyExport export, IEnumerable <SignerInfoConfig> signerInfos) { export.SignatureInfos.AddRange(signerInfos.Select(sigInfo => new SignatureInfo { AndroidPackage = sigInfo.AndroidPackage, AppBundleId = sigInfo.AppBundleId, SignatureAlgorithm = SignatureAlgorithm, VerificationKeyId = sigInfo.VerificationKeyId, VerificationKeyVersion = sigInfo.VerificationKeyVersion, })); var ms = new MemoryStream(); using (var zipFile = new ZipArchive(ms, ZipArchiveMode.Create, true)) using (var bin = await CreateBinAsync(export)) using (var sig = await CreateSigAsync(export, bin.ToArray(), signerInfos)) { // Copy the bin contents into the entry var binEntry = zipFile.CreateEntry(BinEntryName, CompressionLevel.Optimal); using (var binStream = binEntry.Open()) { await bin.CopyToAsync(binStream); } // Copy the sig contents into the entry var sigEntry = zipFile.CreateEntry(SigEntryName, CompressionLevel.NoCompression); using (var sigStream = sigEntry.Open()) { await sig.CopyToAsync(sigStream); } } // Rewind to the front for the consumer ms.Position = 0; return(ms); }
public static async Task <MemoryStream> CreateSigAsync(TemporaryExposureKeyExport export, byte[] exportBytes, IEnumerable <SignerInfoConfig> signerInfos) { var stream = new MemoryStream(); // Create signature list object var tk = new TEKSignatureList(); foreach (var sigInfo in signerInfos) { // Generate the signature from the bin file contents var sig = await GenerateSignatureAsync(exportBytes, sigInfo); tk.Signatures.Add(new TEKSignature { BatchNum = export.BatchNum, BatchSize = export.BatchSize, SignatureInfo = new SignatureInfo { AndroidPackage = sigInfo.AndroidPackage, AppBundleId = sigInfo.AppBundleId, SignatureAlgorithm = SignatureAlgorithm, VerificationKeyId = sigInfo.VerificationKeyId, VerificationKeyVersion = sigInfo.VerificationKeyVersion, }, Signature = ByteString.CopyFrom(sig), }); } // Write signature proto tk.WriteTo(stream); // Rewind to the front for the consumer stream.Position = 0; return(stream); }
public string WriteToBlob(TemporaryExposureKeyExport bin, TEKSignatureList sig) { // TODO: write to blob storage return "URL"; }
public async Task CreateAsync(ulong startTimestamp, ulong endTimestamp, string region, IEnumerable <TemporaryExposureKeyModel> keys) { Logger.LogInformation($"start {nameof(CreateAsync)}"); var current = keys; while (current.Any()) { var exportKeyModels = current.Take(MaxKeysPerFile).ToArray(); var exportKeys = exportKeyModels.Select(_ => _.ToKey()).ToArray(); current = current.Skip(MaxKeysPerFile); var signatureInfo = SignatureService.Create(); await SignService.SetSignatureAsync(signatureInfo); var exportModel = await TekExportRepository.CreateAsync(); exportModel.BatchSize = exportKeyModels.Length; exportModel.StartTimestamp = startTimestamp; exportModel.EndTimestamp = endTimestamp; exportModel.Region = region; exportModel.SignatureInfos = new SignatureInfo[] { signatureInfo }; 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 BlobService.WriteToBlobAsync(s, exportModel, bin, sig); } await TekExportRepository.UpdateAsync(exportModel); } }
public async Task WriteToBlobAsync(Stream s, TemporaryExposureKeyExportModel model, TemporaryExposureKeyExport bin, TEKSignatureList sig) { // write to blob storage var cloudBlobContainer = BlobClient.GetContainerReference(BlobContainerName); await cloudBlobContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, new BlobRequestOptions(), new OperationContext()); // Filename is inferable as batch number var exportFileName = $"{model.BatchNum}.tekexport"; var blockBlob = cloudBlobContainer.GetBlockBlobReference(exportFileName); // Set the batch number and region as metadata blockBlob.Metadata[batchNumberMetadataKey] = model.BatchNum.ToString(); blockBlob.Metadata[batchRegionMetadataKey] = model.Region; await blockBlob.UploadFromStreamAsync(s); await blockBlob.SetMetadataAsync(); }
public async Task WriteToBlobAsync(Stream s, TemporaryExposureKeyExportModel model, TemporaryExposureKeyExport bin, TEKSignatureList sig) { Logger.LogInformation($"start {nameof(WriteToBlobAsync)}"); // write to blob storage var blobContainerName = $"{TekExportBlobStorageContainerPrefix}{model.Region}".ToLower(); var cloudBlobContainer = BlobClient.GetContainerReference(blobContainerName); await cloudBlobContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, new BlobRequestOptions(), new OperationContext()); // Filename is inferable as batch number var exportFileName = $"{model.BatchNum}{fileNameSuffix}"; var blockBlob = cloudBlobContainer.GetBlockBlobReference(exportFileName); // Set the batch number and region as metadata blockBlob.Metadata[batchNumberMetadataKey] = model.BatchNum.ToString(); blockBlob.Metadata[batchRegionMetadataKey] = model.Region; await blockBlob.UploadFromStreamAsync(s); Logger.LogInformation($" {nameof(WriteToBlobAsync)} upload {exportFileName}"); await blockBlob.SetMetadataAsync(); Logger.LogInformation($" {nameof(WriteToBlobAsync)} set metadata {exportFileName}"); }
public async Task CreateAsync(ulong startTimestamp, ulong endTimestamp, string region, int batchNum, long batchTimestamp, IEnumerable <TemporaryExposureKeyModel> keys) { Logger.LogInformation($"start {nameof(CreateAsync)}"); var current = keys; while (current.Any()) { var exportKeyModels = current.Take(MaxKeysPerFile).ToArray(); var exportKeys = exportKeyModels.Select(_ => _.ToKey()).ToArray(); current = current.Skip(MaxKeysPerFile); var signatureInfo = SignatureService.Create(); await SignService.SetSignatureAsync(signatureInfo); var exportModel = new TemporaryExposureKeyExportModel(); exportModel.id = batchNum.ToString(); exportModel.PartitionKey = region; // TODO: not support apple //exportModel.BatchNum = batchNum; exportModel.BatchNum = 1; exportModel.Region = region; // TODO: not support apple //exportModel.BatchSize = exportKeyModels.Length; exportModel.BatchSize = 1; exportModel.StartTimestamp = startTimestamp; exportModel.EndTimestamp = endTimestamp; exportModel.TimestampSecondsSinceEpoch = batchTimestamp; exportModel = await TekExportRepository.CreateAsync(exportModel); 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(); await binStream.WriteAsync(FixedHeader, 0, FixedHeaderWidth); using var binStreamCoded = new CodedOutputStream(binStream, true); bin.WriteTo(binStreamCoded); binStreamCoded.Flush(); await binStream.FlushAsync(); 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()) using (var output = new CodedOutputStream(sigFile)) { sig.WriteTo(output); output.Flush(); await sigFile.FlushAsync(); } } s.Seek(0, SeekOrigin.Begin); await BlobService.WriteToBlobAsync(s, exportModel, bin, sig); } await TekExportRepository.UpdateAsync(exportModel); } }
public void CreateMethod() { // preparation var instance = new TemporaryExposureKeyExport(); }