private async Task <SelfDiagnosisSubmission> CreateSubmissionAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys, PositiveDiagnosisState pendingDiagnosis)
        {
            // Create the network keys
            var keys = temporaryExposureKeys.Select(k => new ExposureKey
            {
                KeyData          = Convert.ToBase64String(k.Key),
                RollingStart     = (long)(k.RollingStart - DateTime.UnixEpoch).TotalMinutes / 10,
                RollingDuration  = (int)(k.RollingDuration.TotalMinutes / 10),
                TransmissionRisk = (int)k.TransmissionRiskLevel
            });

            // Create the submission
            var submission = new SelfDiagnosisSubmission(true)
            {
                SubmissionNumber          = userData.PendingDiagnosis.DiagnosisUid,
                AppPackageName            = AppInfo.PackageName,
                UserUuid                  = userData.UserUuid,
                DeviceVerificationPayload = null,
                Platform                  = DeviceInfo.Platform.ToString().ToLowerInvariant(),
                Regions             = AppSettings.Instance.SupportedRegions,
                Keys                = keys.ToArray(),
                VerificationPayload = pendingDiagnosis.DiagnosisUid,
            };

            // See if we can add the device verification
            if (DependencyService.Get <IDeviceVerifier>() is IDeviceVerifier verifier)
            {
                submission.DeviceVerificationPayload = await verifier?.VerifyAsync(submission);
            }
            return(submission);
        }
        public void DetectKeyTimesDoNotOverlap()
        {
            var s = new SelfDiagnosisSubmission(true)
            {
                Keys = new List <ExposureKey>
                {
                    new ExposureKey
                    {
                        Key              = "",
                        RollingStart     = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero).ToUnixTimeSeconds(),
                        RollingDuration  = 144,
                        TransmissionRisk = 1
                    },
                    new ExposureKey
                    {
                        Key              = "",
                        RollingStart     = new DateTimeOffset(2020, 1, 2, 0, 0, 0, TimeSpan.Zero).ToUnixTimeSeconds(),
                        RollingDuration  = 144,
                        TransmissionRisk = 1
                    },
                }
            };

            Assert.True(s.Validate());
        }
        /*
         * public async Task UploadSelfExposureKeysToServerAsync(IEnumerable<TemporaryExposureKey> temporaryExposureKeys)
         * {
         *  var pendingDiagnosis = userData.PendingDiagnosis;
         *
         *  if (pendingDiagnosis == null || string.IsNullOrEmpty(pendingDiagnosis.DiagnosisUid))
         *      throw new InvalidOperationException();
         *
         *  try
         *  {
         *      var request = new DiagnosisSubmissionHttpRequestModel()
         *      {
         *          SubmissionNumber = userData.PendingDiagnosis.DiagnosisUid,
         *          AppPackageName = Xamarin.Essentials.AppInfo.PackageName, // experimental
         *          UserUuid = userData.UserUuid,
         *          Region = userData.Region ?? AppConstants.DefaultRegion,
         *          Platform = Device.RuntimePlatform.ToLower(),
         *          Keys = temporaryExposureKeys.Select(_ => DiagnosisSubmissionHttpRequestModel.Key.FromTemporaryExposureKey(_)).ToArray(),
         *          DeviceVerificationPayload = "" // TODO: device payload
         *      };
         *
         *      // TODO check implementation
         *      await httpDataService.PostSelfExposureKeysAsync(request);
         *
         *      // Update pending status
         *      userData.PendingDiagnosis.Shared = true;
         *      await userDataService.SetAsync(userData);
         *  }
         *  catch
         *  {
         *      throw;
         *  }
         * }
         */
        // this will be called when the user is submitting a diagnosis and the local keys need to go to the server
        public async Task UploadSelfExposureKeysToServerAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys)
        {
            var pendingDiagnosis = userData.PendingDiagnosis;

            if (pendingDiagnosis == null || string.IsNullOrEmpty(pendingDiagnosis.DiagnosisUid))
            {
                throw new InvalidOperationException();
            }

            var selfDiag = await CreateSubmissionAsync();

            var url = $"{apiUrlBase.TrimEnd('/')}/selfdiagnosis";

            var json = JsonConvert.SerializeObject(selfDiag);

            using var http = new HttpClient();
            var response = await http.PutAsync(url, new StringContent(json));

            response.EnsureSuccessStatusCode();

            // Update pending status
            pendingDiagnosis.Shared = true;
            await userDataService.SetAsync(userData);


            async Task <SelfDiagnosisSubmission> CreateSubmissionAsync()
            {
                // Create the network keys
                var keys = temporaryExposureKeys.Select(k => new ExposureKey
                {
                    Key              = Convert.ToBase64String(k.Key),
                    RollingStart     = (long)(k.RollingStart - DateTime.UnixEpoch).TotalMinutes / 10,
                    RollingDuration  = (int)(k.RollingDuration.TotalMinutes / 10),
                    TransmissionRisk = (int)k.TransmissionRiskLevel
                });

                // Create the submission
                var submission = new SelfDiagnosisSubmission(true)
                {
                    AppPackageName            = AppInfo.PackageName,
                    DeviceVerificationPayload = null,
                    Platform            = DeviceInfo.Platform.ToString().ToLowerInvariant(),
                    Regions             = userData.ServerBatchNumbers.Keys.ToArray(),
                    Keys                = keys.ToArray(),
                    VerificationPayload = pendingDiagnosis.DiagnosisUid,
                };

                // See if we can add the device verification
                if (DependencyService.Get <IDeviceVerifier>() is IDeviceVerifier verifier)
                {
                    submission.DeviceVerificationPayload = await verifier?.VerifyAsync(submission);
                }

                return(submission);
            }
        }
