@@ -223,6 +223,14 @@ static void setTextMode(FILE *file, int isOutput){
223223/* True if the timer is enabled */
224224static int enableTimer = 0 ;
225225
226+ #ifdef SQLITE_HAS_CODEC
227+ /* Database encryption support
228+ * Types were defined according to sqlite3_key() prototype.
229+ */
230+ static void * encryption_key = NULL ;
231+ static int encryption_key_length = 0 ;
232+ #endif
233+
226234/* Return the current wall-clock time */
227235static sqlite3_int64 timeOfDay (void ){
228236 static sqlite3_vfs * clockVfs = 0 ;
@@ -11038,6 +11046,14 @@ static void open_db(ShellState *p, int keepAlive){
1103811046 }
1103911047 }
1104011048 globalDb = p -> db ;
11049+
11050+ #ifdef SQLITE_HAS_CODEC
11051+ if (encryption_key != NULL ) {
11052+ sqlite3_activate_see ("7bb07b8d471d642e" );
11053+ sqlite3_key (p -> db , encryption_key , encryption_key_length );
11054+ }
11055+ #endif
11056+
1104111057 if ( p -> db == 0 || SQLITE_OK != sqlite3_errcode (p -> db ) ){
1104211058 utf8_printf (stderr ,"Error: unable to open database \"%s\": %s\n" ,
1104311059 p -> zDbFilename , sqlite3_errmsg (p -> db ));
@@ -15611,6 +15627,9 @@ static const char zOptions[] =
1561115627#ifdef SQLITE_ENABLE_VFSTRACE
1561215628 " -vfstrace enable tracing of all VFS calls\n"
1561315629#endif
15630+ #ifdef SQLITE_HAS_CODEC
15631+ " -key hexvalue set encryption key (hexadecimal, no quotes)\n"
15632+ #endif
1561415633#ifdef SQLITE_HAVE_ZLIB
1561515634 " -zip open the file as a ZIP Archive\n"
1561615635#endif
@@ -15876,6 +15895,55 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1587615895 data .openMode = SHELL_OPEN_APPENDVFS ;
1587715896 }else if ( strcmp (z ,"-readonly" )== 0 ){
1587815897 data .openMode = SHELL_OPEN_READONLY ;
15898+
15899+ }else if (strcmp (argv [i ], "-key" ) == 0 ) {
15900+ #ifdef SQLITE_HAS_CODEC
15901+ /* Process hex key from command-line.
15902+ ** Message to SQLite developers: your parsers are NOT robust!
15903+ */
15904+ unsigned int idx ;
15905+ unsigned int tmpLength ;
15906+
15907+ i ++ ;
15908+ /* compute key length */
15909+ idx = i ;
15910+ while ((argv [i ][idx ] != ' ' ) && (argv [i ][idx ] != '\x00' )) {
15911+ char c = (argv [i ][idx ]);
15912+ if (!((isdigit (c )) || ((c >= 'a' ) && (c <= 'f' )) || ((c >= 'A' ) && (c <= 'F' )))) {
15913+ fprintf (stderr , "Expecting hexadecimal values for encryption key!\r\n" );
15914+ return 1 ;
15915+ }
15916+ idx ++ ;
15917+ }
15918+ tmpLength = idx ;
15919+ if ((tmpLength % 2 ) != 0 ) {
15920+ fprintf (stderr , "Expecting an even number of characters for encryption key!\r\n" );
15921+ return 1 ;
15922+ }
15923+
15924+ /* allocate key memory */
15925+ encryption_key_length = tmpLength / 2 ;
15926+ encryption_key = malloc (encryption_key_length );
15927+ if (encryption_key == NULL ) {
15928+ fprintf (stderr , "Out of memory!\r\n" );
15929+ return 1 ;
15930+ }
15931+
15932+ /* convert hex string into values */
15933+ idx = 0 ;
15934+ while ((argv [i ][idx ] != ' ' ) && (argv [i ][idx ] != '\x00' )) {
15935+ char hex [3 ];
15936+ hex [0 ] = (argv [i ][idx ++ ]);
15937+ hex [1 ] = (argv [i ][idx ++ ]);
15938+ hex [2 ] = '\x00' ;
15939+
15940+ ((unsigned char * )encryption_key )[(idx - 2 ) / 2 ] = (unsigned char )(0xFF & strtoul (hex , NULL , 16 ));
15941+ }
15942+ #else
15943+ fprintf (stderr , "Sorry, encryption support is not available\r\n" );
15944+ fprintf (stderr , "HINT: define 'SQLITE_HAS_CODEC' at compile time\r\n" );
15945+ return 1 ;
15946+ #endif
1587915947#if !defined(SQLITE_OMIT_VIRTUALTABLE ) && defined(SQLITE_HAVE_ZLIB )
1588015948 }else if ( strncmp (z , "-A" ,2 )== 0 ){
1588115949 /* All remaining command-line arguments are passed to the ".archive"
@@ -16029,6 +16097,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1602916097 if ( bail_on_error ) return rc ;
1603016098 }
1603116099 }
16100+
16101+ #ifdef SQLITE_HAS_CODEC
16102+ }
16103+ else if (strcmp (z , "-key" ) == 0 ) {
16104+ /* encryption key has already been set */
16105+ i ++ ;
16106+ #endif
16107+
1603216108#if !defined(SQLITE_OMIT_VIRTUALTABLE ) && defined(SQLITE_HAVE_ZLIB )
1603316109 }else if ( strncmp (z , "-A" , 2 )== 0 ){
1603416110 if ( nCmd > 0 ){
@@ -16131,5 +16207,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1613116207 for (i = 0 ; i < argc ; i ++ ) free (argv [i ]);
1613216208 free (argv );
1613316209#endif
16210+
16211+ #ifdef SQLITE_HAS_CODEC
16212+ if (encryption_key != NULL ) {
16213+ free (encryption_key );
16214+ encryption_key = NULL ;
16215+ }
16216+ #endif
16217+
1613416218 return rc ;
1613516219}
0 commit comments