Overview
Comment: | Added verification system so that passwords are only updated if they currently contain a valid password |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d12f13c9776d4b5d96bd544188013f1a |
User & Date: | rkeene on 2016-03-15 18:28:46 |
Other Links: | manifest | tags |
Context
2016-03-15
| ||
18:32 | Added a "whoami" command to determine the current users check-in: 92d30d85bb user: rkeene tags: trunk | |
18:28 | Added verification system so that passwords are only updated if they currently contain a valid password check-in: d12f13c977 user: rkeene tags: trunk | |
2016-03-11
| ||
21:45 | Added README check-in: 47680a1e16 user: rkeene tags: trunk | |
Changes
Modified build/pre.sh from [7d2c051364] to [7789bf77c1].
︙ | ︙ | |||
16 17 18 19 20 21 22 | rm -rf lib if [ "$1" = 'clean' -o "$1" = 'distclean' ]; then exit 0 fi | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | rm -rf lib if [ "$1" = 'clean' -o "$1" = 'distclean' ]; then exit 0 fi "${TCLKIT:-tclkit}" "${ourdir}/teapot-client.kit" get . tcl tcl pki aes sha256 for platform in linux-ix86 linux-x86_64 macosx-ix86 macosx-x86_64 win32-ix86 win32-x86_64; do dl_platform="${platform}" vers='0.9.9' case "${platform}" in macosx-*) vers='0.9.6' |
︙ | ︙ |
Modified hunter2 from [7cb1f824eb] to [e039ea66c1].
︙ | ︙ | |||
100 101 102 103 104 105 106 107 108 109 110 111 112 113 | lappend ::auto_path [file join [file dirname [info script]] lib [platform::identify]] lappend ::auto_path [file join [file dirname [info script]] lib [platform::generic]] lappend ::auto_path [file join [file dirname [info script]] lib] package require pki package require pki::pkcs11 package require aes # Backports for older versions of "pki" proc ::pki::pkcs::parse_public_key {key {password ""}} { array set parsed_key [::pki::_parse_pem $key "-----BEGIN PUBLIC KEY-----" "-----END PUBLIC KEY-----" $password] set key_seq $parsed_key(data) | > | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | lappend ::auto_path [file join [file dirname [info script]] lib [platform::identify]] lappend ::auto_path [file join [file dirname [info script]] lib [platform::generic]] lappend ::auto_path [file join [file dirname [info script]] lib] package require pki package require pki::pkcs11 package require aes package require sha256 # Backports for older versions of "pki" proc ::pki::pkcs::parse_public_key {key {password ""}} { array set parsed_key [::pki::_parse_pem $key "-----BEGIN PUBLIC KEY-----" "-----END PUBLIC KEY-----" $password] set key_seq $parsed_key(data) |
︙ | ︙ | |||
203 204 205 206 207 208 209 210 211 212 213 214 | lappend slotInfo [list handle $handle id $slotID prompt $slotPromptForPIN cert $cert pubkey $pubkey] } } return $slotInfo } proc _addPassword {name password publicKeys} { set fd [open "/dev/urandom" r] fconfigure $fd -translation binary | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | > > > | | | > > > | > | 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 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | lappend slotInfo [list handle $handle id $slotID prompt $slotPromptForPIN cert $cert pubkey $pubkey] } } return $slotInfo } proc _verifyPassword {name password} { set publicKeys [list] db eval {SELECT publicKey, verification FROM passwords WHERE name = $name} row { set salt [dict get $row(verification) salt] set hashAlgorithm [dict get $row(verification) hashAlgorithm] set publicKey $row(publicKey) set plaintext "${salt}|${publicKey}|${password}" switch -- $hashAlgorithm { "sha256" { set verificationHash [sha2::sha256 -hex -- $plaintext] } default { return -code error "Unknown hashing algorithm: $hashAlgorithm" } } set row(verificationHash) [dict get $row(verification) hash] if {$verificationHash ne $row(verificationHash)} { puts stderr "FAILED: verification failed for $name with public key $publicKey -- it will not get the new password." continue } lappend publicKeys $publicKey } return $publicKeys } proc _addPassword {name password publicKeys} { set fd [open "/dev/urandom" r] fconfigure $fd -translation binary set keySize 16 # Pad the password with 0 bytes until it is a multiple of the key size set blockPassword $password append blockPassword [string repeat "\x00" [expr {-[string length $password] % $keySize}]] db transaction { db eval {DELETE FROM passwords WHERE name = $name;} foreach publicKey $publicKeys { set key [read $fd $keySize] if {[string length $key] != $keySize} { close $fd return -code error "ERROR: Short read from random device" } set salt [read $fd $keySize] set salt [binary encode base64 $salt] set publicKeyItem [::pki::pkcs::parse_public_key [binary decode base64 $publicKey]] set encryptedKey [binary encode base64 [::pki::encrypt -pub -binary -- $key $publicKeyItem]] set encryptedPass [binary encode base64 [::aes::aes -dir encrypt -key $key -- $blockPassword]] set verificationHash [sha2::sha256 -hex -- "${salt}|${publicKey}|${password}"] set verification [list salt $salt hashAlgorithm sha256 hash $verificationHash] db eval {INSERT INTO passwords (name, encryptedPass, encryptedKey, publicKey, verification) VALUES ($name, @encryptedPass, @encryptedKey, @publicKey, @verification);} } } close $fd } proc _prompt {prompt} { puts -nonewline $prompt |
︙ | ︙ | |||
277 278 279 280 281 282 283 | set prompted($slotInfo(id)) 1 } db eval {SELECT encryptedPass, encryptedKey FROM passwords WHERE name = $name AND publicKey = $pubkey;} row { set key [::pki::decrypt -binary -priv -- [binary decode base64 $row(encryptedKey)] $slotInfo(cert)] set password [::aes::aes -dir decrypt -key $key -- [binary decode base64 $row(encryptedPass)]] | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | set prompted($slotInfo(id)) 1 } db eval {SELECT encryptedPass, encryptedKey FROM passwords WHERE name = $name AND publicKey = $pubkey;} row { set key [::pki::decrypt -binary -priv -- [binary decode base64 $row(encryptedKey)] $slotInfo(cert)] set password [::aes::aes -dir decrypt -key $key -- [binary decode base64 $row(encryptedPass)]] return [string trimright $password "\x00"] } } return -code error "No valid keys" } proc _modifyPublicKeys {passwordName userNames sql} { |
︙ | ︙ | |||
452 453 454 455 456 457 458 | } proc updatePassword {passwordName password} { if {$password eq ""} { set password [_prompt "Please enter the new password: "] } | > | > | > > | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | } proc updatePassword {passwordName password} { if {$password eq ""} { set password [_prompt "Please enter the new password: "] } set oldPassword [_getPassword $passwordName] set publicKeys [_verifyPassword $passwordName $oldPassword] if {[llength $publicKeys] == 0} { puts stderr "Warning: This will delete the password since there are no valid public keys." } _addPassword $passwordName $password $publicKeys } proc deletePassword {passwordName} { db eval {DELETE FROM passwords WHERE name = $passwordName;} |
︙ | ︙ | |||
511 512 513 514 515 516 517 | ### MAIN sqlite3 db $passwordFile db eval { CREATE TABLE IF NOT EXISTS users(name, publicKey BLOB); | | | 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | ### MAIN sqlite3 db $passwordFile db eval { CREATE TABLE IF NOT EXISTS users(name, publicKey BLOB); CREATE TABLE IF NOT EXISTS passwords(name, encryptedPass BLOB, encryptedKey BLOB, publicKey BLOB, verification BLOB); } if {$action in $validCommands} { if {[catch { $action {*}$argv } error]} { puts stderr "Error: $error" |
︙ | ︙ |