content: /*
   * Copyright (C) 2010 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.
   */
  
  package android.security;
  
  import android.os.Environment;
  import android.os.FileUtils;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.security.NoSuchAlgorithmException;
  import java.security.SecureRandom;
  
  import javax.crypto.KeyGenerator;
  import javax.crypto.SecretKey;
  
  import libcore.io.IoUtils;
  
  /**
   *@hide
   */
  public class SystemKeyStore {
  
      private static final String SYSTEM_KEYSTORE_DIRECTORY = "misc/systemkeys";
      private static final String KEY_FILE_EXTENSION = ".sks";
      private static SystemKeyStore mInstance = new SystemKeyStore();
  
      private SystemKeyStore() { }
  
      public static SystemKeyStore getInstance() {
          return mInstance;
      }
  
      public static String toHexString(byte[] keyData) {
          if (keyData == null) {
              return null;
          }
          int keyLen = keyData.length;
          int expectedStringLen = keyData.length * 2;
          StringBuilder sb = new StringBuilder(expectedStringLen);
          for (int i = 0; i < keyData.length; i++) {
              String hexStr = Integer.toString(keyData[i] & 0x00FF, 16);
              if (hexStr.length() == 1) {
                  hexStr = "0" + hexStr;
              }
              sb.append(hexStr);
          }
          return sb.toString();
      }
  
      public String generateNewKeyHexString(int numBits, String algName, String keyName)
              throws NoSuchAlgorithmException {
          return toHexString(generateNewKey(numBits, algName, keyName));
      }
  
      public byte[] generateNewKey(int numBits, String algName, String keyName)
              throws NoSuchAlgorithmException {
  
          // Check if key with similar name exists. If so, return null.
          File keyFile = getKeyFile(keyName);
          if (keyFile.exists()) {
              throw new IllegalArgumentException();
          }
  
          KeyGenerator skg = KeyGenerator.getInstance(algName);
          SecureRandom srng = SecureRandom.getInstance("SHA1PRNG");
          skg.init(numBits, srng);
  
          SecretKey sk = skg.generateKey();
          byte[] retKey = sk.getEncoded();
  
          try {
              // Store the key
              if (!keyFile.createNewFile()) {
                  throw new IllegalArgumentException();
              }
  
              FileOutputStream fos = new FileOutputStream(keyFile);
              fos.write(retKey);
              fos.flush();
              FileUtils.sync(fos);
              fos.close();
              FileUtils.setPermissions(keyFile.getName(), (FileUtils.S_IRUSR | FileUtils.S_IWUSR),
                  -1, -1);
          } catch (IOException ioe) {
              return null;
          }
          return retKey;
      }
  
      private File getKeyFile(String keyName) {
          File sysKeystoreDir = new File(Environment.getDataDirectory(),
                  SYSTEM_KEYSTORE_DIRECTORY);
          File keyFile = new File(sysKeystoreDir, keyName + KEY_FILE_EXTENSION);
          return keyFile;
      }
  
      public String retrieveKeyHexString(String keyName) throws IOException {
          return toHexString(retrieveKey(keyName));
      }
  
      public byte[] retrieveKey(String keyName) throws IOException {
          File keyFile = getKeyFile(keyName);
          if (!keyFile.exists()) {
              return null;
          }
          return IoUtils.readFileAsByteArray(keyFile.toString());
      }
  
      public void deleteKey(String keyName) {
  
          // Get the file first.
          File keyFile = getKeyFile(keyName);
          if (!keyFile.exists()) {
              throw new IllegalArgumentException();
          }
  
          keyFile.delete();
      }
  }
  