xref: /aosp_15_r20/external/cronet/components/cronet/android/test/mock_cert_verifier.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 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 <string>
6 #include <vector>
7 
8 #include "base/android/jni_android.h"
9 #include "base/android/jni_array.h"
10 #include "base/android/jni_string.h"
11 #include "base/test/test_support_android.h"
12 #include "components/cronet/android/cronet_test_apk_jni/MockCertVerifier_jni.h"
13 #include "crypto/sha2.h"
14 #include "net/base/net_errors.h"
15 #include "net/cert/asn1_util.h"
16 #include "net/cert/cert_verifier.h"
17 #include "net/cert/cert_verify_result.h"
18 #include "net/cert/mock_cert_verifier.h"
19 #include "net/cert/x509_util.h"
20 #include "net/test/cert_test_util.h"
21 #include "net/test/test_data_directory.h"
22 
23 using base::android::JavaParamRef;
24 
25 namespace cronet {
26 
27 namespace {
28 
29 // Populates |out_hash_value| with the SHA256 hash of the |cert| public key.
30 // Returns true on success.
CalculatePublicKeySha256(const net::X509Certificate & cert,net::HashValue * out_hash_value)31 static bool CalculatePublicKeySha256(const net::X509Certificate& cert,
32                                      net::HashValue* out_hash_value) {
33   // Extract the public key from the cert.
34   base::StringPiece spki_bytes;
35   if (!net::asn1::ExtractSPKIFromDERCert(
36           net::x509_util::CryptoBufferAsStringPiece(cert.cert_buffer()),
37           &spki_bytes)) {
38     LOG(INFO) << "Unable to retrieve the public key from the DER cert";
39     return false;
40   }
41   // Calculate SHA256 hash of public key bytes.
42   *out_hash_value = net::HashValue(net::HASH_VALUE_SHA256);
43   crypto::SHA256HashString(spki_bytes, out_hash_value->data(),
44                            crypto::kSHA256Length);
45   return true;
46 }
47 
48 }  // namespace
49 
JNI_MockCertVerifier_CreateMockCertVerifier(JNIEnv * env,const JavaParamRef<jobjectArray> & jcerts,const jboolean jknown_root,const JavaParamRef<jstring> & jtest_data_dir)50 static jlong JNI_MockCertVerifier_CreateMockCertVerifier(
51     JNIEnv* env,
52     const JavaParamRef<jobjectArray>& jcerts,
53     const jboolean jknown_root,
54     const JavaParamRef<jstring>& jtest_data_dir) {
55   base::FilePath test_data_dir(
56       base::android::ConvertJavaStringToUTF8(env, jtest_data_dir));
57   base::InitAndroidTestPaths(test_data_dir);
58 
59   std::vector<std::string> certs;
60   base::android::AppendJavaStringArrayToStringVector(env, jcerts, &certs);
61   net::MockCertVerifier* mock_cert_verifier = new net::MockCertVerifier();
62   for (const auto& cert : certs) {
63     net::CertVerifyResult verify_result;
64     verify_result.verified_cert =
65         net::ImportCertFromFile(net::GetTestCertsDirectory(), cert);
66 
67     // By default, HPKP verification is enabled for known trust roots only.
68     verify_result.is_issued_by_known_root = jknown_root;
69 
70     // Calculate the public key hash and add it to the verify_result.
71     net::HashValue hashValue;
72     CHECK(CalculatePublicKeySha256(*verify_result.verified_cert.get(),
73                                    &hashValue));
74     verify_result.public_key_hashes.push_back(hashValue);
75 
76     mock_cert_verifier->AddResultForCert(verify_result.verified_cert.get(),
77                                          verify_result, net::OK);
78   }
79 
80   return reinterpret_cast<jlong>(mock_cert_verifier);
81 }
82 
JNI_MockCertVerifier_CreateFreeForAllMockCertVerifier(JNIEnv * env)83 static jlong JNI_MockCertVerifier_CreateFreeForAllMockCertVerifier(
84     JNIEnv* env) {
85   net::MockCertVerifier* mock_cert_verifier = new net::MockCertVerifier();
86   mock_cert_verifier->set_default_result(net::OK);
87   return reinterpret_cast<jlong>(mock_cert_verifier);
88 }
89 
90 }  // namespace cronet
91