SystemKeyStore.java revision 8d578836dc4f9fb41532b8b3dd7a6b168d6f4f9d
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.security;
18
19import android.os.Environment;
20import android.os.FileUtils;
21import android.os.Process;
22
23import org.apache.harmony.luni.util.InputStreamHelper;
24
25import java.io.File;
26import java.io.FileInputStream;
27import java.io.FileOutputStream;
28import java.io.IOException;
29import java.security.NoSuchAlgorithmException;
30import java.security.SecureRandom;
31
32import javax.crypto.KeyGenerator;
33import javax.crypto.SecretKey;
34
35/**
36 *@hide
37 */
38public class SystemKeyStore {
39
40    private static final String SYSTEM_KEYSTORE_DIRECTORY = "misc/systemkeys";
41    private static final String KEY_FILE_EXTENSION = ".sks";
42    private static SystemKeyStore mInstance = new SystemKeyStore();
43
44    private SystemKeyStore() { }
45
46    public static SystemKeyStore getInstance() {
47        return mInstance;
48    }
49
50    public static String toHexString(byte[] keyData) {
51        if (keyData == null) {
52            return null;
53        }
54        int keyLen = keyData.length;
55        int expectedStringLen = keyData.length * 2;
56        StringBuilder sb = new StringBuilder(expectedStringLen);
57        for (int i = 0; i < keyData.length; i++) {
58            String hexStr = Integer.toString(keyData[i] & 0x00FF, 16);
59            if (hexStr.length() == 1) {
60                hexStr = "0" + hexStr;
61            }
62            sb.append(hexStr);
63        }
64        return sb.toString();
65    }
66
67    public String generateNewKeyHexString(int numBits, String algName, String keyName)
68            throws NoSuchAlgorithmException {
69        return toHexString(generateNewKey(numBits, algName, keyName));
70    }
71
72    public byte[] generateNewKey(int numBits, String algName, String keyName)
73            throws NoSuchAlgorithmException {
74
75        // Check if key with similar name exists. If so, return null.
76        File keyFile = getKeyFile(keyName);
77        if (keyFile.exists()) {
78            throw new IllegalArgumentException();
79        }
80
81        KeyGenerator skg = KeyGenerator.getInstance(algName);
82        SecureRandom srng = SecureRandom.getInstance("SHA1PRNG");
83        skg.init(numBits, srng);
84
85        SecretKey sk = skg.generateKey();
86        byte[] retKey = sk.getEncoded();
87
88        try {
89            // Store the key
90            if (!keyFile.createNewFile()) {
91                throw new IllegalArgumentException();
92            }
93
94            FileOutputStream fos = new FileOutputStream(keyFile);
95            fos.write(retKey);
96            fos.flush();
97            fos.close();
98            FileUtils.setPermissions(keyFile.getName(), (FileUtils.S_IRUSR | FileUtils.S_IWUSR),
99                -1, -1);
100        } catch (IOException ioe) {
101            return null;
102        }
103        return retKey;
104    }
105
106    private File getKeyFile(String keyName) {
107        File sysKeystoreDir = new File(Environment.getDataDirectory(),
108                SYSTEM_KEYSTORE_DIRECTORY);
109        File keyFile = new File(sysKeystoreDir, keyName + KEY_FILE_EXTENSION);
110        return keyFile;
111    }
112
113    public String retrieveKeyHexString(String keyName) throws IOException {
114        return toHexString(retrieveKey(keyName));
115    }
116
117    public byte[] retrieveKey(String keyName) throws IOException {
118        File keyFile = getKeyFile(keyName);
119
120        if (!keyFile.exists()) {
121            return null;
122        }
123
124        FileInputStream fis = new FileInputStream(keyFile);
125        return InputStreamHelper.readFullyAndClose(fis);
126    }
127
128    public void deleteKey(String keyName) {
129
130        // Get the file first.
131        File keyFile = getKeyFile(keyName);
132        if (!keyFile.exists()) {
133            throw new IllegalArgumentException();
134        }
135
136        keyFile.delete();
137    }
138}
139