System.Data.SQLite
Check-in [acedfb1e11]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix rekey routine to skip the reserved locking page on databases over 1gb
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sourceforge
Files: files | file ages | folders
SHA1: acedfb1e11dfc60ad7619cca3feb61b99216f39a
User & Date: rmsimpson 2006-02-02 22:44:28
Context
2006-02-02
22:45
Post 3.3.3 code changes check-in: 67812ebd3a user: rmsimpson tags: sourceforge
22:44
Fix rekey routine to skip the reserved locking page on databases over 1gb check-in: acedfb1e11 user: rmsimpson tags: sourceforge
2006-01-31
19:11
1.0.25.0 check-in: c0022ffcbd user: rmsimpson tags: sourceforge
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SQLite.Interop/crypt.c.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
318
319
320
321
322
323
324
325

326
327
328
329
330

331
332
333
334
335
336
337
// space to hold it.
static LPCRYPTBLOCK CreateCryptBlock(HCRYPTKEY hKey, Pager *pager, LPCRYPTBLOCK pExisting)
{
  LPCRYPTBLOCK pBlock;

  if (!pExisting) // Creating a new cryptblock
  {
    pBlock = malloc(sizeof(CRYPTBLOCK));
    ZeroMemory(pBlock, sizeof(CRYPTBLOCK));
    pBlock->hReadKey = hKey;
    pBlock->hWriteKey = hKey;
  }
  else // Updating an existing cryptblock
  {
    pBlock = pExisting;
................................................................................

  pBlock->dwPageSize = (DWORD)pager->pageSize;
  pBlock->dwCryptSize = pBlock->dwPageSize;

  // Existing cryptblocks may have a buffer, if so, delete it
  if (pBlock->pvCrypt)
  {
    free(pBlock->pvCrypt);
    pBlock->pvCrypt = NULL;
  }

  // Figure out if this cryptographic key requires extra buffer space, and if so, allocate 
  // enough room for it
  if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &pBlock->dwCryptSize, pBlock->dwCryptSize * 2))
  {
    if (pBlock->dwCryptSize > pBlock->dwPageSize)
    {
      pBlock->pvCrypt = malloc(pBlock->dwCryptSize);
    }
  }
  return pBlock;
}

// Destroy a cryptographic context and any buffers and keys allocated therein
static void DestroyCryptBlock(LPCRYPTBLOCK pBlock)
................................................................................
  {
    CryptDestroyKey(pBlock->hWriteKey);
  }

  // If there's extra buffer space allocated, free it as well
  if (pBlock->pvCrypt)
  {
    free(pBlock->pvCrypt);
  }

  // All done with this cryptblock
  free(pBlock);
}

// Encrypt/Decrypt functionality, called by pager.c
void sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
................................................................................
  {
    if (pBlock->hReadKey)
      CryptDestroyKey(pBlock->hReadKey);
    if (pBlock->hWriteKey)
      CryptDestroyKey(pBlock->hWriteKey);

    if (pBlock->pvCrypt)
      free(pBlock->pvCrypt);
  }
  free(pBlock);
}

// Once a password has been supplied and a key created, we don't keep the 
// original password for security purposes.  Therefore return NULL.
void sqlite3CodecGetKey(sqlite3 *db, int nDb, void **ppKey, int *pnKeyLen)
{
  *ppKey = NULL;
................................................................................

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    int nPage = sqlite3pager_pagecount(p);

    void *pPage;
    int n;

    for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
    {

      rc = sqlite3pager_get(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3pager_write(pPage);
        sqlite3pager_unref(pPage);
      }
    }







|







 







|









|







 







|



|







 







|

|







 







|
>

|



>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
// space to hold it.
static LPCRYPTBLOCK CreateCryptBlock(HCRYPTKEY hKey, Pager *pager, LPCRYPTBLOCK pExisting)
{
  LPCRYPTBLOCK pBlock;

  if (!pExisting) // Creating a new cryptblock
  {
    pBlock = sqliteMalloc(sizeof(CRYPTBLOCK));
    ZeroMemory(pBlock, sizeof(CRYPTBLOCK));
    pBlock->hReadKey = hKey;
    pBlock->hWriteKey = hKey;
  }
  else // Updating an existing cryptblock
  {
    pBlock = pExisting;
................................................................................

  pBlock->dwPageSize = (DWORD)pager->pageSize;
  pBlock->dwCryptSize = pBlock->dwPageSize;

  // Existing cryptblocks may have a buffer, if so, delete it
  if (pBlock->pvCrypt)
  {
    sqliteFree(pBlock->pvCrypt);
    pBlock->pvCrypt = NULL;
  }

  // Figure out if this cryptographic key requires extra buffer space, and if so, allocate 
  // enough room for it
  if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &pBlock->dwCryptSize, pBlock->dwCryptSize * 2))
  {
    if (pBlock->dwCryptSize > pBlock->dwPageSize)
    {
      pBlock->pvCrypt = sqliteMalloc(pBlock->dwCryptSize);
    }
  }
  return pBlock;
}

// Destroy a cryptographic context and any buffers and keys allocated therein
static void DestroyCryptBlock(LPCRYPTBLOCK pBlock)
................................................................................
  {
    CryptDestroyKey(pBlock->hWriteKey);
  }

  // If there's extra buffer space allocated, free it as well
  if (pBlock->pvCrypt)
  {
    sqliteFree(pBlock->pvCrypt);
  }

  // All done with this cryptblock
  sqliteFree(pBlock);
}

// Encrypt/Decrypt functionality, called by pager.c
void sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
................................................................................
  {
    if (pBlock->hReadKey)
      CryptDestroyKey(pBlock->hReadKey);
    if (pBlock->hWriteKey)
      CryptDestroyKey(pBlock->hWriteKey);

    if (pBlock->pvCrypt)
      sqliteFree(pBlock->pvCrypt);
  }
  sqliteFree(pBlock);
}

// Once a password has been supplied and a key created, we don't keep the 
// original password for security purposes.  Therefore return NULL.
void sqlite3CodecGetKey(sqlite3 *db, int nDb, void **ppKey, int *pnKeyLen)
{
  *ppKey = NULL;
................................................................................

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage = sqlite3pager_pagecount(p);
    Pgno nSkip = PAGER_MJ_PGNO(p);
    void *pPage;
    Pgno n;

    for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
    {
      if (n == nSkip) continue;
      rc = sqlite3pager_get(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3pager_write(pPage);
        sqlite3pager_unref(pPage);
      }
    }