Skip to content

Commit ab0ecd1

Browse files
committed
Support for creating encrypted databases (DNET-841).
1 parent 596b638 commit ab0ecd1

File tree

10 files changed

+90
-27
lines changed

10 files changed

+90
-27
lines changed

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsDatabase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ protected void SafelyDetach()
276276

277277
#region Database Methods
278278

279-
public virtual void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database)
279+
public virtual void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey)
280280
{
281281
try
282282
{

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version10/GdsServiceManager.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public GdsDatabase Database
5555
public GdsServiceManager(GdsConnection connection)
5656
{
5757
_connection = connection;
58-
_database = new GdsDatabase(_connection);
58+
_database = CreateDatabase(_connection);
5959
}
6060

6161
#endregion
@@ -178,6 +178,11 @@ public virtual void Query(ServiceParameterBuffer spb, int requestLength, byte[]
178178
}
179179
}
180180

181+
protected virtual GdsDatabase CreateDatabase(GdsConnection connection)
182+
{
183+
return new GdsDatabase(connection);
184+
}
185+
181186
#endregion
182187
}
183188
}

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version11/GdsServiceManager.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,19 @@
1515

1616
//$Authors = Carlos Guzman Alvarez, Jiri Cincura (jiri@cincura.net)
1717

18+
using FirebirdSql.Data.Common;
19+
1820
namespace FirebirdSql.Data.Client.Managed.Version11
1921
{
2022
internal class GdsServiceManager : Version10.GdsServiceManager
2123
{
2224
public GdsServiceManager(GdsConnection connection)
2325
: base(connection)
2426
{ }
27+
28+
protected override Version10.GdsDatabase CreateDatabase(GdsConnection connection)
29+
{
30+
return new GdsDatabase(connection);
31+
}
2532
}
2633
}

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version12/GdsServiceManager.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,19 @@
1515

1616
//$Authors = Carlos Guzman Alvarez, Jiri Cincura (jiri@cincura.net)
1717

18+
using FirebirdSql.Data.Common;
19+
1820
namespace FirebirdSql.Data.Client.Managed.Version12
1921
{
2022
internal class GdsServiceManager : Version11.GdsServiceManager
2123
{
2224
public GdsServiceManager(GdsConnection connection)
2325
: base(connection)
2426
{ }
27+
28+
protected override Version10.GdsDatabase CreateDatabase(GdsConnection connection)
29+
{
30+
return new GdsDatabase(connection);
31+
}
2532
}
2633
}

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsDatabase.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ namespace FirebirdSql.Data.Client.Managed.Version13
3030
{
3131
internal class GdsDatabase : Version12.GdsDatabase
3232
{
33-
#warning Refactoring op_attach and op_create.
3433
public GdsDatabase(GdsConnection connection)
3534
: base(connection)
3635
{ }
@@ -42,14 +41,7 @@ public override void Attach(DatabaseParameterBuffer dpb, string dataSource, int
4241
SendAttachToBuffer(dpb, database);
4342
XdrStream.Flush();
4443
var response = ReadResponse();
45-
#warning Unification
46-
while (response is CryptKeyCallbackReponse cryptResponse)
47-
{
48-
XdrStream.Write(IscCodes.op_crypt_key_callback);
49-
XdrStream.WriteBuffer(cryptKey);
50-
XdrStream.Flush();
51-
response = ReadResponse();
52-
}
44+
response = ProcessCryptCallbackResponseIfNeeded(response, cryptKey);
5345
ProcessAttachResponse(response as GenericResponse);
5446
}
5547
catch (IscException)
@@ -79,6 +71,38 @@ protected override void SendAttachToBuffer(DatabaseParameterBuffer dpb, string d
7971
XdrStream.WriteBuffer(dpb.ToArray());
8072
}
8173

74+
public override void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey)
75+
{
76+
try
77+
{
78+
SendCreateToBuffer(dpb, database);
79+
XdrStream.Flush();
80+
81+
try
82+
{
83+
var response = ReadResponse();
84+
response = ProcessCryptCallbackResponseIfNeeded(response, cryptKey);
85+
ProcessCreateResponse(response as GenericResponse);
86+
87+
Detach();
88+
}
89+
catch (IscException)
90+
{
91+
try
92+
{
93+
CloseConnection();
94+
}
95+
catch
96+
{ }
97+
throw;
98+
}
99+
}
100+
catch (IOException ex)
101+
{
102+
throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex);
103+
}
104+
}
105+
82106
protected override void SendCreateToBuffer(DatabaseParameterBuffer dpb, string database)
83107
{
84108
XdrStream.Write(IscCodes.op_create);
@@ -97,6 +121,18 @@ public override void AttachWithTrustedAuth(DatabaseParameterBuffer dpb, string d
97121
Attach(dpb, dataSource, port, database, cryptKey);
98122
}
99123

124+
public IResponse ProcessCryptCallbackResponseIfNeeded(IResponse response, byte[] cryptKey)
125+
{
126+
while (response is CryptKeyCallbackReponse cryptResponse)
127+
{
128+
XdrStream.Write(IscCodes.op_crypt_key_callback);
129+
XdrStream.WriteBuffer(cryptKey);
130+
XdrStream.Flush();
131+
response = ReadResponse();
132+
}
133+
return response;
134+
}
135+
100136
#region Override Statement Creation Methods
101137

102138
public override StatementBase CreateStatement()

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Managed/Version13/GdsServiceManager.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,7 @@ public override void Attach(ServiceParameterBuffer spb, string dataSource, int p
3333
SendAttachToBuffer(spb, service);
3434
Database.XdrStream.Flush();
3535
var response = Database.ReadResponse();
36-
while (response is CryptKeyCallbackReponse cryptResponse)
37-
{
38-
Database.XdrStream.Write(IscCodes.op_crypt_key_callback);
39-
Database.XdrStream.WriteBuffer(cryptKey);
40-
Database.XdrStream.Flush();
41-
response = Database.ReadResponse();
42-
}
36+
response = (Database as GdsDatabase).ProcessCryptCallbackResponseIfNeeded(response, cryptKey);
4337
ProcessAttachResponse(response as GenericResponse);
4438
}
4539
catch (IOException ex)
@@ -48,5 +42,10 @@ public override void Attach(ServiceParameterBuffer spb, string dataSource, int p
4842
throw IscException.ForErrorCode(IscCodes.isc_net_write_err, ex);
4943
}
5044
}
45+
46+
protected override Version10.GdsDatabase CreateDatabase(GdsConnection connection)
47+
{
48+
return new GdsDatabase(connection);
49+
}
5150
}
5251
}

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesDatabase.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ public void Dispose()
149149

