aboutsummaryrefslogtreecommitdiff
path: root/src/main/ui/Utils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/ui/Utils.java')
-rw-r--r--src/main/ui/Utils.java105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/main/ui/Utils.java b/src/main/ui/Utils.java
new file mode 100644
index 0000000..ccb244e
--- /dev/null
+++ b/src/main/ui/Utils.java
@@ -0,0 +1,105 @@
+package ui;
+
+import model.asn1.exceptions.ParseException;
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * 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: Pack the big-endian bytes into a 64bit integer.
+ * Throws {@link model.asn1.exceptions.ParseException} if the value is too large.
+ */
+ public static long bytesToLong(Byte[] array) throws ParseException {
+ try {
+ return new BigInteger(byteToByte(array)).longValueExact();
+ } catch (ArithmeticException ignored) {
+ throw new ParseException("Value is too large.");
+ }
+ }
+
+ /**
+ * EFFECTS: Unpack the multibyte 64bit integer to its shortest array of byte format.
+ */
+ 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: Parse the two-digit octet string into an unsigned byte, preserving leading zero and negative values.
+ * REQUIRES: The input octet must be a two-char string, with each char matching [0-9][A-F].
+ */
+ public static Byte parseByte(String octet) {
+ return (byte) Integer.parseInt(octet, 16);
+ }
+
+ /**
+ * EFFECTS: Decode the input PEM file, with optional check on tags.
+ * 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 + "-----$",
+ 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", "");
+ return byteToByte(Base64.getDecoder().decode(b64));
+ }
+}