Esempio n. 1
0
        public static byte[] GetAndroidNonce(this DiagnosisSubmissionParameter submission)
        {
            var cleartext = GetAndroidNonceClearText(submission);
            var nonce     = GetSha256(cleartext);

            return(nonce);
        }
Esempio n. 2
0
        public static byte[] CreateAndroidNonceV3(DiagnosisSubmissionParameter submission)
        {
            var cleartext = GetNonceClearTextV3(submission);
            var nonce     = GetSha256(cleartext);

            return(nonce);
        }
Esempio n. 3
0
        private async Task <DiagnosisSubmissionParameter> CreateSubmissionAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys, PositiveDiagnosisState pendingDiagnosis)
        {
            loggerService.StartMethod();

            // Filter Temporary exposure keys
            var filteredTemporaryExposureKeys = ExposureNotificationService.FliterTemporaryExposureKeys(temporaryExposureKeys);

            // Create the network keys
            var keys = filteredTemporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key
            {
                KeyData            = Convert.ToBase64String(k.Key),
                RollingStartNumber = (uint)(k.RollingStart - DateTime.UnixEpoch).TotalMinutes / 10,
                RollingPeriod      = (uint)(k.RollingDuration.TotalMinutes / 10),
                TransmissionRisk   = (int)k.TransmissionRiskLevel
            });

            var beforeKey = Utils.SerializeToJson(temporaryExposureKeys.ToList());
            var afterKey  = Utils.SerializeToJson(keys.ToList());

            Debug.WriteLine($"C19R {beforeKey}");
            Debug.WriteLine($"C19R {afterKey}");

            if (keys.Count() == 0)
            {
                loggerService.Error($"Temporary exposure keys is empty.");
                loggerService.EndMethod();
                throw new InvalidDataException();
            }

            // Generate Padding
            var padding = GetPadding();

            loggerService.Info($"userData is {(userData == null ? "" : "not ")}null or empty.");

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

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

            loggerService.Info($"UserUuid is {(string.IsNullOrEmpty(submission.UserUuid) ? "null or empty" : "set")}.");
            loggerService.Info($"DeviceVerificationPayload is {(string.IsNullOrEmpty(submission.DeviceVerificationPayload) ? "null or empty" : "set")}.");
            loggerService.Info($"VerificationPayload is {(string.IsNullOrEmpty(submission.VerificationPayload) ? "null or empty" : "set")}.");

            loggerService.EndMethod();
            return(submission);
        }
