Example #1
0
        public async Task <IActionResult> VerifyPersonFace([FromBody] BiometricPersonDataDto biometricPersonData)
        {
            Guid   guid          = _dataAccessService.FindPersonGuid(biometricPersonData.PersonData);
            string personGroupId = _portalConfiguration.FacePersonGroupId + (_portalConfiguration.DemoMode ? string.Empty : biometricPersonData.Requester);

            if (guid == Guid.Empty)
            {
                if (_portalConfiguration.DemoMode)
                {
                    Person person = _facesService.GetPersons(personGroupId).FirstOrDefault(p => p.UserData.Equals(biometricPersonData.PersonData, StringComparison.InvariantCultureIgnoreCase));
                    if (person != null)
                    {
                        guid = person.PersonId;
                    }
                }
                else
                {
                    return(BadRequest());
                }
            }

            byte[] imageContent = Convert.FromBase64String(biometricPersonData.ImageString);

            Tuple <bool, double> res = await _facesService.VerifyPerson(personGroupId, guid, imageContent).ConfigureAwait(false);

            return(Ok(new { Result = res.Item1, Probability = res.Item2 }));
        }
Example #2
0
        public async Task <IActionResult> RegisterPerson([FromBody] BiometricPersonDataDto biometricPersonData)
        {
            PersonFaceData personFaceData = new PersonFaceData
            {
                PersonGroupId = _portalConfiguration.FacePersonGroupId + (_portalConfiguration.DemoMode ? string.Empty : biometricPersonData.Requester),
                PersonGuid    = Guid.NewGuid(),
                UserData      = biometricPersonData.PersonData,
                ImageContent  = Convert.FromBase64String(biometricPersonData.ImageString)
            };

            Guid guid = await _facesService.AddPerson(personFaceData).ConfigureAwait(false);

            _dataAccessService.AddBiometricRecord(biometricPersonData.PersonData, guid);

            return(Ok());
        }
