protected override void SetupVariant(int options) { _encrypted = options == 1; C4EncryptionKey crypto = new C4EncryptionKey(); C4EncryptionKey *encryption = null; if (_encrypted) { WriteLine(" ...encrypted"); crypto.algorithm = C4EncryptionAlgorithm.AES256; for (int i = 0; i < 32; i++) { crypto.bytes[i] = 0xcc; } encryption = &crypto; } _store = (C4BlobStore *)LiteCoreBridge.Check(err => Native.c4blob_openStore(Path.Combine( Test.TestDir, $"cbl_blob_test{Path.DirectorySeparatorChar}"), C4DatabaseFlags.Create, encryption, err)); var bogusKey = _bogusKey; for (int i = 0; i < C4BlobKey.Size; i++) { bogusKey.bytes[i] = 0x55; } }
private C4View *OpenIndexWithOptions(C4DatabaseFlags options, bool dryRun = false) { if (_indexDB == null) { _indexDB = (C4View *)ForestDBBridge.Check(err => { var encryptionKey = default(C4EncryptionKey); if (_dbStorage.EncryptionKey != null) { encryptionKey = new C4EncryptionKey(_dbStorage.EncryptionKey.KeyData); } return(Native.c4view_open(_dbStorage.Forest, _path, Name, dryRun ? "0" : Delegate.MapVersion, options, &encryptionKey, err)); }); if (dryRun) { ForestDBBridge.Check(err => Native.c4view_close(_indexDB, err)); _indexDB = null; } } return(_indexDB); }
public AtomicAction ActionToChangeEncryptionKey(SymmetricKey newKey) { var retVal = new AtomicAction(() => ForestDBBridge.Check(err => { var newc4key = default(C4EncryptionKey); if (newKey != null) { newc4key = new C4EncryptionKey(newKey.KeyData); } return(Native.c4db_rekey(Forest, &newc4key, err)); }), null, null); foreach (var viewName in GetAllViews()) { var store = GetViewStorage(viewName, false) as ForestDBViewStore; if (store == null) { continue; } retVal.AddLogic(store.ActionToChangeEncryptionKey(newKey)); } return(retVal); }
public void TestDatabaseRekey() { RunTestVariants(() => { CreateNumberedDocs(99); // Add blob to the store: var blobToStore = C4Slice.Constant("This is a blob to store in the store!"); var blobKey = new C4BlobKey(); var blobStore = (C4BlobStore *)LiteCoreBridge.Check(err => Native.c4db_getBlobStore(Db, err)); LiteCoreBridge.Check(err => { C4BlobKey local; var retVal = NativeRaw.c4blob_create(blobStore, blobToStore, null, &local, err); blobKey = local; return(retVal); }); C4Error error; var blobResult = NativeRaw.c4blob_getContents(blobStore, blobKey, &error); ((C4Slice)blobResult).Should().Equal(blobToStore); Native.c4slice_free(blobResult); // If we're on the unexcrypted pass, encrypt the db. Otherwise, decrypt it: var newKey = new C4EncryptionKey(); if (Native.c4db_getConfig(Db)->encryptionKey.algorithm == C4EncryptionAlgorithm.None) { newKey.algorithm = C4EncryptionAlgorithm.AES256; var keyBytes = Encoding.ASCII.GetBytes("a different key than default...."); Marshal.Copy(keyBytes, 0, (IntPtr)newKey.bytes, 32); } var tmp = newKey; LiteCoreBridge.Check(err => { var local = tmp; return(Native.c4db_rekey(Db, &local, err)); }); // Verify the db works: Native.c4db_getDocumentCount(Db).Should().Be(99); ((IntPtr)blobStore).Should().NotBe(IntPtr.Zero); blobResult = NativeRaw.c4blob_getContents(blobStore, blobKey, &error); ((C4Slice)blobResult).Should().Equal(blobToStore); Native.c4slice_free(blobResult); // Check thqat db can be reopened with the new key: Native.c4db_getConfig(Db)->encryptionKey.algorithm.Should().Be(newKey.algorithm); for (int i = 0; i < 32; i++) { Native.c4db_getConfig(Db)->encryptionKey.bytes[i].Should().Be(newKey.bytes[i]); } ReopenDB(); }); }
public AtomicAction ActionToChangeEncryptionKey(SymmetricKey newKey) { return(new AtomicAction(() => ForestDBBridge.Check(err => { var newc4key = default(C4EncryptionKey); if (newKey != null) { newc4key = new C4EncryptionKey(newKey.KeyData); } return Native.c4view_rekey(_indexDB, &newc4key, err); }), null, null)); }
/// <summary> /// Sets the encryption key for the database. If null, encryption is /// removed. /// </summary> /// <param name="key">The new key to encrypt the database with, or <c>null</c> /// to remove encryption</param> public void SetEncryptionKey([CanBeNull] EncryptionKey key) { ThreadSafety.DoLockedBridge(err => { var newKey = new C4EncryptionKey { algorithm = key == null ? C4EncryptionAlgorithm.None : C4EncryptionAlgorithm.AES256 }; if (key != null) { var i = 0; foreach (var b in key.KeyData) { newKey.bytes[i++] = b; } } return(Native.c4db_rekey(c4db, &newKey, err)); }); }
protected override void SetupVariant(int option) { _objectCount = Native.c4_getObjectCount(); Native.c4_shutdown(null); var encryptedStr = (option & 1) == 1 ? "encrypted " : String.Empty; WriteLine($"Opening {encryptedStr} SQLite database"); C4Error err; var encryptionKey = new C4EncryptionKey(); if ((option & 1) == 1) { encryptionKey.algorithm = C4EncryptionAlgorithm.AES256; var i = 0; foreach (var b in Encoding.UTF8.GetBytes("this is not a random key at all.")) { encryptionKey.bytes[i++] = b; } } DBConfig2 = new C4DatabaseConfig2() { ParentDirectory = TestDir, flags = C4DatabaseFlags.Create | C4DatabaseFlags.SharedKeys, encryptionKey = encryptionKey }; LiteCoreBridge.Check(error => Native.c4db_deleteNamed(DBName, TestDir, error)); var config = DBConfig2; Db = Native.c4db_openNamed(DBName, &config, &err); ((long)Db).Should().NotBe(0, "because otherwise the database failed to open"); }
private C4Database *Reopen() { var forestPath = Path.Combine(Directory, DB_FILENAME); try { return((C4Database *)ForestDBBridge.Check(err => { var nativeKey = default(C4EncryptionKey); if (_encryptionKey != null) { nativeKey = new C4EncryptionKey(_encryptionKey.KeyData); } return Native.c4db_open(forestPath, _config, &nativeKey, err); })); } catch (CBForestException e) { if (e.Domain == C4ErrorDomain.ForestDB && e.Code == (int)ForestDBStatus.NoDbHeaders) { throw new CouchbaseLiteException(StatusCode.Unauthorized); } throw; } }
public static C4Database* c4db_open(C4Slice path, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError) { #if DEBUG var retVal = _c4db_open(path, flags, encryptionKey, outError); if(retVal != null) { _AllocatedObjects[(IntPtr)retVal] = "C4Database"; #if ENABLE_LOGGING Console.WriteLine("[c4db_open] Allocated 0x{0}", ((IntPtr)retVal).ToString("X")); #endif } return retVal; #else return _c4db_open(path, flags, encryptionKey, outError); #endif }
private static extern C4Database* _c4db_open(C4Slice path, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError);
/// <summary> /// Opens a view, or creates it if the file doesn't already exist. /// </summary> /// <param name="db">The database the view is associated with</param> /// <param name="path">The file that the view is stored in</param> /// <param name="viewName">The name of the view</param> /// <param name="version">The version of the view's map function</param> /// <param name="flags">The flags for opening the view file</param> /// <param name="encryptionKey">The option encryption key used to encrypt the database</param> /// <param name="outError">The error that occurred if the operation doesn't succeed</param> /// <returns>A pointer to the view on success, otherwise null</returns> public static C4View* c4view_open(C4Database *db, C4Slice path, C4Slice viewName, C4Slice version, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError) { #if DEBUG var retVal = _c4view_open(db, path, viewName, version, flags, encryptionKey, outError); if(retVal != null) { _AllocatedObjects.TryAdd((IntPtr)retVal, "C4View"); #if ENABLE_LOGGING Console.WriteLine("[c4view_open] Allocated 0x{0}", ((IntPtr)retVal).ToString("X")); #endif } return retVal; #else return _c4view_open(db, path, viewName, version, flags, encryptionKey, outError); #endif }
public static extern bool c4view_rekey(C4View *view, C4EncryptionKey *newKey, C4Error *outError);
/// <summary> /// Opens a view, or creates it if the file doesn't already exist. /// </summary> /// <param name="db">The database the view is associated with</param> /// <param name="path">The file that the view is stored in</param> /// <param name="viewName">The name of the view</param> /// <param name="version">The version of the view's map function</param> /// <param name="flags">The flags for opening the view file</param> /// <param name="encryptionKey">The option encryption key used to encrypt the database</param> /// <param name="outError">The error that occurred if the operation doesn't succeed</param> /// <returns>A pointer to the view on success, otherwise null</returns> public static C4View* c4view_open(C4Database *db, string path, string viewName, string version, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError) { using(var path_ = new C4String(path)) using(var viewName_ = new C4String(viewName)) using(var version_ = new C4String(version)) { return c4view_open(db, path_.AsC4Slice(), viewName_.AsC4Slice(), version_.AsC4Slice(), flags, encryptionKey, outError); } }
private static extern C4View* _c4view_open(C4Database *db, C4Slice path, C4Slice viewName, C4Slice version, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError);
private C4Database* Reopen() { var forestPath = Path.Combine(Directory, DB_FILENAME); try { return (C4Database*)ForestDBBridge.Check(err => { var nativeKey = default(C4EncryptionKey); if (_encryptionKey != null) { nativeKey = new C4EncryptionKey(_encryptionKey.KeyData); } return Native.c4db_open(forestPath, _config, &nativeKey, err); }); } catch(CBForestException e) { if (e.Domain == C4ErrorDomain.ForestDB && e.Code == (int)ForestDBStatus.NoDbHeaders) { throw new CouchbaseLiteException(StatusCode.Unauthorized); } throw; } }
public AtomicAction ActionToChangeEncryptionKey(SymmetricKey newKey) { var retVal = new AtomicAction(() => ForestDBBridge.Check(err => { var newc4key = default(C4EncryptionKey); if (newKey != null) { newc4key = new C4EncryptionKey(newKey.KeyData); } return Native.c4db_rekey(Forest, &newc4key, err); }), null, null); foreach (var viewName in GetAllViews()) { var store = GetViewStorage(viewName, false) as ForestDBViewStore; if (store == null) { continue; } retVal.AddLogic(store.ActionToChangeEncryptionKey(newKey)); } return retVal; }
/// <summary> /// Opens a database. /// </summary> /// <param name="path">The path to the DB file</param> /// <param name="readOnly">Whether or not the DB should be opened in read-only mode</param> /// <param name="encryptionKey">The option encryption key used to encrypt the database</param> /// <param name="outError">The error that occurred if the operation doesn't succeed</param> /// <returns>A database instance for use in the C4 API</returns> public static C4Database *c4db_open(string path, C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError) { using(var path_ = new C4String(path)) { return c4db_open(path_.AsC4Slice(), flags, encryptionKey, outError); } }
public static extern bool c4db_rekey(C4Database *db, C4EncryptionKey *newKey, C4Error *outError);
private C4Database* Reopen() { if(_encryptionKey != null) { Log.To.Database.I(TAG, "Database is encrypted; setting CBForest encryption key"); } var forestPath = Path.Combine(Directory, DB_FILENAME); try { return (C4Database*)ForestDBBridge.Check(err => { var nativeKey = default(C4EncryptionKey); if(_encryptionKey != null) { nativeKey = new C4EncryptionKey(_encryptionKey.KeyData); } return Native.c4db_open(forestPath, _config, &nativeKey, err); }); } catch(CBForestException e) { if(e.Domain == C4ErrorDomain.ForestDB && e.Code == (int)ForestDBStatus.NoDbHeaders) { throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.Unauthorized, TAG, "Failed to decrypt database, or it is corrupt"); } Log.To.Database.E(TAG, "Got exception while opening database, rethrowing..."); throw; } }