Esempio n. 4
0
        public async Task <HttpStatusCode> PutSelfExposureKeysAsync(DiagnosisSubmissionParameter request)
        {
            loggerService.StartMethod();

            try
            {
                await serverConfigurationRepository.LoadAsync();

                var diagnosisKeyRegisterApiUrls = serverConfigurationRepository.DiagnosisKeyRegisterApiUrls;
                if (diagnosisKeyRegisterApiUrls.Count() == 0)
                {
                    loggerService.Error("DiagnosisKeyRegisterApiUrls count 0");
                    throw new InvalidOperationException("DiagnosisKeyRegisterApiUrls count 0");
                }
                else if (diagnosisKeyRegisterApiUrls.Count() > 1)
                {
                    loggerService.Warning("Multi DiagnosisKeyRegisterApiUrl are detected.");
                }

                var url     = diagnosisKeyRegisterApiUrls.First();
                var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");

                return(await PutAsync(url, content));
            }
            finally
            {
                loggerService.EndMethod();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Validation Android
        /// </summary>
        /// <param name="param">subumission parameter</param>
        /// <returns>True when successful.</returns>
        public async Task <bool> ValidationAndroid(DiagnosisSubmissionParameter param)
        {
            try
            {
                var token = new JwtSecurityToken(param.DeviceVerificationPayload);

                // TODO: Token Validate

                // request
                var payload = new AndroidPayload()
                {
                    SignedAttestation = param.DeviceVerificationPayload
                };
                var content = new StringContent(JsonConvert.SerializeObject(payload));
                content.Headers.ContentType.MediaType = "application/json";
                var request = new HttpRequestMessage(HttpMethod.Post, UrlAndroid + AndroidBearerToken);

                // response
                var response = await ClientAndroid.SendAsync(request);

                var responseBody = await response.Content.ReadAsStringAsync();

                var result = JsonConvert.DeserializeObject <AndroidResponse>(responseBody);
                return(result.IsValidSignature);
            }
            catch (Exception) { }
            return(false);
        }
        public async Task RunAsyncMethod(bool isValid, bool isValidDevice, string submissionNumber, string userUuid)
        {
            // preparation
            var config = new Mock <IConfiguration>();

            config.Setup(_ => _["SupportRegions"]).Returns("Region1,Region2");
            var diagnosisRepo = new Mock <IDiagnosisRepository>();

            diagnosisRepo.Setup(_ => _.SubmitDiagnosisAsync(It.IsAny <string>(),
                                                            It.IsAny <DateTimeOffset>(),
                                                            It.IsAny <string>(),
                                                            It.IsAny <TemporaryExposureKeyModel[]>()))
            .Returns(Task.CompletedTask);
            var tekRepo          = new Mock <ITemporaryExposureKeyRepository>();
            var validation       = new Mock <IValidationUserService>();
            var validationResult = new IValidationUserService.ValidateResult()
            {
                IsValid = isValid
            };

            validation.Setup(_ => _.ValidateAsync(It.IsAny <HttpRequest>(), It.IsAny <IUser>())).ReturnsAsync(validationResult);
            var deviceCheck = new Mock <IDeviceValidationService>();

            deviceCheck.Setup(_ => _.Validation(It.IsAny <DiagnosisSubmissionParameter>())).ReturnsAsync(isValidDevice);
            var logger       = new Mock.LoggerMock <Covid19Radar.Api.DiagnosisApi>();
            var diagnosisApi = new DiagnosisApi(config.Object,
                                                diagnosisRepo.Object,
                                                tekRepo.Object,
                                                validation.Object,
                                                deviceCheck.Object,
                                                logger);
            var context  = new Mock <HttpContext>();
            var bodyJson = new DiagnosisSubmissionParameter()
            {
                SubmissionNumber = submissionNumber,
                UserUuid         = userUuid,
                Keys             = new DiagnosisSubmissionParameter.Key[] {
                    new DiagnosisSubmissionParameter.Key()
                    {
                        KeyData = "", RollingPeriod = 1, RollingStartNumber = 1
                    }
                }
            };
            var bodyString = Newtonsoft.Json.JsonConvert.SerializeObject(bodyJson);

            using var stream = new System.IO.MemoryStream();
            using (var writer = new System.IO.StreamWriter(stream, leaveOpen: true))
            {
                await writer.WriteAsync(bodyString);

                await writer.FlushAsync();
            }
            stream.Seek(0, System.IO.SeekOrigin.Begin);
            context.Setup(_ => _.Request.Body).Returns(stream);
            // action
            await diagnosisApi.RunAsync(context.Object.Request);

            // assert
        }
        public void PropertiesTest()
        {
            // preparation
            var model = new DiagnosisSubmissionParameter();

            // model property access
            Helper.ModelTestHelper.PropetiesTest(model);
        }
Esempio n. 8
0
 Task <HttpStatusCode> IHttpDataService.PutSelfExposureKeysAsync(DiagnosisSubmissionParameter request)
 {
     return(Task.Factory.StartNew <HttpStatusCode>(() =>
     {
         Debug.WriteLine("HttpDataServiceMock::PutSelfExposureKeysAsync called");
         return HttpStatusCode.OK;
     }));
 }
Esempio n. 9
0
        public async Task <HttpStatusCode> PutSelfExposureKeysAsync(DiagnosisSubmissionParameter request)
        {
            var            url     = $"{AppSettings.Instance.ApiUrlBase.TrimEnd('/')}/diagnosis";
            var            content = new StringContent(Utils.SerializeToJson(request), Encoding.UTF8, "application/json");
            HttpStatusCode status  = await PutAsync(url, content);

            return(status);
        }
        /// <summary>
        /// Validation Android
        /// </summary>
        /// <param name="param">subumission parameter</param>
        /// <returns>True when successful.</returns>
        public bool Validation(DiagnosisSubmissionParameter param, byte[] expectedNonce, DateTimeOffset requestTime, AuthorizedAppInformation app)
        {
            var claims = ParsePayload(param.DeviceVerificationPayload);

            // Validate the nonce
            if (Convert.ToBase64String(claims.Nonce) != Convert.ToBase64String(expectedNonce))
            {
                return(false);
            }

            // Validate time interval
            var now = requestTime.ToUnixTimeMilliseconds();

            if (app.SafetyNetPastTimeSeconds > 0)
            {
                var minTime = now - (app.SafetyNetPastTimeSeconds * 1000);
                if (claims.TimestampMilliseconds < minTime)
                {
                    return(false);
                }
            }
            if (app.SafetyNetFutureTimeSeconds > 0)
            {
                var minTime = now + (app.SafetyNetFutureTimeSeconds * 1000);
                if (claims.TimestampMilliseconds > minTime)
                {
                    return(false);
                }
            }

            // Validate certificate
            if (app.SafetyNetApkDigestSha256?.Length > 0)
            {
                var apkSha = Convert.ToBase64String(claims.ApkCertificateDigestSha256);
                if (!app.SafetyNetApkDigestSha256.Contains(apkSha))
                {
                    return(false);
                }
            }

            // Validate integrity
            if (app.SafetyNetCtsProfileMatch)
            {
                if (!claims.CtsProfileMatch)
                {
                    return(false);
                }
            }
            if (app.SafetyNetBasicIntegrity)
            {
                if (!claims.BasicIntegrity)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 11
0
        public async Task <HttpStatusCode> PutSelfExposureKeysAsync(DiagnosisSubmissionParameter request)
        {
            loggerService.StartMethod();
            var            url     = $"{AppSettings.Instance.ApiUrlBase.TrimEnd('/')}/v2/diagnosis";
            var            content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json");
            HttpStatusCode status  = await PutAsync(url, content);

            loggerService.EndMethod();
            return(status);
        }
        public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime)
        {
            var app = await AuthApp.GetAsync(param.Platform);

            return(param.Platform switch
            {
                "android" => await Android.Validation(param, param.GetAndroidNonce(), requestTime, app),
                "ios" => await Apple.Validation(param, requestTime, app),
                _ => false,
            });
Esempio n. 13
0
        private async Task <DiagnosisSubmissionParameter> CreateSubmissionAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys, PositiveDiagnosisState pendingDiagnosis)
        {
            // Create the network keys

            var keys = temporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key
            {
                KeyData            = Convert.ToBase64String(k.Key),
                RollingStartNumber = (uint)(k.RollingStart - DateTime.UnixEpoch).TotalMinutes / 10,
                RollingPeriod      = (uint)(k.RollingDuration.TotalMinutes / 10),
                TransmissionRisk   = (int)k.TransmissionRiskLevel
            });

            var beforeKey = Utils.SerializeToJson(temporaryExposureKeys.ToList());
            var afterKey  = Utils.SerializeToJson(keys.ToList());

            Debug.WriteLine($"C19R {beforeKey}");
            Debug.WriteLine($"C19R {afterKey}");

            foreach (var key in keys)
            {
                if (!key.IsValid())
                {
                    Debug.WriteLine($"C19R Invalid Key Expcetion");
                    throw new InvalidDataException();
                }
            }

            if (keys.ToArray() == null)
            {
                throw new InvalidDataException();
            }

            // Generate Padding
            var padding = GetPadding();

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

            // See if we can add the device verification
            if (DependencyService.Get <IDeviceVerifier>() is IDeviceVerifier verifier)
            {
                submission.DeviceVerificationPayload = await verifier?.VerifyAsync(submission);
            }
            return(submission);
        }
Esempio n. 14
0
        // Put /diagnosis - upload self diagnosys file
        public async Task PutSelfExposureKeysAsync(DiagnosisSubmissionParameter 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));
            }
        }
