summaryrefslogtreecommitdiff
path: root/keystore/keystore.h
blob: b15d00f4ff7767fad1868fe79be9d319e7200e1e (plain)
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
/*
 * Copyright (C) 2016 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.
 */

#ifndef KEYSTORE_KEYSTORE_H_
#define KEYSTORE_KEYSTORE_H_

#include "user_state.h"

#include <hardware/keymaster2.h>

#include <utils/Vector.h>

#include "blob.h"

typedef struct {
    uint32_t uid;
    const uint8_t* filename;
} grant_t;

class KeyStore {
  public:
    KeyStore(Entropy* entropy, keymaster2_device_t* device, keymaster2_device_t* fallback);
    ~KeyStore();

    keymaster2_device_t* getDevice() const { return mDevice; }

    keymaster2_device_t* getFallbackDevice() const { return mFallbackDevice; }

    keymaster2_device_t* getDeviceForBlob(const Blob& blob) const {
        return blob.isFallback() ? mFallbackDevice : mDevice;
    }

    ResponseCode initialize();

    State getState(uid_t userId) { return getUserState(userId)->getState(); }

    ResponseCode initializeUser(const android::String8& pw, uid_t userId);

    ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser);
    ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
    ResponseCode readMasterKey(const android::String8& pw, uid_t userId);

    android::String8 getKeyName(const android::String8& keyName);
    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid);
    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid);

    /*
     * Delete entries owned by userId. If keepUnencryptedEntries is true
     * then only encrypted entries will be removed, otherwise all entries will
     * be removed.
     */
    void resetUser(uid_t userId, bool keepUnenryptedEntries);
    bool isEmpty(uid_t userId) const;

    void lock(uid_t userId);

    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId);
    ResponseCode put(const char* filename, Blob* keyBlob, uid_t userId);
    ResponseCode del(const char* filename, const BlobType type, uid_t userId);
    ResponseCode list(const android::String8& prefix, android::Vector<android::String16>* matches,
                      uid_t userId);

    void addGrant(const char* filename, uid_t granteeUid);
    bool removeGrant(const char* filename, uid_t granteeUid);
    bool hasGrant(const char* filename, const uid_t uid) const {
        return getGrant(filename, uid) != NULL;
    }

    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId,
                           int32_t flags);

    bool isHardwareBacked(const android::String16& keyType) const;

    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
                               const BlobType type);

    /**
     * Returns any existing UserState or creates it if it doesn't exist.
     */
    UserState* getUserState(uid_t userId);

    /**
     * Returns any existing UserState or creates it if it doesn't exist.
     */
    UserState* getUserStateByUid(uid_t uid);

    /**
     * Returns NULL if the UserState doesn't already exist.
     */
    const UserState* getUserState(uid_t userId) const;

    /**
     * Returns NULL if the UserState doesn't already exist.
     */
    const UserState* getUserStateByUid(uid_t uid) const;

  private:
    static const char* sOldMasterKey;
    static const char* sMetaDataFile;
    static const android::String16 sRSAKeyType;
    Entropy* mEntropy;

    keymaster2_device_t* mDevice;
    keymaster2_device_t* mFallbackDevice;

    android::Vector<UserState*> mMasterKeys;

    android::Vector<grant_t*> mGrants;

    typedef struct { uint32_t version; } keystore_metadata_t;

    keystore_metadata_t mMetaData;

    const grant_t* getGrant(const char* filename, uid_t uid) const;

    /**
     * Upgrade the key from the current version to whatever is newest.
     */
    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
                     const BlobType type, uid_t uid);

    /**
     * Takes a blob that is an PEM-encoded RSA key as a byte array and converts it to a DER-encoded
     * PKCS#8 for import into a keymaster.  Then it overwrites the original blob with the new blob
     * format that is returned from the keymaster.
     */
    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid);

    void readMetaData();
    void writeMetaData();

    bool upgradeKeystore();
};

#endif  // KEYSTORE_KEYSTORE_H_