package ui; import model.asn1.exceptions.ParseException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Useful small methods for the whole program. */ public final class Utils { /** * EFFECTS: Convert the input primitive byte array into the boxed Byte array. */ public static Byte[] byteToByte(byte[] array) { Byte[] arr = new Byte[array.length]; for (int i = 0; i < arr.length; i++) { arr[i] = array[i]; } return arr; } /** * EFFECTS: Convert the input boxed Byte array into primitive byte array. */ public static byte[] byteToByte(Byte[] array) { byte[] arr = new byte[array.length]; for (int i = 0; i < arr.length; i++) { arr[i] = array[i]; } return arr; } /** * EFFECTS: Pack the big-endian bytes into a 32bit integer. * Throws {@link model.asn1.exceptions.ParseException} if the value is too large. */ public static int bytesToInt(Byte[] array) throws ParseException { try { return new BigInteger(byteToByte(array)).intValueExact(); } catch (ArithmeticException ignored) { throw new ParseException("Value is too large."); } } /** * EFFECTS: Unpack the multibyte 64bit integer to its shortest array of byte format. Remove leading empty byte * if that number is not zero. */ public static Byte[] valToByte(long val) { byte[] v = BigInteger.valueOf(val).toByteArray(); if (val != 0 && v[0] == 0) { if (v.length == 1) { return new Byte[0]; } byte[] arr = new byte[v.length - 1]; System.arraycopy(v, 1, arr, 0, arr.length); return byteToByte(arr); } return byteToByte(v); } /** * EFFECTS: Decode the input PEM file, with optional check on tags. \n must present after each line, optional after * the last. * Throws {@link ParseException} if the desiredTag is specified but the input does not have the specific tag, or * if the input does not have any tags at all (not a PEM). */ public static Byte[] parsePEM(Byte[] input, String desiredTag) throws ParseException { final String str = new String(byteToByte(input), StandardCharsets.UTF_8); Pattern pattern = Pattern.compile("^-----BEGIN " + desiredTag + "-----$\n^(.*)$\n^-----END " + desiredTag + "-----$\n*", Pattern.DOTALL | Pattern.MULTILINE); final Matcher matcher = pattern.matcher(str); if (!matcher.matches()) { throw new ParseException("Not a valid PEM"); } final String b64 = matcher.group(1).replace("\n", ""); try { return byteToByte(Base64.getDecoder().decode(b64)); } catch (IllegalArgumentException e) { throw new ParseException(e.getMessage()); } } /** * EFFECTS: Base64 encode the input bytes and convert them into PEM format. * REQUIRES: desiredTag must be upper case and not empty. */ public static String toPEM(Byte[] input, String tag) { return "-----BEGIN " + tag + "-----\n" + Base64.getEncoder().encodeToString(byteToByte(input)) + "\n-----END " + tag + "-----"; } }