Esempio n. 15
0
        public async Task <bool> Validation(DiagnosisSubmissionParameter param)
        {
            switch (param.Platform)
            {
            case "android":
                return(await ValidationAndroid(param));

            case "ios":
                return(await ValidationApple(param));
            }
            return(false);
        }
Esempio n. 16
0
        private async Task <DiagnosisSubmissionParameter> CreateSubmissionAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys, string positiveDiagnosis)
        {
            var loggerService = LoggerService;

            loggerService.StartMethod();

            // Filter Temporary exposure keys
            var filteredTemporaryExposureKeys = ExposureNotificationService.FliterTemporaryExposureKeys(temporaryExposureKeys);

            // Create the network keys
            var keys = filteredTemporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key
            {
                KeyData            = Convert.ToBase64String(k.Key),
                RollingStartNumber = (uint)(k.RollingStart - DateTime.UnixEpoch).TotalMinutes / 10,
                RollingPeriod      = (uint)(k.RollingDuration.TotalMinutes / 10),
            });

            var beforeKey = JsonConvert.SerializeObject(temporaryExposureKeys.ToList());
            var afterKey  = JsonConvert.SerializeObject(keys.ToList());

            Debug.WriteLine($"C19R {beforeKey}");
            Debug.WriteLine($"C19R {afterKey}");

            if (keys.Count() == 0)
            {
                loggerService.Error($"Temporary exposure keys is empty.");
                loggerService.EndMethod();
                throw new InvalidDataException();
            }

            // Generate Padding
            var padding = GetPadding();

            // Create the submission
            var submission = new DiagnosisSubmissionParameter()
            {
                Keys     = keys.ToArray(),
                Regions  = AppSettings.Instance.SupportedRegions,
                Platform = DeviceInfo.Platform.ToString().ToLowerInvariant(),
                DeviceVerificationPayload = null,
                AppPackageName            = AppInfo.PackageName,
                VerificationPayload       = positiveDiagnosis,
                Padding = padding
            };

            submission.DeviceVerificationPayload = await DeviceVerifier.VerifyAsync(submission);

            loggerService.Info($"DeviceVerificationPayload is {(string.IsNullOrEmpty(submission.DeviceVerificationPayload) ? "null or empty" : "set")}.");
            loggerService.Info($"VerificationPayload is {(string.IsNullOrEmpty(submission.VerificationPayload) ? "null or empty" : "set")}.");

            loggerService.EndMethod();
            return(submission);
        }
        public Task SubmitDiagnosisAsync(DiagnosisSubmissionParameter Parameter)
        {
            var item = new DiagnosisModel()
            {
                id           = Parameter.UserUuid,
                PartitionKey = Parameter.SubmissionNumber,
                UserUuid     = Parameter.UserUuid,
                Keys         = Parameter.Keys
            };

            return(_db.Diagnosis.UpsertItemAsync <DiagnosisModel>(item, new PartitionKey(item.PartitionKey)));
        }
