1 // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
2 //
3 // Use of this source code is governed by an MIT-style
4 // license that can be found in the LICENSE file.
5 6 package sqlite3
7 8 import (
9 "crypto/sha1"
10 "crypto/sha256"
11 "crypto/sha512"
12 )
13 14 // This file provides several different implementations for the
15 // default embedded sqlite_crypt function.
16 // This function is uses a caesar-cypher by default
17 // and is used within the UserAuthentication module to encode
18 // the password.
19 //
20 // The provided functions can be used as an overload to the sqlite_crypt
21 // function through the use of the RegisterFunc on the connection.
22 //
23 // Because the functions can serv a purpose to an end-user
24 // without using the UserAuthentication module
25 // the functions are default compiled in.
26 //
27 // From SQLITE3 - user-auth.txt
28 // The sqlite_user.pw field is encoded by a built-in SQL function
29 // "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument
30 // is the plaintext password supplied to the sqlite3_user_authenticate()
31 // interface. The second argument is the sqlite_user.pw value and is supplied
32 // so that the function can extract the "salt" used by the password encoder.
33 // The result of sqlite_crypt(X,Y) is another blob which is the value that
34 // ends up being stored in sqlite_user.pw. To verify credentials X supplied
35 // by the sqlite3_user_authenticate() routine, SQLite runs:
36 //
37 // sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw)
38 //
39 // To compute an appropriate sqlite_user.pw value from a new or modified
40 // password X, sqlite_crypt(X,NULL) is run. A new random salt is selected
41 // when the second argument is NULL.
42 //
43 // The built-in version of of sqlite_crypt() uses a simple Caesar-cypher
44 // which prevents passwords from being revealed by searching the raw database
45 // for ASCII text, but is otherwise trivally broken. For better password
46 // security, the database should be encrypted using the SQLite Encryption
47 // Extension or similar technology. Or, the application can use the
48 // sqlite3_create_function() interface to provide an alternative
49 // implementation of sqlite_crypt() that computes a stronger password hash,
50 // perhaps using a cryptographic hash function like SHA1.
51 52 // CryptEncoderSHA1 encodes a password with SHA1
53 func CryptEncoderSHA1(pass []byte, hash any) []byte {
54 h := sha1.Sum(pass)
55 return h[:]
56 }
57 58 // CryptEncoderSSHA1 encodes a password with SHA1 with the
59 // configured salt.
60 func CryptEncoderSSHA1(salt string) func(pass []byte, hash any) []byte {
61 return func(pass []byte, hash any) []byte {
62 s := []byte(salt)
63 p := append(pass, s...)
64 h := sha1.Sum(p)
65 return h[:]
66 }
67 }
68 69 // CryptEncoderSHA256 encodes a password with SHA256
70 func CryptEncoderSHA256(pass []byte, hash any) []byte {
71 h := sha256.Sum256(pass)
72 return h[:]
73 }
74 75 // CryptEncoderSSHA256 encodes a password with SHA256
76 // with the configured salt
77 func CryptEncoderSSHA256(salt string) func(pass []byte, hash any) []byte {
78 return func(pass []byte, hash any) []byte {
79 s := []byte(salt)
80 p := append(pass, s...)
81 h := sha256.Sum256(p)
82 return h[:]
83 }
84 }
85 86 // CryptEncoderSHA384 encodes a password with SHA384
87 func CryptEncoderSHA384(pass []byte, hash any) []byte {
88 h := sha512.Sum384(pass)
89 return h[:]
90 }
91 92 // CryptEncoderSSHA384 encodes a password with SHA384
93 // with the configured salt
94 func CryptEncoderSSHA384(salt string) func(pass []byte, hash any) []byte {
95 return func(pass []byte, hash any) []byte {
96 s := []byte(salt)
97 p := append(pass, s...)
98 h := sha512.Sum384(p)
99 return h[:]
100 }
101 }
102 103 // CryptEncoderSHA512 encodes a password with SHA512
104 func CryptEncoderSHA512(pass []byte, hash any) []byte {
105 h := sha512.Sum512(pass)
106 return h[:]
107 }
108 109 // CryptEncoderSSHA512 encodes a password with SHA512
110 // with the configured salt
111 func CryptEncoderSSHA512(salt string) func(pass []byte, hash any) []byte {
112 return func(pass []byte, hash any) []byte {
113 s := []byte(salt)
114 p := append(pass, s...)
115 h := sha512.Sum512(p)
116 return h[:]
117 }
118 }
119 120 // EOF
121