Merge "Reinitialize KeyStore::mMasterKey after unlock (and add test-keystore)"
diff --git a/cmds/keystore/keystore.cpp b/cmds/keystore/keystore.cpp
index b48be6ef..bbd1a1b 100644
--- a/cmds/keystore/keystore.cpp
+++ b/cmds/keystore/keystore.cpp
@@ -363,6 +363,7 @@
                 response = writeMasterKey(pw);
             }
             if (response == NO_ERROR) {
+                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
                 setupMasterKeys();
             }
             return response;
diff --git a/cmds/keystore/test-keystore b/cmds/keystore/test-keystore
new file mode 100755
index 0000000..82b276f
--- /dev/null
+++ b/cmds/keystore/test-keystore
@@ -0,0 +1,272 @@
+#!/bin/bash
+#
+# Copyright 2011, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+prefix=$0
+log_file=$prefix.log
+baseline_file=$prefix.baseline
+
+function cleanup_output() {
+    rm -f $log_file
+    rm -f $baseline_file
+}
+
+function log() {
+    echo "$@"
+    append $log_file \# "$@"
+    append $baseline_file \# "$@"
+}
+
+function expect() {
+    append $baseline_file "$@"
+}
+
+function append() {
+    declare -r file=$1
+    shift
+    echo "$@" >> $file
+}
+
+function run() {
+    # strip out carriage returns from adb
+    # strip out date/time from ls -l
+    "$@" | tr --delete '\r' | sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2} +[0-9]{1,2}:[0-9]{2} //' >> $log_file
+}
+
+function keystore() {
+    declare -r user=$1
+    shift
+    run adb shell su $user keystore_cli "$@"
+}
+
+function list_keystore_directory() {
+    run adb shell ls -al /data/misc/keystore
+}
+
+function compare() {
+    log "comparing $baseline_file and $log_file"
+    diff $baseline_file $log_file || (log $tag FAILED && exit 1)
+}
+
+function test_basic() {
+
+    #
+    # reset
+    #
+    log "reset keystore as system user"
+    keystore system r
+    expect "1 No error"
+    list_keystore_directory
+
+    #
+    # basic tests as system/root
+    #
+    log "root does not have permission to run test"
+    keystore root t
+    expect "6 Permission denied"
+    
+    log "but system user does"
+    keystore system t
+    expect "3 Uninitialized"
+    list_keystore_directory
+
+    log "password is now bar"
+    keystore system p bar
+    expect "1 No error"
+    list_keystore_directory
+    expect "-rw------- keystore keystore       84 .masterkey"
+    
+    log "no error implies initialized and unlocked"
+    keystore system t
+    expect "1 No error"
+    
+    log "saw with no argument"
+    keystore system s
+    expect "5 Protocol error"
+
+    log "saw nothing"
+    keystore system s ""
+    expect "1 No error"
+
+    log "add key baz"
+    keystore system i baz quux
+    expect "1 No error"
+
+    log "1000 is uid of system"
+    list_keystore_directory
+    expect "-rw------- keystore keystore       84 .masterkey"
+    expect "-rw------- keystore keystore       52 1000_baz"
+
+    log "saw baz"
+    keystore system s ""
+    expect "1 No error"
+    expect "baz"
+
+    log "system does not have access to read any keys"
+    keystore system g baz
+    expect "6 Permission denied"
+    
+    log "however, root can read system user keys (as can wifi or vpn users)"
+    keystore root g baz
+    expect "1 No error"
+    expect "quux"
+
+    #
+    # app user tests
+    #
+
+    # app_0 has uid 10000, as seen below
+    log "other uses cannot see the system keys"
+    keystore app_0 g baz
+    expect "7 Key not found"
+    
+    log "app user cannot use reset, password, lock, unlock"
+    keystore app_0 r
+    expect "6 Permission denied"
+    keystore app_0 p
+    expect "6 Permission denied"
+    keystore app_0 l
+    expect "6 Permission denied"
+    keystore app_0 u
+    expect "6 Permission denied"
+
+    log "install app_0 key"
+    keystore app_0 i 0x deadbeef
+    expect 1 No error
+    list_keystore_directory
+    expect "-rw------- keystore keystore       84 .masterkey"
+    expect "-rw------- keystore keystore       52 10000_0x"
+    expect "-rw------- keystore keystore       52 1000_baz"
+
+    log "get with no argument"
+    keystore app_0 g
+    expect "5 Protocol error"
+    
+    keystore app_0 g 0x
+    expect "1 No error"
+    expect "deadbeef"
+    
+    keystore app_0 i fred barney
+    expect "1 No error"
+    
+    keystore app_0 s ""
+    expect "1 No error"
+    expect "0x"
+    expect "fred"
+
+    log "note that saw returns the suffix of prefix matches"
+    keystore app_0 s fr # fred
+    expect "1 No error"
+    expect "ed" # fred
+
+    #
+    # lock tests
+    #
+    log "lock the store as system"
+    keystore system l
+    expect "1 No error"
+    keystore system t
+    expect "2 Locked"
+    
+    log "saw works while locked"
+    keystore app_0 s ""
+    expect "1 No error"
+    expect "0x"
+    expect "fred"
+
+    log "...but cannot read keys..."
+    keystore app_0 g 0x
+    expect "2 Locked"
+    
+    log "...but they can be deleted."
+    keystore app_0 e 0x
+    expect "1 No error"
+    keystore app_0 d 0x
+    expect "1 No error"
+    keystore app_0 e 0x
+    expect "7 Key not found"
+
+    #
+    # password
+    #
+    log "wrong password"
+    keystore system u foo
+    expect "13 Wrong password (4 tries left)"
+    log "right password"
+    keystore system u bar
+    expect "1 No error"
+    
+    log "make the password foo"
+    keystore system p foo
+    expect "1 No error"
+    
+    #
+    # final reset
+    #
+    log "reset wipes everything for all users"
+    keystore system r
+    expect "1 No error"
+    list_keystore_directory
+    
+    keystore system t
+    expect "3 Uninitialized"
+
+}
+
+function test_4599735() {
+    # http://b/4599735
+    log "start regression test for b/4599735"
+    keystore system r
+    expect "1 No error"
+
+    keystore system p foo
+    expect "1 No error"
+
+    keystore system i baz quux
+    expect "1 No error"
+    
+    keystore root g baz
+    expect "1 No error"
+    expect "quux"
+
+    keystore system l
+    expect "1 No error"
+
+    keystore system p foo
+    expect "1 No error"
+
+    log "after unlock, regression led to result of '8 Value corrupted'"
+    keystore root g baz
+    expect "1 No error"
+    expect "quux"
+
+    keystore system r
+    expect "1 No error"
+    log "end regression test for b/4599735"
+}
+
+function main() {
+    cleanup_output
+    log $tag START
+    test_basic
+    test_4599735
+    compare
+    log $tag PASSED
+    cleanup_output
+}
+
+main