Exemple #4
0
        // Put /diagnosis - upload self diagnosys file
        public async Task PutSelfExposureKeysAsync(SelfDiagnosisSubmission request)
        {
            System.Console.WriteLine(Utils.SerializeToJson(request));
            var url     = $"{AppSettings.Instance.ApiUrlBase.TrimEnd('/')}/diagnosis";
            var content = new StringContent(Utils.SerializeToJson(request), Encoding.UTF8, "application/json");
            var result  = await PutAsync(url, content);

            if (result != null)
            {
                System.Console.WriteLine(Utils.SerializeToJson(result));
            }
        }
        public void DetectKeysUnder14Days()
        {
            var s = new SelfDiagnosisSubmission(true);

            for (var i = 1; i <= 14; i++)
            {
                s.Keys.Add(new ExposureKey
                {
                    Key              = "",
                    RollingStart     = new DateTimeOffset(2020, 1, i, 0, 0, 0, TimeSpan.Zero).ToUnixTimeSeconds(),
                    RollingDuration  = 144,
                    TransmissionRisk = 1
                });;
            }

            Assert.True(s.Validate());
        }
        public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "dev/dummy-keys")] HttpRequest req, ILogger logger)
        {
            logger.LogInformation("Adding dummy keys...");

            var diagnosisUid = random.Next(100001, 128000).ToString();

            await storage.AddDiagnosisUidsAsync(new[] { diagnosisUid });

            var submission = new SelfDiagnosisSubmission(true)
            {
                VerificationPayload = diagnosisUid,
                Regions             = PickRandom(new[] { "ca" }, new[] { "za" }, new[] { "ca", "za" }),
                AppPackageName      = "com.xamarin.exposurenotification.sampleapp",
                Platform            = PickRandom("android", "ios"),
                Keys = GetKeys()
            };

            await storage.SubmitPositiveDiagnosisAsync(submission);
        }
Exemple #7
0
        public async Task SubmitPositiveDiagnosisAsync(SelfDiagnosisSubmission diagnosis)
        {
            using var transaction = context.Database.BeginTransaction();

            // Ensure the database contains the diagnosis uid
            var dbDiag = await context.Diagnoses.FirstOrDefaultAsync(d => d.DiagnosisUid == diagnosis.VerificationPayload);

            // Check that the diagnosis uid exists and that there aren't too many keys associated
            // already, otherwise it might be someone submitting fake data with a legitimate key
            if (dbDiag == null || dbDiag.KeyCount > maxKeysPerDiagnosisUid)
            {
                throw new InvalidOperationException();
            }

            // Duplicate the key for each region so it gets included in the batch files for that region
            foreach (var supporedRegion in diagnosis.Regions)
            {
                var region = supporedRegion.ToUpperInvariant();

                var dbKeys = diagnosis.Keys.Select(k => DbTemporaryExposureKey.FromKey(k, region)).ToList();

                // Add the new keys to the db
                foreach (var dbk in dbKeys)
                {
                    // Only add key if it doesn't exist already
                    if (!await context.TemporaryExposureKeys.AnyAsync(k => k.Base64KeyData == dbk.Base64KeyData && k.Region == region))
                    {
                        context.TemporaryExposureKeys.Add(dbk);
                    }
                }
            }

            // Increment key count
            dbDiag.KeyCount += diagnosis.Keys.Count();

            await context.SaveChangesAsync();

            await transaction.CommitAsync();
        }
        public async Task <string> VerifyAsync(SelfDiagnosisSubmission submission)
        {
            var token = await DeviceCheck.DCDevice.CurrentDevice.GenerateTokenAsync();

            return(Convert.ToBase64String(token.ToArray()));
        }
        public Task <string> VerifyAsync(SelfDiagnosisSubmission submission)
        {
            var nonce = submission.GetAndroidNonce();

            return(GetSafetyNetAttestationAsync(nonce));
        }
 public static Task <bool> VerifyDevice(SelfDiagnosisSubmission submission, DateTimeOffset requestTime, AuthorizedAppConfig.DevicePlatform platform, AuthorizedAppConfig auth) =>
 platform switch
 {