Esempio n. 18
0
        /// <summary>
        /// Validation iOS
        /// </summary>
        /// <param name="param">subumission parameter</param>
        /// <returns>True when successful.</returns>
        /// <remarks>
        /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data
        /// </remarks>
        public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime, AuthorizedAppInformation app)
        {
            var payload = new ApplePayload()
            {
                DeviceToken = param.DeviceVerificationPayload,
                Timestamp   = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };

            var keysText = param.Keys
                           .OrderBy(_ => _.KeyData)
                           .Select(_ => _.KeyData)
                           .Aggregate((a, b) => a + b);

            using (var sha = System.Security.Cryptography.SHA256.Create())
            {
                var value = System.Text.Encoding.UTF8.GetBytes(param.AppPackageName + keysText + string.Join(',', param.Regions));
                payload.TransactionId = Convert.ToBase64String(sha.ComputeHash(value));
            }

            var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey);

            var content = new StringContent(JsonConvert.SerializeObject(payload));
            var request = new HttpRequestMessage(HttpMethod.Post, UrlApple);

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
            var response = await ClientApple.SendAsync(request);

            //switch (response.StatusCode)
            //{
            //    // 200 OK:                  The transaction was successful
            //    // 200 Bit State Not Found: The bit state wasn't found
            //    case System.Net.HttpStatusCode.OK:
            //        if (response.ReasonPhrase == "OK") return true;

            //        break;
            //    //
            //    default:
            //        break;
            //}
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 19
0
        public void AndroidClearTextTestV3_NoSymptom()
        {
            var platform = "Android";
            var dummyDiagnosisKeyDataList = new[] {
                CreateDiagnosisKey("KeyData1", 10000, 140, 1),
                CreateDiagnosisKey("KeyData2", 20000, 141, 1),
                CreateDiagnosisKey("KeyData3", 30000, 142, 1),
                CreateDiagnosisKey("KeyData4", 40000, 143, 1),
                CreateDiagnosisKey("KeyData5", 50000, 70, 1),
            };

            var dummyRegions = new string[]
            {
                "440",
                "441",
            };

            var dummySymptomOnsetDate          = "2021-12-19T19:02:00.000+09:00";
            var dummyDeviceVerificationPayload = "DeviceVerificationPayload THIS STRING IS MEANINGLESS";
            var dummyAppPackageName            = "jp.go.mhlw.cocoa.unit_test";
            var dummyVerificationPayload       = "VerificationPayload THIS STRING IS MEANINGLESS";

            // This value will not affect any result.
            var dummyPadding = new Random().Next().ToString();

            var submissionParameter = new DiagnosisSubmissionParameter()
            {
                HasSymptom = false,
                Platform   = platform,
                Regions    = dummyRegions,
                OnsetOfSymptomOrTestDate = dummySymptomOnsetDate,
                Keys = dummyDiagnosisKeyDataList,
                DeviceVerificationPayload = dummyDeviceVerificationPayload,
                AppPackageName            = dummyAppPackageName,
                VerificationPayload       = dummyVerificationPayload,
                Padding = dummyPadding,
            };

            string clearText = DeviceVerifierUtils.GetNonceClearTextV3(submissionParameter);

            Assert.Equal(
                EXPECTED_CLEAR_TEXT_V3_NOSYMPTOM,
                clearText
                );
        }
