mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-01 13:28:39 +09:00
61 lines
2.8 KiB
Swift
61 lines
2.8 KiB
Swift
#if SQLITE_SWIFT_SQLCIPHER
|
|
import SQLCipher
|
|
|
|
|
|
/// Extension methods for [SQLCipher](https://www.zetetic.net/sqlcipher/).
|
|
/// @see [sqlcipher api](https://www.zetetic.net/sqlcipher/sqlcipher-api/)
|
|
extension Connection {
|
|
|
|
/// Specify the key for an encrypted database. This routine should be
|
|
/// called right after sqlite3_open().
|
|
///
|
|
/// @param key The key to use.The key itself can be a passphrase, which is converted to a key
|
|
/// using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) key derivation. The result
|
|
/// is used as the encryption key for the database.
|
|
///
|
|
/// Alternatively, it is possible to specify an exact byte sequence using a blob literal.
|
|
/// With this method, it is the calling application's responsibility to ensure that the data
|
|
/// provided is a 64 character hex string, which will be converted directly to 32 bytes (256 bits)
|
|
/// of key data.
|
|
/// e.g. x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'
|
|
/// @param db name of the database, defaults to 'main'
|
|
public func key(_ key: String, db: String = "main") throws {
|
|
try _key_v2(db: db, keyPointer: key, keySize: key.utf8.count)
|
|
}
|
|
|
|
public func key(_ key: Blob, db: String = "main") throws {
|
|
try _key_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count)
|
|
}
|
|
|
|
|
|
/// Change the key on an open database. If the current database is not encrypted, this routine
|
|
/// will encrypt it.
|
|
/// To change the key on an existing encrypted database, it must first be unlocked with the
|
|
/// current encryption key. Once the database is readable and writeable, rekey can be used
|
|
/// to re-encrypt every page in the database with a new key.
|
|
public func rekey(_ key: String, db: String = "main") throws {
|
|
try _rekey_v2(db: db, keyPointer: key, keySize: key.utf8.count)
|
|
}
|
|
|
|
public func rekey(_ key: Blob, db: String = "main") throws {
|
|
try _rekey_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count)
|
|
}
|
|
|
|
// MARK: - private
|
|
private func _key_v2(db: String, keyPointer: UnsafePointer<UInt8>, keySize: Int) throws {
|
|
try check(sqlite3_key_v2(handle, db, keyPointer, Int32(keySize)))
|
|
try cipher_key_check()
|
|
}
|
|
|
|
private func _rekey_v2(db: String, keyPointer: UnsafePointer<UInt8>, keySize: Int) throws {
|
|
try check(sqlite3_rekey_v2(handle, db, keyPointer, Int32(keySize)))
|
|
}
|
|
|
|
// When opening an existing database, sqlite3_key_v2 will not immediately throw an error if
|
|
// the key provided is incorrect. To test that the database can be successfully opened with the
|
|
// provided key, it is necessary to perform some operation on the database (i.e. read from it).
|
|
private func cipher_key_check() throws {
|
|
try scalar("SELECT count(*) FROM sqlite_master;")
|
|
}
|
|
}
|
|
#endif
|