Accessing entities using EntityFramework on encrypted database failed
---------------------------------------------------------------------

                 Key: DNET-832
                 URL: http://tracker.firebirdsql.org/browse/DNET-832
             Project: .NET Data provider
          Issue Type: Bug
    Affects Versions: 6.0.0.0
         Environment: Issue occurred on develoment environment: Windows 10; 
.NET 4.7.1; Firebird 3.0.3.32900 (32 Bit); Entity Framework 6.2.0-61023.0; 
IBPhoenix Encryption Plugin 1.2.0
            Reporter: Michael Wresche
            Assignee: Jiri Cincura
            Priority: Blocker


At first:
 - We have an encrypted Firebird database which will be accessed from our 
application by using Entity Framework
 - The encryption plugin uses a file-based key so the connection string does 
not contain any encryption information.
 - Accessing the encrypted database by using FbConnection, FbCommand, etc. 
works fine
 - If the database is not encrypted and the encryption plugin is not configured 
in Firebird, Entity Framework as well as FbConnection works fine
 - If we access the encrypted database using Entity Framework, we got the 
following exception (Unfortunately in german): Das Objekt des Typs 
"FirebirdSql.Data.Client.Managed.Version13.CryptKeyCallbackReponse" kann nicht 
in Typ "FirebirdSql.Data.Client.Managed.GenericResponse" umgewandelt werden. 
You can find the callstack of the exception at the end of the bug description.

I have debugged the issue with the latest sources on GitHub and was able to 
find the root cause (hopefully): The method GdsConnection.ProcessOperation 
returned an CryptKeyCallbackResponse which will be casted to GenericResponse in 
Version10.GdsDatabase.ReadGenericResponse and this fails. 

After some short debugging sessions in order to find out what happened when I 
access the encrypted database directly (without Entity Framework), I came to 
the following conclusion:

Entity Framework invoked FbProviderServices.GetDbProviderManifestToken() with a 
connection which is not yet open. Because of the connection state the requested 
server version will be determined by using the FbServerProperties class 
(FbProviderServices Line 130). This class uses the FbService to communicate 
with the database. The FbService uses the GdsServiceManager and this class 
creates an instance of the Version10.GdsDatabase class which is used to 
communicate with the database. In my opinion, the instance of GdsDatabase 
should be created by using the appropriate factory method. Anyway, it seems 
that Version10.GdsDatabase is not able to communicate with encrypted databases. 
I came to the conclusion that encryption is only compatible with Version13. I 
made the following two changes in order to get working solution:

1. I changed the constructor of GdsServiceManager to create a 
Version13.GdsDatabase class. 
2. In class Version13.GdsDatabase, I override ReadGenericResponse:
               public override GenericResponse ReadGenericResponse()
                {
                        byte[] cryptKey = new byte[2096];

                        var response = ReadResponse();
                        while (response is CryptKeyCallbackReponse 
cryptResponse)
                        {
                                XdrStream.Write(IscCodes.op_crypt_key_callback);
                                XdrStream.WriteBuffer(cryptKey);
                                XdrStream.Flush();
                                response = ReadResponse();
                        }

                        return response as GenericResponse;
                }
 
I know that this solution is just a hack but I don't know the architecture of 
the source code and I found no helpful source code comments. With the described 
changes, I was able to access the database.

I was wondering why no other user has reported a similar behavior.

I do my best to add all required information. If you need further information, 
feel free to contact me.

The callstack of the exception:

FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ReadGenericResponse()
 Line 602
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Client\Managed\Version10\GdsDatabase.cs(602)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Client.Managed.Version10.GdsServiceManager.Attach(FirebirdSql.Data.Common.ServiceParameterBuffer
 spb, string dataSource, int port, string service) Line 73
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Client\Managed\Version10\GdsServiceManager.cs(73)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbService.Open() 
Line 114
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbService.cs(114)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbService.QueryService(byte[]
 items) Line 341
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbService.cs(341)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbService.ProcessQuery(byte[]
 items, System.Action<bool, object> queryResponseAction) Line 231
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbService.cs(231)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbService.Query(byte[]
 items, System.Action<bool, object> resultAction) Line 200
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbService.cs(200)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbService.Query(byte[]
 items) Line 159
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbService.cs(159)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbServerProperties.GetInfo(byte[]
 items) Line 90
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbServerProperties.cs(90)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbServerProperties.GetInfo(int
 item) Line 85
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbServerProperties.cs(85)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbServerProperties.GetString(int
 item) Line 75
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbServerProperties.cs(75)
FirebirdSql.Data.FirebirdClient.dll!FirebirdSql.Data.Services.FbServerProperties.GetServerVersion()
 Line 40
        at 
C:\Users\michael.wresche\source\repos\FirebirdSql.Data.FirebirdClient\Provider\src\FirebirdSql.Data.FirebirdClient\Services\FbServerProperties.cs(40)
EntityFramework.Firebird.dll!EntityFramework.Firebird.FbProviderServices.GetDbProviderManifestToken(System.Data.Common.DbConnection
 connection) Line 130
        at 
C:\Users\michael.wresche\Source\Repos\FirebirdSql.Data.FirebirdClient\Provider\src\EntityFramework.Firebird\FbProviderServices.cs(130)
EntityFramework.dll!System.Data.Entity.Core.Common.DbProviderServices.GetProviderManifestToken(System.Data.Common.DbConnection
 connection)
EntityFramework.dll!System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(System.Data.Entity.Core.Common.DbProviderServices
 providerServices, System.Data.Common.DbConnection connection)
mscorlib.dll!System.Collections.Concurrent.ConcurrentDictionary<System.Tuple<System.Type,
 string, string>, string>.GetOrAdd(System.Tuple<System.Type, string, string> 
key, System.Func<System.Tuple<System.Type, string, string>, string> 
valueFactory)
EntityFramework.dll!System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(System.Data.Common.DbConnection
 connection, out System.Data.Entity.Core.Common.DbProviderManifest 
providerManifest)
EntityFramework.dll!System.Data.Entity.DbModelBuilder.Build(System.Data.Common.DbConnection
 providerConnection)
EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.CreateModel(System.Data.Entity.Internal.LazyInternalContext
 internalContext)
EntityFramework.dll!System.Data.Entity.Internal.RetryLazy<System.Data.Entity.Internal.LazyInternalContext,
 
System.Data.Entity.Infrastructure.DbCompiledModel>.GetValue(System.Data.Entity.Internal.LazyInternalContext
 input)
EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.Initialize()
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(System.Type
 entityType)
EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet<OTTO.IBA.Entities.DBVersion>.Initialize()
EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet<OTTO.IBA.Entities.DBVersion>.AsNoTracking()
EntityFramework.dll!System.Data.Entity.Infrastructure.DbQuery<OTTO.IBA.Entities.DBVersion>.AsNoTracking()
OTTO.IBA.Datenbankzugriff.EntityFramework.dll!OTTO.IBA.Datenbankzugriff.EntityFramework.DAOs.DBVersionDAO.GetAktuelleDBVersion()
 Line 45
        at 
C:\Projekte\Otto_IBA2\Development\Sources\App\Datenbankzugriff\OTTO.IBA.Datenbankzugriff.EntityFramework\DAOs\DBVersionDAO.cs(45)


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://tracker.firebirdsql.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Firebird-net-provider mailing list
Firebird-net-provider@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/firebird-net-provider

Reply via email to