1 // Copyright 2013 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 #include "net/android/keystore.h"
6
7 #include <string_view>
8 #include <vector>
9
10 #include "base/android/jni_android.h"
11 #include "base/android/jni_array.h"
12 #include "base/android/jni_string.h"
13 #include "base/check.h"
14
15 // Must come after all headers that specialize FromJniType() / ToJniType().
16 #include "net/net_jni_headers/AndroidKeyStore_jni.h"
17
18 using base::android::AttachCurrentThread;
19 using base::android::ConvertJavaStringToUTF8;
20 using base::android::ConvertUTF8ToJavaString;
21 using base::android::HasException;
22 using base::android::JavaByteArrayToByteVector;
23 using base::android::JavaRef;
24 using base::android::ScopedJavaLocalRef;
25 using base::android::ToJavaByteArray;
26
27 namespace net::android {
28
GetPrivateKeyClassName(const JavaRef<jobject> & key)29 std::string GetPrivateKeyClassName(const JavaRef<jobject>& key) {
30 JNIEnv* env = AttachCurrentThread();
31 ScopedJavaLocalRef<jstring> name =
32 Java_AndroidKeyStore_getPrivateKeyClassName(env, key);
33 return ConvertJavaStringToUTF8(env, name);
34 }
35
PrivateKeySupportsSignature(const base::android::JavaRef<jobject> & key,std::string_view algorithm)36 bool PrivateKeySupportsSignature(const base::android::JavaRef<jobject>& key,
37 std::string_view algorithm) {
38 JNIEnv* env = AttachCurrentThread();
39
40 ScopedJavaLocalRef<jstring> algorithm_ref =
41 ConvertUTF8ToJavaString(env, algorithm);
42 DCHECK(!algorithm_ref.is_null());
43
44 jboolean result =
45 Java_AndroidKeyStore_privateKeySupportsSignature(env, key, algorithm_ref);
46 return !HasException(env) && result;
47 }
48
PrivateKeySupportsCipher(const base::android::JavaRef<jobject> & key,std::string_view algorithm)49 bool PrivateKeySupportsCipher(const base::android::JavaRef<jobject>& key,
50 std::string_view algorithm) {
51 JNIEnv* env = AttachCurrentThread();
52
53 ScopedJavaLocalRef<jstring> algorithm_ref =
54 ConvertUTF8ToJavaString(env, algorithm);
55 DCHECK(!algorithm_ref.is_null());
56
57 jboolean result =
58 Java_AndroidKeyStore_privateKeySupportsCipher(env, key, algorithm_ref);
59 return !HasException(env) && result;
60 }
61
SignWithPrivateKey(const JavaRef<jobject> & private_key_ref,std::string_view algorithm,base::span<const uint8_t> input,std::vector<uint8_t> * signature)62 bool SignWithPrivateKey(const JavaRef<jobject>& private_key_ref,
63 std::string_view algorithm,
64 base::span<const uint8_t> input,
65 std::vector<uint8_t>* signature) {
66 JNIEnv* env = AttachCurrentThread();
67
68 ScopedJavaLocalRef<jstring> algorithm_ref =
69 ConvertUTF8ToJavaString(env, algorithm);
70 DCHECK(!algorithm_ref.is_null());
71
72 // Convert message to byte[] array.
73 ScopedJavaLocalRef<jbyteArray> input_ref = ToJavaByteArray(env, input);
74 DCHECK(!input_ref.is_null());
75
76 // Invoke platform API
77 ScopedJavaLocalRef<jbyteArray> signature_ref =
78 Java_AndroidKeyStore_signWithPrivateKey(env, private_key_ref,
79 algorithm_ref, input_ref);
80 if (HasException(env) || signature_ref.is_null())
81 return false;
82
83 // Write signature to string.
84 JavaByteArrayToByteVector(env, signature_ref, signature);
85 return true;
86 }
87
EncryptWithPrivateKey(const JavaRef<jobject> & private_key_ref,std::string_view algorithm,base::span<const uint8_t> input,std::vector<uint8_t> * ciphertext)88 bool EncryptWithPrivateKey(const JavaRef<jobject>& private_key_ref,
89 std::string_view algorithm,
90 base::span<const uint8_t> input,
91 std::vector<uint8_t>* ciphertext) {
92 JNIEnv* env = AttachCurrentThread();
93
94 ScopedJavaLocalRef<jstring> algorithm_ref =
95 ConvertUTF8ToJavaString(env, algorithm);
96 DCHECK(!algorithm_ref.is_null());
97
98 // Convert message to byte[] array.
99 ScopedJavaLocalRef<jbyteArray> input_ref = ToJavaByteArray(env, input);
100 DCHECK(!input_ref.is_null());
101
102 // Invoke platform API
103 ScopedJavaLocalRef<jbyteArray> ciphertext_ref =
104 Java_AndroidKeyStore_encryptWithPrivateKey(env, private_key_ref,
105 algorithm_ref, input_ref);
106 if (HasException(env) || ciphertext_ref.is_null())
107 return false;
108
109 // Write ciphertext to string.
110 JavaByteArrayToByteVector(env, ciphertext_ref, ciphertext);
111 return true;
112 }
113
114 } // namespace net::android
115