• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.net;
6 
7 import org.chromium.base.Log;
8 import org.chromium.base.annotations.CalledByNative;
9 import org.chromium.base.annotations.JNINamespace;
10 
11 import java.security.InvalidKeyException;
12 import java.security.NoSuchAlgorithmException;
13 import java.security.PrivateKey;
14 import java.security.Signature;
15 
16 import javax.crypto.Cipher;
17 import javax.crypto.NoSuchPaddingException;
18 
19 /**
20  * Specifies all the dependencies from the native OpenSSL engine on an Android KeyStore.
21  */
22 @JNINamespace("net::android")
23 public class AndroidKeyStore {
24     private static final String TAG = "AndroidKeyStore";
25 
26     @CalledByNative
getPrivateKeyClassName(PrivateKey privateKey)27     private static String getPrivateKeyClassName(PrivateKey privateKey) {
28         return privateKey.getClass().getName();
29     }
30 
31     /**
32      * Check if a given PrivateKey object supports a signature algorithm.
33      *
34      * @param privateKey The PrivateKey handle.
35      * @param algorithm The signature algorithm to use.
36      * @return whether the algorithm is supported.
37      */
38     @CalledByNative
privateKeySupportsSignature(PrivateKey privateKey, String algorithm)39     private static boolean privateKeySupportsSignature(PrivateKey privateKey, String algorithm) {
40         try {
41             Signature signature = Signature.getInstance(algorithm);
42             signature.initSign(privateKey);
43         } catch (NoSuchAlgorithmException | InvalidKeyException e) {
44             return false;
45         } catch (Exception e) {
46             Log.e(TAG, "Exception while checking support for " + algorithm + ": " + e);
47             return false;
48         }
49         return true;
50     }
51 
52     /**
53      * Check if a given PrivateKey object supports an encryption algorithm.
54      *
55      * @param privateKey The PrivateKey handle.
56      * @param algorithm The signature algorithm to use.
57      * @return whether the algorithm is supported.
58      */
59     @CalledByNative
privateKeySupportsCipher(PrivateKey privateKey, String algorithm)60     private static boolean privateKeySupportsCipher(PrivateKey privateKey, String algorithm) {
61         try {
62             Cipher cipher = Cipher.getInstance(algorithm);
63             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
64         } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) {
65             return false;
66         } catch (Exception e) {
67             Log.e(TAG, "Exception while checking support for " + algorithm + ": " + e);
68             return false;
69         }
70         return true;
71     }
72 
73     /**
74      * Sign a given message with a given PrivateKey object.
75      *
76      * @param privateKey The PrivateKey handle.
77      * @param algorithm The signature algorithm to use.
78      * @param message The message to sign.
79      * @return signature as a byte buffer.
80      */
81     @CalledByNative
signWithPrivateKey( PrivateKey privateKey, String algorithm, byte[] message)82     private static byte[] signWithPrivateKey(
83             PrivateKey privateKey, String algorithm, byte[] message) {
84         // Hint: Algorithm names come from:
85         // http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html
86         Signature signature = null;
87         try {
88             signature = Signature.getInstance(algorithm);
89         } catch (NoSuchAlgorithmException e) {
90             Log.e(TAG, "Signature algorithm " + algorithm + " not supported: " + e);
91             return null;
92         }
93 
94         try {
95             signature.initSign(privateKey);
96             signature.update(message);
97             return signature.sign();
98         } catch (Exception e) {
99             Log.e(TAG,
100                     "Exception while signing message with " + algorithm + " and "
101                             + privateKey.getAlgorithm() + " private key ("
102                             + privateKey.getClass().getName() + "): " + e);
103             return null;
104         }
105     }
106 
107     /**
108      * Encrypts a given input with a given PrivateKey object.
109      *
110      * @param privateKey The PrivateKey handle.
111      * @param algorithm The cipher to use.
112      * @param input The input to encrypt.
113      * @return ciphertext as a byte buffer.
114      */
115     @CalledByNative
encryptWithPrivateKey( PrivateKey privateKey, String algorithm, byte[] message)116     private static byte[] encryptWithPrivateKey(
117             PrivateKey privateKey, String algorithm, byte[] message) {
118         Cipher cipher = null;
119         try {
120             cipher = Cipher.getInstance(algorithm);
121         } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
122             Log.e(TAG, "Cipher " + algorithm + " not supported: " + e);
123             return null;
124         }
125 
126         try {
127             cipher.init(Cipher.ENCRYPT_MODE, privateKey);
128             return cipher.doFinal(message);
129         } catch (Exception e) {
130             Log.e(TAG,
131                     "Exception while encrypting input with " + algorithm + " and "
132                             + privateKey.getAlgorithm() + " private key ("
133                             + privateKey.getClass().getName() + "): " + e);
134             return null;
135         }
136     }
137 }
138