Skip to content

Commit 65bdece

Browse files
committed
Improvements to cevfs_build.
Avoid sqlite3HexToBlob as SQLite memory management hasn't been configured yet. Pass VFS name in as a parameter.
1 parent 60778a4 commit 65bdece

File tree

4 files changed

+83
-26
lines changed

4 files changed

+83
-26
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,19 @@ build> $ clang cevfs-all.c cevfs_build.c -O2 -o cevfs_build -lz
5656

5757
Then to create a CEVFS database:
5858
```
59-
./cevfs_build UNCOMPRESSED COMPRESSED KEY VFS_NAME
59+
./cevfs_build UNCOMPRESSED COMPRESSED VFS_NAME KEY
6060
```
6161

6262
parameters:
6363
- **UNCOMPRESSED**: path to uncompressed database
6464
- **COMPRESSED**: path to new compressed database
65-
- **KEY**: encryption key
6665
- **VFS_NAME**: name to embed in header (10 chars. max.)
66+
- **KEY**: encryption key
67+
68+
E.g.:
69+
```
70+
./cevfs_build myDatabase.db myNewDatabase.db default "x'2F3A995FCE317EA2...'"
71+
```
6772

6873
### Creating a Custom Version of SQLite
6974
It is helpful to have a custom command-line version of `sqlite3` on your development workstation for opening/testing your newly created databases.

cevfs/cevfs.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,14 +1770,18 @@ int cevfs_create_vfs(
17701770
return sqlite3_vfs_register(pNew, makeDefault);
17711771
}
17721772

1773+
static int _cevfs_destroy_vfs(sqlite3_vfs *pVfs) {
1774+
sqlite3_free(pVfs);
1775+
return SQLITE_OK;
1776+
}
1777+
17731778
int cevfs_destroy_vfs(const char *zName){
17741779
sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
17751780
if( pVfs ){
17761781
//cevfs_info *pInfo = (cevfs_info *)pVfs->pAppData;
1777-
sqlite3_free(pVfs);
1778-
return SQLITE_OK;
1782+
return _cevfs_destroy_vfs(pVfs);
17791783
}
1780-
return SQLITE_NOTFOUND;
1784+
return CEVFS_ERROR_VFS_DOES_NOT_EXIST;
17811785
}
17821786

17831787
int cevfs_build(
@@ -1858,12 +1862,11 @@ int cevfs_build(
18581862
}
18591863
}
18601864
}
1861-
}
1862-
}else{
1863-
rc = SQLITE_CORRUPT;
1865+
} else rc = SQLITE_CORRUPT;
18641866
}
18651867
}
1866-
}
1868+
} else rc = SQLITE_INTERNAL;
1869+
_cevfs_destroy_vfs(pDestVfs);
18671870
}
18681871
return rc;
18691872
}

cevfs/cevfs.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ SOFTWARE.
3535
#define CEVFS_ERROR_MALFORMED_KEY (CEVFS_ERROR | (2<<8))
3636
#define CEVFS_ERROR_EXT_VERSION_TOO_OLD (CEVFS_ERROR | (3<<8))
3737
#define CEVFS_ERROR_VFS_ALREADY_EXISTS (CEVFS_ERROR | (4<<8))
38-
#define CEVFS_ERROR_COMPRESSION_FAILED (CEVFS_ERROR | (5<<8))
39-
#define CEVFS_ERROR_DECOMPRESSION_FAILED (CEVFS_ERROR | (6<<8))
40-
#define CEVFS_ERROR_ENCRYPTION_FAILED (CEVFS_ERROR | (7<<8))
41-
#define CEVFS_ERROR_DECRYPTION_FAILED (CEVFS_ERROR | (8<<8))
38+
#define CEVFS_ERROR_VFS_DOES_NOT_EXIST (CEVFS_ERROR | (5<<8))
39+
#define CEVFS_ERROR_COMPRESSION_FAILED (CEVFS_ERROR | (6<<8))
40+
#define CEVFS_ERROR_DECOMPRESSION_FAILED (CEVFS_ERROR | (7<<8))
41+
#define CEVFS_ERROR_ENCRYPTION_FAILED (CEVFS_ERROR | (8<<8))
42+
#define CEVFS_ERROR_DECRYPTION_FAILED (CEVFS_ERROR | (9<<8))
4243

