1 /*
2  * Copyright (C) 2020 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 package com.android.telephony;
17 
18 import android.text.TextUtils;
19 import android.util.Base64;
20 import android.util.Log;
21 
22 import com.android.internal.telephony.util.TelephonyUtils;
23 
24 import java.security.MessageDigest;
25 import java.security.NoSuchAlgorithmException;
26 
27 /**
28  * A copy of {@link android.telephony.Rlog} to be used within the telephony mainline module.
29  *
30  * @hide
31  */
32 public final class Rlog {
33 
34     private static final boolean USER_BUILD = TelephonyUtils.IS_USER;
35 
Rlog()36     private Rlog() {
37     }
38 
log(int priority, String tag, String msg)39     private static int log(int priority, String tag, String msg) {
40         return Log.logToRadioBuffer(priority, tag, msg);
41     }
42 
v(String tag, String msg)43     public static int v(String tag, String msg) {
44         return log(Log.VERBOSE, tag, msg);
45     }
46 
v(String tag, String msg, Throwable tr)47     public static int v(String tag, String msg, Throwable tr) {
48         return log(Log.VERBOSE, tag,
49                 msg + '\n' + Log.getStackTraceString(tr));
50     }
51 
d(String tag, String msg)52     public static int d(String tag, String msg) {
53         return log(Log.DEBUG, tag, msg);
54     }
55 
d(String tag, String msg, Throwable tr)56     public static int d(String tag, String msg, Throwable tr) {
57         return log(Log.DEBUG, tag,
58                 msg + '\n' + Log.getStackTraceString(tr));
59     }
60 
i(String tag, String msg)61     public static int i(String tag, String msg) {
62         return log(Log.INFO, tag, msg);
63     }
64 
i(String tag, String msg, Throwable tr)65     public static int i(String tag, String msg, Throwable tr) {
66         return log(Log.INFO, tag,
67                 msg + '\n' + Log.getStackTraceString(tr));
68     }
69 
w(String tag, String msg)70     public static int w(String tag, String msg) {
71         return log(Log.WARN, tag, msg);
72     }
73 
w(String tag, String msg, Throwable tr)74     public static int w(String tag, String msg, Throwable tr) {
75         return log(Log.WARN, tag,
76                 msg + '\n' + Log.getStackTraceString(tr));
77     }
78 
w(String tag, Throwable tr)79     public static int w(String tag, Throwable tr) {
80         return log(Log.WARN, tag, Log.getStackTraceString(tr));
81     }
82 
e(String tag, String msg)83     public static int e(String tag, String msg) {
84         return log(Log.ERROR, tag, msg);
85     }
86 
e(String tag, String msg, Throwable tr)87     public static int e(String tag, String msg, Throwable tr) {
88         return log(Log.ERROR, tag,
89                 msg + '\n' + Log.getStackTraceString(tr));
90     }
91 
println(int priority, String tag, String msg)92     public static int println(int priority, String tag, String msg) {
93         return log(priority, tag, msg);
94     }
95 
isLoggable(String tag, int level)96     public static boolean isLoggable(String tag, int level) {
97         return Log.isLoggable(tag, level);
98     }
99 
100     /**
101      * Redact personally identifiable information for production users.
102      * @param tag used to identify the source of a log message
103      * @param pii the personally identifiable information we want to apply secure hash on.
104      * @return If tag is loggable in verbose mode or pii is null, return the original input.
105      * otherwise return a secure Hash of input pii
106      */
pii(String tag, Object pii)107     public static String pii(String tag, Object pii) {
108         String val = String.valueOf(pii);
109         if (pii == null || TextUtils.isEmpty(val) || isLoggable(tag, Log.VERBOSE)) {
110             return val;
111         }
112         return "[" + secureHash(val.getBytes()) + "]";
113     }
114 
115     /**
116      * Redact personally identifiable information for production users.
117      * @param enablePiiLogging set when caller explicitly want to enable sensitive logging.
118      * @param pii the personally identifiable information we want to apply secure hash on.
119      * @return If enablePiiLogging is set to true or pii is null, return the original input.
120      * otherwise return a secure Hash of input pii
121      */
pii(boolean enablePiiLogging, Object pii)122     public static String pii(boolean enablePiiLogging, Object pii) {
123         String val = String.valueOf(pii);
124         if (pii == null || TextUtils.isEmpty(val) || enablePiiLogging) {
125             return val;
126         }
127         return "[" + secureHash(val.getBytes()) + "]";
128     }
129 
130     /**
131      * Returns a secure hash (using the SHA1 algorithm) of the provided input.
132      *
133      * @return "****" if the build type is user, otherwise the hash
134      * @param input the bytes for which the secure hash should be computed.
135      */
secureHash(byte[] input)136     private static String secureHash(byte[] input) {
137         // Refrain from logging user personal information in user build.
138         if (USER_BUILD) {
139             return "****";
140         }
141 
142         MessageDigest messageDigest;
143 
144         try {
145             messageDigest = MessageDigest.getInstance("SHA-1");
146         } catch (NoSuchAlgorithmException e) {
147             return "####";
148         }
149 
150         byte[] result = messageDigest.digest(input);
151         return Base64.encodeToString(
152                 result, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP);
153     }
154 }
155