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 
17 package android.security;
18 
19 import android.os.Environment;
20 import android.os.FileUtils;
21 
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.SecureRandom;
27 
28 import javax.crypto.KeyGenerator;
29 import javax.crypto.SecretKey;
30 
31 import libcore.io.IoUtils;
32 
33 /**
34  *@hide
35  */
36 public class SystemKeyStore {
37 
38     private static final String SYSTEM_KEYSTORE_DIRECTORY = "misc/systemkeys";
39     private static final String KEY_FILE_EXTENSION = ".sks";
40     private static SystemKeyStore mInstance = new SystemKeyStore();
41 
SystemKeyStore()42     private SystemKeyStore() { }
43 
getInstance()44     public static SystemKeyStore getInstance() {
45         return mInstance;
46     }
47 
toHexString(byte[] keyData)48     public static String toHexString(byte[] keyData) {
49         if (keyData == null) {
50             return null;
51         }
52         int keyLen = keyData.length;
53         int expectedStringLen = keyData.length * 2;
54         StringBuilder sb = new StringBuilder(expectedStringLen);
55         for (int i = 0; i < keyData.length; i++) {
56             String hexStr = Integer.toString(keyData[i] & 0x00FF, 16);
57             if (hexStr.length() == 1) {
58                 hexStr = "0" + hexStr;
59             }
60             sb.append(hexStr);
61         }
62         return sb.toString();
63     }
64 
generateNewKeyHexString(int numBits, String algName, String keyName)65     public String generateNewKeyHexString(int numBits, String algName, String keyName)
66             throws NoSuchAlgorithmException {
67         return toHexString(generateNewKey(numBits, algName, keyName));
68     }
69 
generateNewKey(int numBits, String algName, String keyName)70     public byte[] generateNewKey(int numBits, String algName, String keyName)
71             throws NoSuchAlgorithmException {
72 
73         // Check if key with similar name exists. If so, return null.
74         File keyFile = getKeyFile(keyName);
75         if (keyFile.exists()) {
76             throw new IllegalArgumentException();
77         }
78 
79         KeyGenerator skg = KeyGenerator.getInstance(algName);
80         SecureRandom srng = SecureRandom.getInstance("SHA1PRNG");
81         skg.init(numBits, srng);
82 
83         SecretKey sk = skg.generateKey();
84         byte[] retKey = sk.getEncoded();
85 
86         try {
87             // Store the key
88             if (!keyFile.createNewFile()) {
89                 throw new IllegalArgumentException();
90             }
91 
92             FileOutputStream fos = new FileOutputStream(keyFile);
93             fos.write(retKey);
94             fos.flush();
95             FileUtils.sync(fos);
96             fos.close();
97             FileUtils.setPermissions(keyFile.getName(), (FileUtils.S_IRUSR | FileUtils.S_IWUSR),
98                 -1, -1);
99         } catch (IOException ioe) {
100             return null;
101         }
102         return retKey;
103     }
104 
getKeyFile(String keyName)105     private File getKeyFile(String keyName) {
106         File sysKeystoreDir = new File(Environment.getDataDirectory(),
107                 SYSTEM_KEYSTORE_DIRECTORY);
108         File keyFile = new File(sysKeystoreDir, keyName + KEY_FILE_EXTENSION);
109         return keyFile;
110     }
111 
retrieveKeyHexString(String keyName)112     public String retrieveKeyHexString(String keyName) throws IOException {
113         return toHexString(retrieveKey(keyName));
114     }
115 
retrieveKey(String keyName)116     public byte[] retrieveKey(String keyName) throws IOException {
117         File keyFile = getKeyFile(keyName);
118         if (!keyFile.exists()) {
119             return null;
120         }
121         return IoUtils.readFileAsByteArray(keyFile.toString());
122     }
123 
deleteKey(String keyName)124     public void deleteKey(String keyName) {
125 
126         // Get the file first.
127         File keyFile = getKeyFile(keyName);
128         if (!keyFile.exists()) {
129             throw new IllegalArgumentException();
130         }
131 
132         keyFile.delete();
133     }
134 }
135