150150
#region Database Methods
151151

152-
public void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database)
152+
public void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey)
153153
{
154+
CheckCryptKeyForSupport(cryptKey);
155+
154156
var databaseBuffer = Encoding2.Default.GetBytes(database);
155157

156158
ClearStatusVector();
@@ -205,9 +207,7 @@ public void CancelEvents(RemoteEvent events)
205207

206208
public void Attach(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey)
207209
{
208-
// ICryptKeyCallbackImpl would have to be passed from C# for 'cryptKey' passing
209-
if (cryptKey?.Length > 0)
210-
throw new NotSupportedException("Passing Encryption Key isn't, yet, supported on Firebird Embedded.");
210+
CheckCryptKeyForSupport(cryptKey);
211211

212212
var databaseBuffer = Encoding2.Default.GetBytes(database);
213213

@@ -359,5 +359,16 @@ private void DatabaseInfo(byte[] items, byte[] buffer, int bufferLength)
359359
}
360360

361361
#endregion
362+
363+
#region Internal Static Methods
364+
365+
internal static void CheckCryptKeyForSupport(byte[] cryptKey)
366+
{
367+
// ICryptKeyCallbackImpl would have to be passed from C# for 'cryptKey' passing
368+
if (cryptKey?.Length > 0)
369+
throw new NotSupportedException("Passing Encryption Key isn't, yet, supported on Firebird Embedded.");
370+
}
371+
372+
#endregion
362373
}
363374
}

Provider/src/FirebirdSql.Data.FirebirdClient/Client/Native/FesServiceManager.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ public FesServiceManager(string dllName, Charset charset)
6262

6363
public void Attach(ServiceParameterBuffer spb, string dataSource, int port, string service, byte[] cryptKey)
6464
{
65-
// ICryptKeyCallbackImpl would have to be passed from C# for 'cryptKey' passing
66-
if (cryptKey?.Length > 0)
67-
throw new NotSupportedException("Passing Encryption Key isn't, yet, supported on Firebird Embedded.");
65+
FesDatabase.CheckCryptKeyForSupport(cryptKey);
6866

6967
ClearStatusVector();
7068

Provider/src/FirebirdSql.Data.FirebirdClient/Common/IDatabase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal interface IDatabase : IDisposable
3838
void AttachWithTrustedAuth(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey);
3939
void Detach();
4040

41-
void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database);
41+
void CreateDatabase(DatabaseParameterBuffer dpb, string dataSource, int port, string database, byte[] cryptKey);
4242
void DropDatabase();
4343

4444
TransactionBase BeginTransaction(TransactionParameterBuffer tpb);

Provider/src/FirebirdSql.Data.FirebirdClient/FirebirdClient/FbConnectionInternal.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public void Dispose()
123123
public void CreateDatabase(DatabaseParameterBuffer dpb)
124124
{
125125
var db = ClientFactory.CreateDatabase(_options);
126-
db.CreateDatabase(dpb, _options.DataSource, _options.Port, _options.Database);
126+
db.CreateDatabase(dpb, _options.DataSource, _options.Port, _options.Database, _options.CryptKey);
127127
}
128128

129129
public void DropDatabase()

0 commit comments

Comments
 (0)