package cryptodbm
Encrypted layer over the dbm library: access to serverless, key-value databases with symmetric encryption.
Install
Dune Dependency
Authors
Maintainers
Sources
v0.84.2.tar.gz
sha256=388a4a8bf17c9ad0825907251720ba40291a19afb643f64066a29e813be50a7e
md5=7c33f55fca768501d06e2ef0eb583f80
doc/src/cryptodbm.internals/kinds.ml.html
Source file kinds.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
type location = | Table_Builtin | Subtable_Builtin of int | Subtable_User of int let max_subtable = 1 lsl 14 - 1 let loc2s = function | Table_Builtin -> "Table_Builtin" | Subtable_Builtin n -> "Subtable_Builtin " ^ (string_of_int n) | Subtable_User n -> "Subtable_User " ^ (string_of_int n) type 'a howstored = | Uncrypted | Encrypted of 'a (* Encrypting function. Only for KEYs. *) type key_kind = { key_loc : location ; key_how : (Cipher.passwd * Cipher.passwd * int) howstored ; cryptf : hidden } type data_kind = { data_how : (Cipher.passwd * int) howstored } let mk_data how = { data_how = how } (* Optimization: pre-compute encrypting functions when necessary. *) let encrypt_error _ = (Printf.printf "Unexpectedly calling encrypt_error in kinds.ml\n%!" ; assert false) let nocryptf = { table_encrypt = encrypt_error ; subtable_encrypt = encrypt_error } let mkcrypt p = if p == Cipher.empty_passwd then encrypt_error else begin (* Printf.printf "[[mkcrypt%!" ; *) let res = Cipher.encrypt ~passwd:p in (* Printf.printf "]]\n%!" ; *) res end let mk_key loc how = let cryptf = match how with | Uncrypted -> nocryptf | Encrypted (table_passwd, subtable_passwd, _) -> assert (not (table_passwd == Cipher.empty_passwd && subtable_passwd == Cipher.empty_passwd)) ; assert (loc <> Table_Builtin || subtable_passwd == Cipher.empty_passwd) ; { table_encrypt = mkcrypt table_passwd ; subtable_encrypt = mkcrypt subtable_passwd } in { key_loc = loc ; key_how = how ; cryptf } (* These are just regular strings. No boxing. *) type encoded_key = string type encoded_data = string let cmp_encoded_key ek1 ek2 = compare ek1 ek2 module LowerDB = LowerDB_impl (* Randomly choose the number of padding bytes for data. *) let choose_data_padding max_pad = Random.int (max_pad + 1) open Strings (* Encode the location as a string. * Table_builtin -> 0x11000000 * Subtable_Builtin -> 0x01...+subtable(14 bits) * Subtable_User -> 0x00...+subtable(14 bits) *) let put_location = function | Table_Builtin -> "\xc0" | Subtable_Builtin subt -> assert (subt >= 0 && subt <= max_subtable) ; insert16 "oo" 0 (0x4000 lor subt) | Subtable_User subt -> assert (subt >= 0 && subt <= max_subtable) ; insert16 "oo" 0 subt let loc2hash = put_location let get_location s = let len = String.length s in assert (len > 0) ; match s.[0] with | '\xc0' -> (Table_Builtin, String.sub s 1 (len-1)) | _ -> assert (len >= 2) ; let code = read16 s ~pos:0 in let subt = code land 0x3FFF and hd = (code land 0xc000) lsr 14 in let loc = match hd with | 0 -> Subtable_User subt | 1 -> Subtable_Builtin subt | _ -> assert false (* Incorrect encoding. *) in (loc, String.sub s 2 (len-2)) let encode_data data kind = match kind.data_how with | Uncrypted -> data | Encrypted (passwd, padlength) -> assert (passwd != Cipher.empty_passwd) ; let padded_data = if padlength = 0 then pad data 0 else pad data (choose_data_padding padlength) in Cipher.encrypt ~passwd padded_data let decode_data encdata kind = match kind.data_how with | Uncrypted -> encdata | Encrypted (passwd, _) -> assert (passwd != Cipher.empty_passwd) ; let paddata = Cipher.decrypt ~passwd encdata in unpad paddata let encode_key key kind = match kind.key_how with | Uncrypted -> append_char (put_location kind.key_loc ^ key) '0' | Encrypted (table_passwd, subtable_passwd, padlength) -> (* encrypted case => table_encryption(location ^ char ^ subtable_encryption(location? ^ pad(KEY))) ^ lastchar * location? is not needed if the subtable password is empty * lastchar is '1' (no table encryption) or '2' (table encryption) * char is 'E' (subtable has its own encryption), 'T' (subtable does not have its own encryption). *) assert (not (table_passwd == Cipher.empty_passwd && subtable_passwd == Cipher.empty_passwd)) ; assert (kind.key_loc <> Table_Builtin || subtable_passwd == Cipher.empty_passwd) ; (* pad(KEY) *) let padded_key = if padlength = 0 then pad key 0 else let passwd = if table_passwd == Cipher.empty_passwd then subtable_passwd else table_passwd in pad key (Cipher.compute_padding ~key ~passwd ~max_pad:padlength) in (* char ^ subtable_encryption(location ^ pad(KEY)) * char is 'E' or 'T' *) let subtable_key = (* Note also that if this is Table_Builtin key, subtable_passwd is empty. *) if subtable_passwd == Cipher.empty_passwd then padded_key else begin (* Printf.printf "((%!" ; *) let located = put_location kind.key_loc ^ padded_key in (* Printf.printf "----%!" ; *) let res = kind.cryptf.subtable_encrypt located in (* Printf.printf "))%!" ; *) res end in (* location ^ char ^ ... *) let located_key = let subtable_char = if subtable_passwd == Cipher.empty_passwd then 'T' else 'E' in (append_char (put_location kind.key_loc) subtable_char) ^ subtable_key in (* table_encryption(...) *) let table_key = if table_passwd == Cipher.empty_passwd then located_key else kind.cryptf.table_encrypt located_key in (* ... ^ '1' or '2' *) append_char table_key (if table_passwd == Cipher.empty_passwd then '1' else '2') let get_key_info passwd ~subt_pas enckey = let (last, rest_key) = get_last_char enckey in match last with | '0' -> (* Uncrypted case *) let (key_loc, key) = get_location rest_key in let kind = { key_loc ; key_how = Uncrypted ; cryptf = nocryptf } in Some (kind, Some key) (* Encrypted cases *) | '1' | '2' -> begin (* We should not find a table-uncrypted key when a table password was provided. *) assert (not (last = '1' && passwd != Cipher.empty_passwd)) ; try let table_key = if last = '1' then (* No table encryption *) rest_key else (* Table encryption *) if passwd == Cipher.empty_passwd then (* The table password is unknown. We can't say anything. *) raise Not_found else Cipher.decrypt ~passwd rest_key in let (loc, temp_key) = get_location table_key in let (subchar, subtable_key) = get_first_char temp_key in let (key, subpass) = begin match (loc, subchar) with | Table_Builtin, 'T' -> (Some (unpad subtable_key), Cipher.empty_passwd) | Table_Builtin, _ -> assert false (* Table_Builtin cannot be subtable-encrypted. *) | (Subtable_Builtin subt | Subtable_User subt), 'T' -> (Some (unpad subtable_key), Cipher.empty_passwd) | (Subtable_Builtin subt | Subtable_User subt), 'E' -> let subt_passwd = subt_pas subt in if subt_passwd == Cipher.empty_passwd then (* Don't have the password *) (None, Cipher.empty_passwd) else begin let inner_key = Cipher.decrypt ~passwd:subt_passwd subtable_key in let (loc2, padded_key) = get_location inner_key in assert (loc = loc2) ; (Some (unpad padded_key), subt_passwd) end | (Subtable_Builtin subt | Subtable_User subt), _ -> assert false (* Only 'T' or 'E' *) end in let kind = { key_loc = loc ; key_how = Encrypted (passwd, subpass, 0) ; cryptf = nocryptf } in Some (kind, key) with Not_found -> None end | _ -> assert false (* Incorrect encoding *) let sign passwd v = Cipher.digest ("$_" ^ Cipher.strong_passwd passwd ^ "\003M" ^ v ^ "=") let sign_encoded_key = sign let sign_encoded_data = sign let id x = x let encodedkey2s = id let encodeddata2s = id let s2encodedkey = id let s2encodeddata = id
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>