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;
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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();
            });
        }
示例#5
0
        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));
        }
示例#6
0
        /// <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));
            });
        }
示例#7
0
        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");
        }
示例#8
0
        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;
            }
        }
示例#9
0
        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
        }
示例#10
0
 private static extern C4Database* _c4db_open(C4Slice path, C4DatabaseFlags flags, 
     C4EncryptionKey *encryptionKey, C4Error *outError);
示例#11
0
        /// <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
        }
示例#12
0
 public static extern bool c4view_rekey(C4View *view, C4EncryptionKey *newKey, C4Error *outError);
示例#13
0
 /// <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);   
     }
 }
示例#14
0
 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;
        }
示例#17
0
 /// <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);
     }
 }
示例#18
0
 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;
            }
        }