1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
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
+ "-----";
}
}
|