1 /* 2 * Copyright (C) 2017 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 /* 17 * Copyright (c) 2015-2017, The Linux Foundation. 18 */ 19 /* 20 * Copyright 2013 Giesecke & Devrient GmbH. 21 * 22 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 23 * use this file except in compliance with the License. You may obtain a copy of 24 * the License at 25 * 26 * http://www.apache.org/licenses/LICENSE-2.0 27 * 28 * Unless required by applicable law or agreed to in writing, software 29 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 30 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 31 * License for the specific language governing permissions and limitations under 32 * the License. 33 */ 34 35 package com.android.se.internal; 36 37 /** Utilities class. */ 38 public final class ByteArrayConverter { 39 40 /** Override the default constructor to make it private. */ ByteArrayConverter()41 private ByteArrayConverter() { 42 } 43 44 /** 45 * Forms a FileViewProvider-compatible path String (i.e., transforms the byte array {0x3F, 0x00, 46 * 0x2F, 0xE2} into the String "3F00:2FE2"). 47 * 48 * @param rawPath The byte array containing the path component. 49 * @return A FileViewProvider-compatible path String. 50 * @throws IllegalArgumentException if the path has a bad coding. 51 */ byteArrayToPathString(byte[] rawPath)52 public static String byteArrayToPathString(byte[] rawPath) throws IllegalArgumentException { 53 if (rawPath.length % 2 != 0) { 54 throw new IllegalArgumentException("Invald path"); 55 } 56 57 byte[] buffer = new byte[2]; 58 String path = ""; 59 for (int i = 0; i < rawPath.length; i += 2) { 60 System.arraycopy(rawPath, i, buffer, 0, 2); 61 String fid = byteArrayToHexString(buffer); 62 if (fid.equalsIgnoreCase("3F00")) { 63 // MF should not be included in path 64 continue; 65 } 66 path = path.concat(fid); 67 if (i != rawPath.length - 2) { 68 path = path.concat(":"); 69 } 70 } 71 return path; 72 } 73 74 /** 75 * Forms an hex-encoded String of the specified byte array. 76 * 77 * @param array The byte array to be hex-encoded. 78 * @param offset The start position. 79 * @param length The number of bytes to be converted. 80 * @return A hex-encoded String of the specified byte array. 81 */ byteArrayToHexString(byte[] array, int offset, int length)82 public static String byteArrayToHexString(byte[] array, int offset, int length) { 83 if (array == null) { 84 return ""; 85 } 86 87 StringBuilder sb = new StringBuilder(); 88 89 for (int i = 0; i < length; i++) { 90 sb.append(String.format("%02x", array[offset + i] & 0xFF)); 91 } 92 93 return sb.toString(); 94 } 95 96 /** Converts the byte array to Hex String from a given offset */ byteArrayToHexString(byte[] array, int offset)97 public static String byteArrayToHexString(byte[] array, int offset) { 98 StringBuffer s = new StringBuffer(); 99 for (int i = offset; i < array.length; i++) { 100 s.append(Integer.toHexString(0x100 + (array[i] & 0xff)).substring(1)); 101 } 102 return s.toString(); 103 } 104 105 /** 106 * Forms an hex-encoded String of the specified byte array. 107 * 108 * @param byteArray The byte array to be hex-encoded. 109 * @return A hex-encoded String of the specified byte array. 110 */ byteArrayToHexString(byte[] byteArray)111 public static String byteArrayToHexString(byte[] byteArray) { 112 if (byteArray == null) { 113 return ""; 114 } 115 return byteArrayToHexString(byteArray, 0, byteArray.length); 116 } 117 118 /** 119 * Forms a byte array containing the values of the hex-encoded string. 120 * 121 * @param str The hex-encoded string to be converted to byte-array. 122 * @param offset The start position. 123 * @param length The number of chars to be converted (must be multiple of 2). 124 * @return A byte array containing the values of the hex-encoded string. 125 */ hexStringToByteArray(String str, int offset, int length)126 public static byte[] hexStringToByteArray(String str, int offset, int length) { 127 if (length % 2 != 0) { 128 throw new IllegalArgumentException("length must be multiple of 2"); 129 } 130 131 str = str.toUpperCase(); 132 133 byte[] outputBytes = new byte[str.length() / 2]; 134 135 for (int i = 0; i < length; i += 2) { 136 char c1 = str.charAt(i + offset); 137 char c2 = str.charAt(i + 1 + offset); 138 if (!isHexChar(c1) || !isHexChar(c2)) { 139 throw new IllegalArgumentException("Invalid char found"); 140 } 141 142 outputBytes[i / 2] = (byte) ((Character.digit(c1, 16) << 4) + Character.digit(c2, 16)); 143 } 144 145 return outputBytes; 146 } 147 148 /** 149 * Forms a byte array containing the values of the hex-encoded string. 150 * 151 * @param str The hex-encoded string to be converted to byte-array. 152 * @return A byte array containing the values of the hex-encoded string. 153 */ hexStringToByteArray(String str)154 public static byte[] hexStringToByteArray(String str) { 155 return hexStringToByteArray(str, 0, str.length()); 156 } 157 158 /** 159 * Forms a byte array containing the specified integer value. 160 * 161 * @param value The integer value to be converted to byte array. 162 * @return A byte array containing the specified integer value. 163 */ intToByteArray(int value)164 public static byte[] intToByteArray(int value) { 165 return new byte[]{ 166 (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value 167 }; 168 } 169 170 /** 171 * Forms an integer from a byte array. 172 * 173 * @param byteArray The byte array from where to form the integer. 174 * @return The integer value representing the specified byte array. 0 if the array is empty. If 175 * the array is longer than 4 bytes, only bytes 0 to 3 will be considered. 176 */ byteArrayToInt(byte[] byteArray)177 public static int byteArrayToInt(byte[] byteArray) { 178 switch (byteArray.length) { 179 case 0: 180 return 0; 181 case 1: 182 return (byteArray[0] & 0xFF); 183 case 2: 184 return (byteArray[0] & 0xFF) << 8 | (byteArray[1] & 0xFF); 185 case 3: 186 return (byteArray[0] & 0xFF) << 16 | (byteArray[1] & 0xFF) << 8 | (byteArray[2] 187 & 0xFF); 188 default: 189 return (byteArray[0] & 0xFF) << 24 190 | (byteArray[1] & 0xFF) << 16 191 | (byteArray[2] & 0xFF) << 8 192 | byteArray[3] & 0xFF; 193 } 194 } 195 196 /** 197 * Decides whether a char is a valid hex value or not. 198 * 199 * @param c The char to be evaluated. 200 * @return true if the specified char is a valid hex value, false otherwise. 201 */ isHexChar(char c)202 public static boolean isHexChar(char c) { 203 if (Character.isLowerCase(c)) { 204 c = Character.toUpperCase(c); 205 } 206 207 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'); 208 } 209 } 210