Esempio n. 20
0
        private async Task <DiagnosisSubmissionParameter> CreateSubmissionAsync(
            DateTime symptomOnsetDate,
            IList <TemporaryExposureKey> temporaryExposureKeys,
            string processNumber,
            string idempotencyKey
            )
        {
            _loggerService.StartMethod();

            // Create the network keys
            var keys = temporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key
            {
                KeyData            = Convert.ToBase64String(k.KeyData),
                RollingStartNumber = (uint)k.RollingStartIntervalNumber,
                RollingPeriod      = (uint)k.RollingPeriod,
                ReportType         = (uint)k.ReportType,
            });

            // Generate Padding
            var padding = GetPadding();

            // Create the submission
            var submission = new DiagnosisSubmissionParameter()
            {
                SymptomOnsetDate          = symptomOnsetDate.ToString(AppConstants.FORMAT_TIMESTAMP),
                Keys                      = keys.ToArray(),
                Regions                   = AppSettings.Instance.SupportedRegions,
                Platform                  = DeviceInfo.Platform.ToString().ToLowerInvariant(),
                DeviceVerificationPayload = null,
                AppPackageName            = AppInfo.PackageName,
                VerificationPayload       = processNumber,
                IdempotencyKey            = idempotencyKey,
                Padding                   = padding
            };

            submission.DeviceVerificationPayload = await _deviceVerifier.VerifyAsync(submission);

            _loggerService.Info($"DeviceVerificationPayload is {(string.IsNullOrEmpty(submission.DeviceVerificationPayload) ? "null or empty" : "set")}.");
            _loggerService.Info($"VerificationPayload is {(string.IsNullOrEmpty(submission.VerificationPayload) ? "null or empty" : "set")}.");

            _loggerService.EndMethod();

            return(submission);
        }
