1package eu.siacs.conversations.utils;
2
3import java.security.SecureRandom;
4import java.text.Normalizer;
5import java.util.Arrays;
6import java.util.Collection;
7import java.util.LinkedHashSet;
8
9import eu.siacs.conversations.Config;
10
11public final class CryptoHelper {
12 public static final String FILETRANSFER = "?FILETRANSFERv1:";
13 private final static char[] hexArray = "0123456789abcdef".toCharArray();
14 private final static char[] vowels = "aeiou".toCharArray();
15 private final static char[] consonants = "bcdfghjklmnpqrstvwxyz".toCharArray();
16 final public static byte[] ONE = new byte[] { 0, 0, 0, 1 };
17
18 public static String bytesToHex(byte[] bytes) {
19 char[] hexChars = new char[bytes.length * 2];
20 for (int j = 0; j < bytes.length; j++) {
21 int v = bytes[j] & 0xFF;
22 hexChars[j * 2] = hexArray[v >>> 4];
23 hexChars[j * 2 + 1] = hexArray[v & 0x0F];
24 }
25 return new String(hexChars);
26 }
27
28 public static byte[] hexToBytes(String hexString) {
29 int len = hexString.length();
30 byte[] array = new byte[len / 2];
31 for (int i = 0; i < len; i += 2) {
32 array[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
33 .digit(hexString.charAt(i + 1), 16));
34 }
35 return array;
36 }
37
38 public static String hexToString(final String hexString) {
39 return new String(hexToBytes(hexString));
40 }
41
42 public static byte[] concatenateByteArrays(byte[] a, byte[] b) {
43 byte[] result = new byte[a.length + b.length];
44 System.arraycopy(a, 0, result, 0, a.length);
45 System.arraycopy(b, 0, result, a.length, b.length);
46 return result;
47 }
48
49 public static String randomMucName(SecureRandom random) {
50 return randomWord(3, random) + "." + randomWord(7, random);
51 }
52
53 private static String randomWord(int lenght, SecureRandom random) {
54 StringBuilder builder = new StringBuilder(lenght);
55 for (int i = 0; i < lenght; ++i) {
56 if (i % 2 == 0) {
57 builder.append(consonants[random.nextInt(consonants.length)]);
58 } else {
59 builder.append(vowels[random.nextInt(vowels.length)]);
60 }
61 }
62 return builder.toString();
63 }
64
65 /**
66 * Escapes usernames or passwords for SASL.
67 */
68 public static String saslEscape(final String s) {
69 final StringBuilder sb = new StringBuilder((int) (s.length() * 1.1));
70 for (int i = 0; i < s.length(); i++) {
71 char c = s.charAt(i);
72 switch (c) {
73 case ',':
74 sb.append("=2C");
75 break;
76 case '=':
77 sb.append("=3D");
78 break;
79 default:
80 sb.append(c);
81 break;
82 }
83 }
84 return sb.toString();
85 }
86
87 public static String saslPrep(final String s) {
88 return Normalizer.normalize(s, Normalizer.Form.NFKC);
89 }
90
91 public static String prettifyFingerprint(String fingerprint) {
92 StringBuilder builder = new StringBuilder(fingerprint);
93 builder.insert(8, " ");
94 builder.insert(17, " ");
95 builder.insert(26, " ");
96 builder.insert(35, " ");
97 return builder.toString();
98 }
99
100 public static String[] getSupportedCipherSuites(final String[] platformSupportedCipherSuites) {
101 final Collection<String> cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS));
102 cipherSuites.retainAll(Arrays.asList(platformSupportedCipherSuites));
103 return cipherSuites.toArray(new String[cipherSuites.size()]);
104 }
105}