Example #3
0
        public async Task <IActionResult> RegisterPerson([FromBody] BiometricPersonDataDto biometricPersonData)
        {
            byte[] imageContent = null;

            _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}, {biometricPersonData.Images?.Count ?? -1} {nameof(biometricPersonData.Images)}");
            Contract.Requires(biometricPersonData != null, nameof(biometricPersonData));
            Contract.Requires(biometricPersonData.Images != null, $"{nameof(biometricPersonData)}.{nameof(biometricPersonData.Images)}");
            Contract.Requires(biometricPersonData.Images.Count > 0, $"Count {nameof(biometricPersonData)}.{nameof(biometricPersonData.Images)} > 0");

            foreach (var image in biometricPersonData.Images)
            {
                _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}, {nameof(image.Key)}={image.Key}, image length: {image.Value?.Length ?? -1}");
            }

            TaskCompletionSource <InherenceData> taskCompletionSource = _inherenceService.GetIdentityProofsAwaiter(biometricPersonData.SessionKey);

            InherenceData inherenceData;

            if (taskCompletionSource.Task.IsCompleted)
            {
                inherenceData = taskCompletionSource.Task.Result;
            }
            else
            {
                try
                {
                    inherenceData = await taskCompletionSource.Task.TimeoutAfter(30000).ConfigureAwait(false);
                }
                catch (TimeoutException ex)
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: Identity Proofs not received for the SessionKey {biometricPersonData.SessionKey}", ex);
                    return(BadRequest("Identity Proofs not received"));
                }
                catch (Exception ex)
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: Identity Proofs failed", ex);
                    return(BadRequest($"Identity Proofs failed: {ex.Message}"));
                }
                finally
                {
                    _inherenceService.RemoveIdentityProofsAwaiter(biometricPersonData.SessionKey);
                }
            }

            _inherenceService.RemoveIdentityProofsAwaiter(biometricPersonData.SessionKey);

            if (inherenceData == null)
            {
                _logger.Error($"[{_inherenceService.AccountId}]: Identity Proofs failed for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                return(BadRequest("Identity Proofs failed"));
            }

            _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, {nameof(InherenceData)} with {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey} obtained");

            string registrationKey = inherenceData.RootRegistrationProof.AssetCommitments[0].ToHexString();

            _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, root commitment is {inherenceData.AssetRootCommitment.ToHexString()} and registration key is {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey} obtained");

            string personGroupId = _portalConfiguration.DemoMode ? _portalConfiguration.FacePersonGroupId.ToLower() : inherenceData.Issuer.ToHexString().ToLower();

            string commitmentToRoot = inherenceData.AssetRootCommitment.ToHexString();

            if (!ConfidentialAssetsHelper.VerifySurjectionProof(inherenceData.RootRegistrationProof, inherenceData.AssetRootCommitment))
            {
                _logger.Error($"[{_inherenceService.AccountId}]: Registration Proofs failed for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                throw new InherenceRegistrationProofsIncorrectException();
            }

            if (inherenceData.AssociatedRootCommitment != null)
            {
                //=============================================================================
                // In the case when AssociatedRootCommitment is not null one of the following scenarios can occur:
                //   1. The user already has Root Inherence Protection attribute - in this case
                //      image provided for registration must be checked for compliance with the existing factor
                //   2. The user does not have yet Root Protection attribute - in this case user must provide two images,
                //      one for the Root Inherence protection attribute and the second for associated one.
                //      Both images must be checked for matching and then two attributes will be created.
                //=============================================================================

                _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, {nameof(InherenceData)} with {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey} contains {nameof(inherenceData.AssociatedRootCommitment)}");

                byte[] commitment = ConfidentialAssetsHelper.SumCommitments(inherenceData.AssetRootCommitment, inherenceData.AssociatedRootCommitment);

                if (!ConfidentialAssetsHelper.VerifySurjectionProof(inherenceData.AssociatedRegistrationProof, commitment))
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: {nameof(inherenceData.AssociatedRegistrationProof)} failed for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                    return(BadRequest(Resources.ERR_INHERENCE_REGISTRATION_PROOFS_INCORRECT));
                }

                string commitmentToAssociated    = inherenceData.AssociatedRootCommitment.ToHexString();
                string associatedRegistrationKey = inherenceData.AssociatedRegistrationProof.AssetCommitments[0].ToHexString();
                _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, associated commitment is {commitmentToAssociated} and registration key is {associatedRegistrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey} obtained");

                if (!biometricPersonData.Images.ContainsKey(commitmentToAssociated))
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, no image found for the associated commitment {commitmentToAssociated}");
                    return(BadRequest($"No image found for the associated commitment {commitmentToAssociated}"));
                }

                Guid rootRegistrationGuid = await GetPersonRegistrationGuid(personGroupId, registrationKey).ConfigureAwait(false);

                if (Guid.Empty.Equals(rootRegistrationGuid))
                {
                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, No root registration found for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");

                    if (!biometricPersonData.Images.ContainsKey(commitmentToRoot))
                    {
                        _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, no image found for the root commitment {commitmentToRoot}");
                        return(BadRequest($"No image found for the root commitment {commitmentToRoot}"));
                    }

                    imageContent = biometricPersonData.Images[commitmentToRoot];
                    byte[] faceAssociated = biometricPersonData.Images[commitmentToAssociated];

                    bool matches = await _facesService.VerifyFaces(imageContent, faceAssociated).ConfigureAwait(false);

                    if (!matches)
                    {
                        _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, faces do not match for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                        return(BadRequest("Provided face images do not match one to another"));
                    }

                    PersonFaceData rootFaceData = new PersonFaceData
                    {
                        PersonGroupId = personGroupId,
                        Name          = registrationKey,
                        UserData      = registrationKey,
                        ImageContent  = imageContent
                    };

                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, adding root registration {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                    await AddPerson(rootFaceData).ConfigureAwait(false);

                    registrationKey = inherenceData.AssociatedRegistrationProof.AssetCommitments[0].ToHexString();
                    imageContent    = faceAssociated;

                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, proceeding with associated registration {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                }
                else
                {
                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, Root registration with key {registrationKey} found for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");

                    registrationKey = inherenceData.AssociatedRegistrationProof.AssetCommitments[0].ToHexString();
                    imageContent    = biometricPersonData.Images.ContainsKey(commitmentToAssociated) ? biometricPersonData.Images[commitmentToAssociated] : null;
                    bool isIdentical = await VerifyPersonFace(personGroupId, rootRegistrationGuid, imageContent).ConfigureAwait(false);

                    if (!isIdentical)
                    {
                        _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, face do not match to registered one for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                        throw new InherenceCrossMatchingFailedException(inherenceData.RootRegistrationProof.AssetCommitments[0].ToHexString());
                    }

                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, proceeding with associated registration {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                }
            }
            else
            {
                _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, {nameof(InherenceData)} with {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey} does not contain {nameof(inherenceData.AssociatedRootCommitment)}");
                if (!biometricPersonData.Images.ContainsKey(commitmentToRoot))
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, no image found for the root commitment {commitmentToRoot}");
                    return(BadRequest($"No image found for the root commitment {commitmentToRoot}"));
                }

                imageContent = biometricPersonData.Images[commitmentToRoot];
            }

            Guid guid = _dataAccessService.FindPersonGuid(registrationKey);

            PersonFaceData personFaceData = new PersonFaceData
            {
                PersonGroupId = personGroupId,
                Name          = registrationKey,
                UserData      = registrationKey,
                ImageContent  = imageContent
            };

            try
            {
                if (guid == Guid.Empty)
                {
                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, adding registration {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                    await AddPerson(personFaceData).ConfigureAwait(false);
                }
                else
                {
                    _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, replacing registration {registrationKey} for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");
                    await ReplacePerson(personFaceData).ConfigureAwait(false);
                }
            }
            catch (Exception ex)
            {
                if (ex is AggregateException aex)
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)} failed with aggregated exception", aex.InnerException);
                }
                else
                {
                    _logger.Error($"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)} failed with exception", ex);
                }

                throw;
            }

            _logger.LogIfDebug(() => $"[{_inherenceService.AccountId}]: {nameof(RegisterPerson)}, completed successfully for {nameof(biometricPersonData.SessionKey)}={biometricPersonData.SessionKey}");

            return(Ok());
        }