Esempio n. 21
0
        public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime)
        {
            var app = await AuthApp.GetAsync(param.Platform);

            // unsupported
            if (app == null)
            {
                return(false);
            }
            if (!app.DeviceValidationEnabled)
            {
                return(true);
            }
            return(param.Platform switch
            {
                "android" => Android.Validation(param, param.GetAndroidNonce(), requestTime, app),
                "ios" => await Apple.Validation(param, requestTime, app),
                _ => false,
            });
Esempio n. 22
0
        Task <HttpStatusCode> IHttpDataService.PutSelfExposureKeysAsync(DiagnosisSubmissionParameter request)
        {
            var code     = HttpStatusCode.OK; // default. for PutSelfExposureKeys NG
            var dataType = mockCommonUtils.GetDiagnosisDataType();

            if (dataType >= 100) // HttpStatusCode >=100 by RFC2616#section-10
            {
                code = (HttpStatusCode)dataType;
            }
            else
            {
                switch (dataType)
                {
                case 1:
                    code = HttpStatusCode.NoContent;     //  for Successful PutSelfExposureKeys
                    break;
                }
            }

            Debug.WriteLine("HttpDataServiceMock::PutSelfExposureKeysAsync called");
            return(Task.FromResult(code));
        }
        public void ToModelTest(string keyData, int period, int expectedPeriod, int start)
        {
            // preparation
            var keyDataBytes  = Encoding.UTF8.GetBytes(keyData);
            var keyDataBase64 = Convert.ToBase64String(keyDataBytes);
            var model         = new DiagnosisSubmissionParameter();

            model.Keys = new DiagnosisSubmissionParameter.Key[] {
                new DiagnosisSubmissionParameter.Key()
                {
                    KeyData = keyDataBase64, RollingPeriod = (uint)period, RollingStartNumber = (uint)start, TransmissionRisk = 0
                }
            };
            var timestamp = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            // action
            var result = model.Keys.Select(_ => _.ToModel(model, timestamp));
            var item   = result.First();

            // assert
            CollectionAssert.AreEqual(keyDataBytes, item.KeyData);
            Assert.AreEqual(expectedPeriod, item.RollingPeriod);
            Assert.AreEqual(start, item.RollingStartIntervalNumber);
        }
Esempio n. 24
0
        private static byte[] GetNonce(DiagnosisSubmissionParameter submission)
        {
            var cleartext = GetNonceClearText(submission);
            var nonce     = GetSha256(cleartext);

            return(nonce);
        private async Task<DiagnosisSubmissionParameter> CreateSubmissionAsync(
            bool hasSymptom,
            DateTime symptomOnsetDate,
            IList<TemporaryExposureKey> temporaryExposureKeys,
            string processNumber,
            string idempotencyKey
            )
        {
            _loggerService.StartMethod();

            // Create the network keys
            var keys = temporaryExposureKeys.Select(k => new DiagnosisSubmissionParameter.Key
            {
                KeyData = Convert.ToBase64String(k.KeyData),
                RollingStartNumber = (uint)k.RollingStartIntervalNumber,
                RollingPeriod = (uint)k.RollingPeriod,
                ReportType = (uint)k.ReportType,
            });

            // Generate Padding
            var padding = GetPadding();

            // Create the submission
            var submission = new DiagnosisSubmissionParameter()
            {
                HasSymptom = hasSymptom,
                OnsetOfSymptomOrTestDate = symptomOnsetDate.ToString(AppConstants.FORMAT_TIMESTAMP),
                Keys = keys.ToArray(),
                Regions = AppSettings.Instance.SupportedRegions,
                Platform = DeviceInfo.Platform.ToString().ToLowerInvariant(),
                DeviceVerificationPayload = null,
                AppPackageName = AppInfo.PackageName,
                VerificationPayload = processNumber,
                IdempotencyKey = idempotencyKey,
                Padding = padding
            };

            // Create device verification payload
            var tries = 0;
            var delay = 4 * 1000;
            while (true) {
                var deviceVerificationPayload = await _deviceVerifier.VerifyAsync(submission);
                if (!_deviceVerifier.IsErrorPayload(deviceVerificationPayload))
                {
                    _loggerService.Info("Payload creation successful.");
                    submission.DeviceVerificationPayload = deviceVerificationPayload;
                    break;
                }
                else if (tries >= 3)
                {
                    _loggerService.Error("Payload creation failed all.");
                    throw new DiagnosisKeyRegisterException(DiagnosisKeyRegisterException.Codes.FailedCreatePayload);
                }

                _loggerService.Warning($"Payload creation failed. {tries + 1} time(s).");
                _loggerService.Info($"delay {delay} msec");
                await Task.Delay(delay);
                delay *= 2;

                tries++;
            }

            _loggerService.Info($"DeviceVerificationPayload is {(string.IsNullOrEmpty(submission.DeviceVerificationPayload) ? "null or empty" : "set")}.");
            _loggerService.Info($"VerificationPayload is {(string.IsNullOrEmpty(submission.VerificationPayload) ? "null or empty" : "set")}.");

            _loggerService.EndMethod();

            return submission;
        }
Esempio n. 26
0
 public Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime)
 {
     return(Task.FromResult(true));
 }
Esempio n. 27
0
 public static string GetNonceClearTextV3(DiagnosisSubmissionParameter submission)
 {
     return(string.Join("|", submission.SymptomOnsetDate, submission.AppPackageName, GetKeyString(submission.Keys), GetRegionString(submission.Regions), submission.VerificationPayload));
        /// <summary>
        /// Validation iOS
        /// </summary>
        /// <param name="param">subumission parameter</param>
        /// <returns>True when successful.</returns>
        /// <remarks>
        /// https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data
        /// </remarks>
        public async Task <bool> Validation(DiagnosisSubmissionParameter param, DateTimeOffset requestTime, AuthorizedAppInformation app)
        {
            var payload = new ApplePayload()
            {
                DeviceToken = param.DeviceVerificationPayload,
                Timestamp   = requestTime.ToUnixTimeMilliseconds()
            };

            var keysText = string.Empty;

            if (param is V1DiagnosisSubmissionParameter)
            {
                keysText = (param as V1DiagnosisSubmissionParameter).Keys
                           .OrderBy(_ => _.KeyData)
                           .Select(_ => _.KeyData)
                           .Aggregate((a, b) => a + b);
            }
            else
            {
                keysText = param.Keys
                           .OrderBy(_ => _.KeyData)
                           .Select(_ => _.KeyData)
                           .Aggregate((a, b) => a + b);
            }

            using (var sha = System.Security.Cryptography.SHA256.Create())
            {
                var value = System.Text.Encoding.UTF8.GetBytes(param.AppPackageName + keysText + string.Join(',', param.Regions));
                payload.TransactionId = Convert.ToBase64String(sha.ComputeHash(value));
            }

            Logger.LogInformation($"{nameof(Validation)} DeviceCheckKeyId:{app.DeviceCheckKeyId} DeviceCheckTeamId:{app.DeviceCheckTeamId} DeviceCheckPrivateKey:{app.DeviceCheckPrivateKey}");

            var jwt = GenerateClientSecretJWT(requestTime, app.DeviceCheckKeyId, app.DeviceCheckTeamId, app.DeviceCheckPrivateKey);

            var payloadJson = JsonConvert.SerializeObject(payload);

            Logger.LogInformation($"{nameof(Validation)} payload:{payloadJson} ");
            var request = new HttpRequestMessage(HttpMethod.Post, UrlApple);

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt);
            request.Content = new StringContent(payloadJson, Encoding.UTF8, "application/json");
            try
            {
                var response = await ClientApple.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                {
                    var responseBody = await response.Content.ReadAsStringAsync();

                    Logger.LogWarning($"POST {UrlApple} {response.StatusCode} {response.ReasonPhrase} {responseBody}");
                }

                //switch (response.StatusCode)
                //{
                //    // 200 OK:                  The transaction was successful
                //    // 200 Bit State Not Found: The bit state wasn't found
                //    case System.Net.HttpStatusCode.OK:
                //        if (response.ReasonPhrase == "OK") return true;

                //        break;
                //    //
                //    default:
                //        break;
                //}
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"{nameof(Validation)}");
                throw;
            }
        }
Esempio n. 29
0
        public static string GetNonceClearTextV3(DiagnosisSubmissionParameter submission)
        {
            string hasSymptom = submission.HasSymptom ? "HasSymptom" : "NoSymptom";

            return(string.Join("|", submission.AppPackageName, submission.OnsetOfSymptomOrTestDate, hasSymptom, GetKeyString(submission.Keys), GetRegionString(submission.Regions), submission.VerificationPayload));
Esempio n. 30
0
 static string GetNonceClearText(DiagnosisSubmissionParameter submission) =>
 string.Join("|", submission.AppPackageName, GetKeyString(submission.Keys), GetRegionString(submission.Regions), submission.VerificationPayload);