4344
struct CevfsMethods {
4445
void *pCtx;

cevfs_build/cevfs_build.c

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,38 +31,86 @@ SOFTWARE.
3131
#include "cevfs.h"
3232
#include "xMethods.c"
3333

34-
typedef uint8_t u8;
35-
3634
extern const char *fileTail(const char *z);
37-
extern void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n);
35+
typedef unsigned char u8;
36+
37+
/*
38+
** Taken from SQLite source code.
39+
** Check to see if this machine uses EBCDIC. (Yes, believe it or
40+
** not, there are still machines out there that use EBCDIC.)
41+
*/
42+
#if 'A' == '\301'
43+
# define SQLITE_EBCDIC 1
44+
#else
45+
# define SQLITE_ASCII 1
46+
#endif
47+
48+
/*
49+
** Taken from SQLite source code.
50+
** Translate a single byte of Hex into an integer.
51+
** This routine only works if h really is a valid hexadecimal
52+
** character: 0..9a..fA..F
53+
*/
54+
static u8 hexToInt(int h){
55+
assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
56+
#ifdef SQLITE_ASCII
57+
h += 9*(1&(h>>6));
58+
#endif
59+
#ifdef SQLITE_EBCDIC
60+
h += 9*(1&~(h>>4));
61+
#endif
62+
return (u8)(h & 0xf);
63+
}
64+
65+
/*
66+
** Taken from SQLite source code.
67+
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
68+
** value. Return a pointer to its binary value. Space to hold the
69+
** binary value has been obtained from malloc and must be freed by
70+
** the calling routine.
71+
*/
72+
static void *hexToBlob(const char *z, int n){
73+
char *zBlob;
74+
int i;
75+
76+
zBlob = (char *)malloc(n/2 + 1);
77+
n--;
78+
if( zBlob ){
79+
for(i=0; i<n; i+=2){
80+
zBlob[i/2] = (hexToInt(z[i])<<4) | hexToInt(z[i+1]);
81+
}
82+
zBlob[i/2] = 0;
83+
}
84+
return zBlob;
85+
}
86+
87+
// This context will be passed to xAutoDetect and the functions defined within.
88+
struct context ctx;
3889

3990
int main(int argc, const char * argv[]) {
40-
if( argc != 4 ){
91+
if( argc != 5 ){
4192
printf("Usage: %s UNCOMPRESSED COMPRESSED KEY\n", fileTail(argv[0]));
4293
printf(" UNCOMPRESSED: URI of uncompressed SQLite DB file.\n");
4394
printf(" COMPRESSED: URI of new compressed DB with optional ?block_size=<block_size>\n");
95+
printf(" VFS_NAME: Name of VFS to embed in database file.\n");
4496
printf(" KEY: Encryption key in the form: x'<hex1><hex2>...<hex32>'\n");
4597
return EXIT_FAILURE;
4698
}
4799

48100
int rc;
49101

50-
// This context will be passed to xAutoDetect and the functions defined within.
51-
struct context ctx;
52-
53102
// Convert encryption key string to hex blob.
54103
// This assumes that the key is in the form of x'<hex-string>'
55104
// You should, of course, implement proper error checking.
56-
const char *key = arvg[3]+2;
57-
char *keyBytes = sqlite3HexToBlob(NULL, key, strlen(key)-1);
105+
const char *key = argv[4]+2;
106+
char *keyBytes = hexToBlob(key, (int)strlen(key)-1);
58107

59108
ctx.pKey = keyBytes; // 32-bit encryption hex key
60109
ctx.nKeySz = kCCKeySizeAES256; // key size in bytes
61110
ctx.nIvSz = kCCBlockSizeAES128; // size of IV in bytes
62111

63-
// If you will be using the VFS name to determine how you set up your xMethods,
64-
// you may want to pass the VFS name as a command line parameter as well.
65-
// For now, we'll just pass "CEVFS-default".
66-
rc = cevfs_build(argv[1], argv[2], "CEVFS-default", &ctx, cevfsAutoDetect);
112+
// You can use the VFS name to determine how you set up your xMethods,
113+
// so we pass the VFS name as a command line parameter as well.
114+
rc = cevfs_build(argv[1], argv[2], argv[3], &ctx, cevfsAutoDetect);
67115
return rc;
68116
}

0 commit comments

Comments
 (0)