Example #1
0
int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
  struct Db *pDb = &db->aDb[nDb];

  CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, zKey, nKey));

  sqlcipher_activate();

  if(nKey && zKey && pDb->pBt) {
    int rc;
    Pager *pPager = pDb->pBt->pBt->pPager;
    sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
    codec_ctx *ctx;

    /* point the internal codec argument against the contet to be prepared */
    rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey); 

    sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);

    codec_set_btree_to_codec_pagesize(db, pDb, ctx);

    /* if fd is null, then this is an in-memory database and
       we dont' want to overwrite the AutoVacuum settings
       if not null, then set to the default */
    sqlite3_mutex_enter(db->mutex);
    if(fd != NULL) { 
      sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
    }
    sqlite3_mutex_leave(db->mutex);
  }
  return SQLITE_OK;
}
Example #2
0
int codec_set_page_size(sqlite3* db, int nDb, int size) {
  struct Db *pDb = &db->aDb[nDb];
  CODEC_TRACE(("codec_set_page_size: entered db=%d nDb=%d size=%d\n", db, nDb, size));

  if(pDb->pBt) {
    int rc;
    codec_ctx *ctx;
    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);

    rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
    if(rc != SQLITE_OK) return rc;

    return codec_set_btree_to_codec_pagesize(db, pDb, ctx);
  }
  return SQLITE_ERROR;
}
Example #3
0
int codec_set_use_hmac(sqlite3* db, int nDb, int use) {
  struct Db *pDb = &db->aDb[nDb];

  CODEC_TRACE(("codec_set_use_hmac: entered db=%d nDb=%d use=%d\n", db, nDb, use));

  if(pDb->pBt) {
    int rc;
    codec_ctx *ctx;
    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);

    rc = sqlcipher_codec_ctx_set_use_hmac(ctx, use);
    if(rc != SQLITE_OK) return rc;

    /* since the use of hmac has changed, the page size may also change */
    /* Note: before forcing the page size we need to force pageSizeFixed to 0, else  
             sqliteBtreeSetPageSize will block the change  */
    return codec_set_btree_to_codec_pagesize(db, pDb, ctx);
  }
  return SQLITE_ERROR;
}
Example #4
0
int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
  struct Db *pDb = &db->aDb[nDb];

  CODEC_TRACE(("sqlite3CodecAttach: entered nDb=%d zKey=%s, nKey=%d\n", nDb, (char *)zKey, nKey));


  if(nKey && zKey && pDb->pBt) {
    int rc;
    Pager *pPager = pDb->pBt->pBt->pPager;
    sqlite3_file *fd = sqlite3Pager_get_fd(pPager);
    codec_ctx *ctx;

    sqlcipher_activate(); /* perform internal initialization for sqlcipher */

    sqlite3_mutex_enter(db->mutex);

    /* point the internal codec argument against the contet to be prepared */
    rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, fd, zKey, nKey); 

    if(rc != SQLITE_OK) return rc; /* initialization failed, do not attach potentially corrupted context */

    sqlite3pager_sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx);

    codec_set_btree_to_codec_pagesize(db, pDb, ctx);

    /* force secure delete. This has the benefit of wiping internal data when deleted
       and also ensures that all pages are written to disk (i.e. not skipped by
       sqlite3PagerDontWrite optimizations) */ 
    sqlite3BtreeSecureDelete(pDb->pBt, 1); 

    /* if fd is null, then this is an in-memory database and
       we dont' want to overwrite the AutoVacuum settings
       if not null, then set to the default */
    if(fd != NULL) { 
      sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM);
    }
    sqlite3_mutex_leave(db->mutex);
  }
  return SQLITE_OK;
}
Example #5
0
int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
  struct Db *pDb = &db->aDb[iDb];
  codec_ctx *ctx = NULL;
  int rc;

  if(pDb->pBt) {
    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
  }

  CODEC_TRACE(("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, iDb, pParse, zLeft, zRight, ctx));
  
  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
    sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
  } else
  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
    char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
    codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
    sqlite3_free(store_pass_value);
  }
  if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
      char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
      codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
      sqlite3_free(profile_status);
  } else
  if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
    if(ctx) {
      char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
      codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
      sqlite3_free(add_random_status);
    }
  } else
  if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){
    if(ctx){
      char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
      codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
      sqlite3_free(migrate_status);
    }
  } else
  if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
    if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
                                              sqlcipher_codec_get_cipher_provider(ctx));
    }
  } else
  if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){
    codec_vdbe_return_static_string(pParse, "cipher_version", codec_get_cipher_version());
  }else
  if( sqlite3StrICmp(zLeft, "cipher")==0 ){
    if(ctx) {
      if( zRight ) {
        sqlcipher_codec_ctx_set_cipher(ctx, zRight, 2); // change cipher for both
      }else {
        codec_vdbe_return_static_string(pParse, "cipher",
          sqlcipher_codec_ctx_get_cipher(ctx, 2));
      }
    }
  }else
  if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
    if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only 
  }else
  if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
    if( zRight ) {
      sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
    } else {
      char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
      codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
      sqlite3_free(kdf_iter);
    }
  }else
  if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
    if(ctx) {
      if( zRight ) {
        sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
      } else {
        char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx, 2));
        codec_vdbe_return_static_string(pParse, "kdf_iter", kdf_iter);
        sqlite3_free(kdf_iter);
      }
    }
  }else
  if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){
    if(ctx) {
      if( zRight ) {
        sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration 
      } else {
        char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx, 2));
        codec_vdbe_return_static_string(pParse, "fast_kdf_iter", fast_kdf_iter);
        sqlite3_free(fast_kdf_iter);
      }
    }
  }else
  if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
    if(ctx) sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 1); // write iterations only
  }else
  if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
    if(ctx) {
      if( zRight ) {
        int size = atoi(zRight);
        rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
      } else {
        char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx));
        codec_vdbe_return_static_string(pParse, "cipher_page_size", page_size);
        sqlite3_free(page_size);
      }
    }
  }else
  if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
    if( zRight ) {
      sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
    } else {
      char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac());
      codec_vdbe_return_static_string(pParse, "cipher_default_use_hmac", default_use_hmac);
      sqlite3_free(default_use_hmac);
    }
  }else
  if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){
    if(ctx) {
      if( zRight ) {
        rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1));
        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
        /* since the use of hmac has changed, the page size may also change */
        rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
        if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
      } else {
        char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx, 2));
        codec_vdbe_return_static_string(pParse, "cipher_use_hmac", hmac_flag);
        sqlite3_free(hmac_flag);
      }
    }
  }else
  if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){
    if(ctx) {
      if(zRight) {
        // clear both pgno endian flags
        if(sqlite3StrICmp(zRight, "le") == 0) {
          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO);
        } else if(sqlite3StrICmp(zRight, "be") == 0) {
          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
          sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO);
        } else if(sqlite3StrICmp(zRight, "native") == 0) {
          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO);
          sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO);
        }
      } else {
        if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO, 2)) {
          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "le");
        } else if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_BE_PGNO, 2)) {
          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "be");
        } else {
          codec_vdbe_return_static_string(pParse, "cipher_hmac_pgno", "native");
        }
      }
    }
  }else
  if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){
    if(ctx) {
      if(zRight) {
        if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
          unsigned char mask = 0;
          const unsigned char *hex = (const unsigned char *)zRight+2;
          cipher_hex2bin(hex,2,&mask);
          sqlcipher_set_hmac_salt_mask(mask);
        }
      } else {
          char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask());
          codec_vdbe_return_static_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask);
          sqlite3_free(hmac_salt_mask);
      }
    }
  }else {
    return 0;
  }
  return 1;
}