Add SQLCipher _key DSN support
Some checks failed
Go / Test (1.24, macos-latest) (push) Has been cancelled
Go / Test (1.24, ubuntu-latest) (push) Has been cancelled
Go / Test (1.25, macos-latest) (push) Has been cancelled
Go / Test (1.25, ubuntu-latest) (push) Has been cancelled
Go / Test (1.26, macos-latest) (push) Has been cancelled
Go / Test (1.26, ubuntu-latest) (push) Has been cancelled
Go / Test for Windows (1.24) (push) Has been cancelled
Go / Test for Windows (1.25) (push) Has been cancelled
Go / Test for Windows (1.26) (push) Has been cancelled
dockerfile / Run Dockerfiles in examples (push) Has been cancelled
Some checks failed
Go / Test (1.24, macos-latest) (push) Has been cancelled
Go / Test (1.24, ubuntu-latest) (push) Has been cancelled
Go / Test (1.25, macos-latest) (push) Has been cancelled
Go / Test (1.25, ubuntu-latest) (push) Has been cancelled
Go / Test (1.26, macos-latest) (push) Has been cancelled
Go / Test (1.26, ubuntu-latest) (push) Has been cancelled
Go / Test for Windows (1.24) (push) Has been cancelled
Go / Test for Windows (1.25) (push) Has been cancelled
Go / Test for Windows (1.26) (push) Has been cancelled
dockerfile / Run Dockerfiles in examples (push) Has been cancelled
This commit is contained in:
97
sqlite3_sqlcipher_test.go
Normal file
97
sqlite3_sqlcipher_test.go
Normal file
@@ -0,0 +1,97 @@
|
||||
//go:build libsqlite3 && sqlcipher
|
||||
// +build libsqlite3,sqlcipher
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const sqlCipherTestRawKey = "x'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'"
|
||||
|
||||
func requireSQLCipher(t *testing.T, db *sql.DB) {
|
||||
t.Helper()
|
||||
var version string
|
||||
if err := db.QueryRow("PRAGMA cipher_version").Scan(&version); err != nil || version == "" {
|
||||
t.Fatalf("SQLCipher is required for this test; link it with -tags libsqlite3: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLCipherKeyDSN(t *testing.T) {
|
||||
filename := TempFilename(t)
|
||||
defer os.Remove(filename)
|
||||
|
||||
dsn := "file:" + filename + "?_key=" + url.QueryEscape(sqlCipherTestRawKey)
|
||||
db, err := sql.Open("sqlite3", dsn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
requireSQLCipher(t, db)
|
||||
if _, err := db.Exec("CREATE TABLE test (value TEXT)"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := db.Exec("INSERT INTO test VALUES ('encrypted')"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
db, err = sql.Open("sqlite3", dsn)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var value string
|
||||
if err := db.QueryRow("SELECT value FROM test").Scan(&value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if value != "encrypted" {
|
||||
t.Fatalf("value = %q; want encrypted", value)
|
||||
}
|
||||
if err := db.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, key := range []string{
|
||||
"x'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'",
|
||||
"",
|
||||
} {
|
||||
db, err = sql.Open("sqlite3", "file:"+filename+"?_key="+url.QueryEscape(key))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var count int
|
||||
err = db.QueryRow("SELECT count(*) FROM test").Scan(&count)
|
||||
db.Close()
|
||||
if err == nil {
|
||||
t.Errorf("reading encrypted database with key %q succeeded", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLCipherKeyAbsentPreservesSQLiteBehavior(t *testing.T) {
|
||||
filename := TempFilename(t)
|
||||
defer os.Remove(filename)
|
||||
|
||||
db, err := sql.Open("sqlite3", filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
if _, err := db.Exec("CREATE TABLE test (value TEXT)"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := db.Exec("INSERT INTO test VALUES ('plain')"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var value string
|
||||
if err := db.QueryRow("SELECT value FROM test").Scan(&value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if value != "plain" {
|
||||
t.Fatalf("value = %q; want plain", value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user