@@ -215,6 +215,14 @@ static void setTextMode(FILE *file, int isOutput){
215215/* True if the timer is enabled */
216216static int enableTimer = 0 ;
217217
218+ #ifdef SQLITE_HAS_CODEC
219+ /* Database encryption support
220+ * Types were defined according to sqlite3_key() prototype.
221+ */
222+ static void * encryption_key = NULL ;
223+ static int encryption_key_length = 0 ;
224+ #endif
225+
218226/* Return the current wall-clock time */
219227static sqlite3_int64 timeOfDay (void ){
220228 static sqlite3_vfs * clockVfs = 0 ;
@@ -10369,6 +10377,14 @@ static void open_db(ShellState *p, int keepAlive){
1036910377 }
1037010378 }
1037110379 globalDb = p -> db ;
10380+
10381+ #ifdef SQLITE_HAS_CODEC
10382+ if (encryption_key != NULL ) {
10383+ sqlite3_activate_see ("7bb07b8d471d642e" );
10384+ sqlite3_key (p -> db , encryption_key , encryption_key_length );
10385+ }
10386+ #endif
10387+
1037210388 if ( p -> db == 0 || SQLITE_OK != sqlite3_errcode (p -> db ) ){
1037310389 utf8_printf (stderr ,"Error: unable to open database \"%s\": %s\n" ,
1037410390 p -> zDbFilename , sqlite3_errmsg (p -> db ));
@@ -14883,6 +14899,9 @@ static const char zOptions[] =
1488314899#ifdef SQLITE_ENABLE_VFSTRACE
1488414900 " -vfstrace enable tracing of all VFS calls\n"
1488514901#endif
14902+ #ifdef SQLITE_HAS_CODEC
14903+ " -key hexvalue set encryption key (hexadecimal, no quotes)\n"
14904+ #endif
1488614905;
1488714906static void usage (int showDetail ){
1488814907 utf8_printf (stderr ,
@@ -14956,7 +14975,7 @@ static char *cmdline_option_value(int argc, char **argv, int i){
1495614975# endif
1495714976#endif
1495814977
14959- #if SQLITE_SHELL_IS_UTF8
14978+ #ifdef SQLITE_SHELL_IS_UTF8
1496014979int SQLITE_CDECL main (int argc , char * * argv ){
1496114980#else
1496214981int SQLITE_CDECL wmain (int argc , wchar_t * * wargv ){
@@ -15125,7 +15144,55 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1512515144#endif
1512615145 }else if ( strcmp (z ,"-append" )== 0 ){
1512715146 data .openMode = SHELL_OPEN_APPENDVFS ;
15128- }
15147+ } else if (strcmp (argv [i ], "-key" ) == 0 ) {
15148+ #ifdef SQLITE_HAS_CODEC
15149+ /* Process hex key from command-line.
15150+ ** Message to SQLite developers: your parsers are NOT robust!
15151+ */
15152+ unsigned int idx ;
15153+ unsigned int tmpLength ;
15154+
15155+ i ++ ;
15156+ /* compute key length */
15157+ idx = i ;
15158+ while ((argv [i ][idx ] != ' ' ) && (argv [i ][idx ] != '\x00' )) {
15159+ char c = (argv [i ][idx ]);
15160+ if (!((isdigit (c )) || ((c >= 'a' ) && (c <= 'f' )) || ((c >= 'A' ) && (c <= 'F' )))) {
15161+ fprintf (stderr , "Expecting hexadecimal values for encryption key!\r\n" );
15162+ return 1 ;
15163+ }
15164+ idx ++ ;
15165+ }
15166+ tmpLength = idx ;
15167+ if ((tmpLength % 2 ) != 0 ) {
15168+ fprintf (stderr , "Expecting an even number of characters for encryption key!\r\n" );
15169+ return 1 ;
15170+ }
15171+
15172+ /* allocate key memory */
15173+ encryption_key_length = tmpLength / 2 ;
15174+ encryption_key = malloc (encryption_key_length );
15175+ if (encryption_key == NULL ) {
15176+ fprintf (stderr , "Out of memory!\r\n" );
15177+ return 1 ;
15178+ }
15179+
15180+ /* convert hex string into values */
15181+ idx = 0 ;
15182+ while ((argv [i ][idx ] != ' ' ) && (argv [i ][idx ] != '\x00' )) {
15183+ char hex [3 ];
15184+ hex [0 ] = (argv [i ][idx ++ ]);
15185+ hex [1 ] = (argv [i ][idx ++ ]);
15186+ hex [2 ] = '\x00' ;
15187+
15188+ ((unsigned char * )encryption_key )[(idx - 2 ) / 2 ] = (unsigned char )(0xFF & strtoul (hex , NULL , 16 ));
15189+ }
15190+ #else
15191+ fprintf (stderr , "Sorry, encryption support is not available\r\n" );
15192+ fprintf (stderr , "HINT: define 'SQLITE_HAS_CODEC' at compile time\r\n" );
15193+ return 1 ;
15194+ #endif
15195+ }
1512915196 }
1513015197 if ( data .zDbFilename == 0 ){
1513115198#ifndef SQLITE_OMIT_MEMORYDB
@@ -15270,6 +15337,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1527015337 if ( bail_on_error ) return rc ;
1527115338 }
1527215339 }
15340+ #ifdef SQLITE_HAS_CODEC
15341+ } else if (strcmp (z , "-key" ) == 0 ) {
15342+ /* encryption key has already been set */
15343+ i ++ ;
15344+ #endif
1527315345 }else {
1527415346 utf8_printf (stderr ,"%s: Error: unknown option: %s\n" , Argv0 , z );
1527515347 raw_printf (stderr ,"Use -help for a list of options.\n" );
@@ -15355,5 +15427,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
1535515427 for (i = 0 ; i < argc ; i ++ ) sqlite3_free (argv [i ]);
1535615428 sqlite3_free (argv );
1535715429#endif
15430+
15431+ #ifdef SQLITE_HAS_CODEC
15432+ if (encryption_key != NULL ) {
15433+ free (encryption_key );
15434+ encryption_key = NULL ;
15435+ }
15436+ #endif
15437+
1535815438 return rc ;
1535915439}
0 commit comments