9 | * ---------------------- Minify.java 2015-10-04 ---------------------- 10 | *
11 | * Copyright (c) 2015 Charles Bihis (www.whoischarles.com) 12 | *
13 | * This work is an adaptation of JSMin.java published by John Reilly which is a 14 | * translation from C to Java of jsmin.c published by Douglas Crockford. 15 | * Permission is hereby granted to use this Java version under the same 16 | * conditions as the original jsmin.c on which all of these derivatives are 17 | * based. 18 | *
19 | *
20 | *
21 | * --------------------- JSMin.java 2006-02-13 --------------------- 22 | *
23 | * Copyright (c) 2006 John Reilly (www.inconspicuous.org) 24 | *
25 | * This work is a translation from C to Java of jsmin.c published by Douglas 26 | * Crockford. Permission is hereby granted to use the Java version under the 27 | * same conditions as the jsmin.c on which it is based. 28 | *
29 | *
30 | *
31 | * ------------------ jsmin.c 2003-04-21 ------------------ 32 | *
33 | * Copyright (c) 2002 Douglas Crockford (www.crockford.com) 34 | *
35 | * Permission is hereby granted, free of charge, to any person obtaining a copy 36 | * of this software and associated documentation files (the "Software"), to deal 37 | * in the Software without restriction, including without limitation the rights 38 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | * copies of the Software, and to permit persons to whom the Software is 40 | * furnished to do so, subject to the following conditions: 41 | *
42 | * The above copyright notice and this permission notice shall be included in 43 | * all copies or substantial portions of the Software. 44 | *
45 | * The Software shall be used for Good, not Evil. 46 | *
47 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53 | * SOFTWARE.
54 | */
55 | /**
56 | * ---------------------- Minify.java 2015-10-04 ----------------------
57 | *
58 | * Copyright (c) 2015 Charles Bihis (www.whoischarles.com)
59 | *
60 | * This work is an adaptation of JSMin.java published by John Reilly which is a
61 | * translation from C to Java of jsmin.c published by Douglas Crockford.
62 | * Permission is hereby granted to use this Java version under the same
63 | * conditions as the original jsmin.c on which all of these derivatives are
64 | * based.
65 | *
66 | *
67 | *
68 | * --------------------- JSMin.java 2006-02-13 ---------------------
69 | *
70 | * Copyright (c) 2006 John Reilly (www.inconspicuous.org)
71 | *
72 | * This work is a translation from C to Java of jsmin.c published by Douglas
73 | * Crockford. Permission is hereby granted to use the Java version under the
74 | * same conditions as the jsmin.c on which it is based.
75 | *
76 | *
77 | *
78 | * ------------------ jsmin.c 2003-04-21 ------------------
79 | *
80 | * Copyright (c) 2002 Douglas Crockford (www.crockford.com)
81 | *
82 | * Permission is hereby granted, free of charge, to any person obtaining a copy
83 | * of this software and associated documentation files (the "Software"), to deal
84 | * in the Software without restriction, including without limitation the rights
85 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
86 | * copies of the Software, and to permit persons to whom the Software is
87 | * furnished to do so, subject to the following conditions:
88 | *
89 | * The above copyright notice and this permission notice shall be included in
90 | * all copies or substantial portions of the Software.
91 | *
92 | * The Software shall be used for Good, not Evil.
93 | *
94 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
95 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
96 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
97 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
98 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
99 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
100 | * SOFTWARE.
101 | */
102 |
103 | /**
104 | * Minify.java is written by Charles Bihis (www.whoischarles.com) and is adapted
105 | * from JSMin.java written by John Reilly (www.inconspicuous.org) which is
106 | * itself a translation of jsmin.c written by Douglas Crockford
107 | * (www.crockford.com).
108 | *
109 | * @see http://www.unl.edu/ucomm/templatedependents/JSMin.java
111 | * @see http://www.crockford.com/javascript/jsmin.c
113 | */
114 |
115 | public class Minify {
116 |
117 | private static final int EOF = -1;
118 |
119 | private PushbackInputStream in;
120 | private OutputStream out;
121 | private int currChar;
122 | private int nextChar;
123 | private int line;
124 | private int column;
125 |
126 | public enum Action {
127 | OUTPUT_CURR, DELETE_CURR, DELETE_NEXT
128 | }
129 |
130 | public Minify() {
131 | this.in = null;
132 | this.out = null;
133 | }
134 |
135 | /**
136 | * Minifies the input JSON string.
137 | *
138 | * Takes the input JSON string and deletes the characters which are
139 | * insignificant to JavaScipt. Comments will be removed, tabs will be replaced
140 | * with spaces, carriage returns will be replaced with line feeds, and most
141 | * spaces and line feeds will be removed. The result will be returned.
142 | *
143 | * @param json The JSON string for which to minify
144 | * @return A minified, yet functionally identical, version of the input JSON
145 | * string
146 | */
147 | public String minify(String json) {
148 | InputStream in = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
149 | ByteArrayOutputStream out = new ByteArrayOutputStream();
150 |
151 | try {
152 | minify(in, out);
153 | } catch (Exception e) {
154 | return null;
155 | }
156 |
157 | return out.toString().trim();
158 | }
159 |
160 | /**
161 | * Takes an input stream to a JSON string and outputs minified JSON to the
162 | * output stream.
163 | *
164 | * Takes the input JSON via the input stream and deletes the characters which
165 | * are insignificant to JavaScript. Comments will be removed, tabs will be
166 | * replaced with spaaces, carriage returns will be replaced with line feeds, and
167 | * most spaces and line feeds will be removed. The result is streamed to the
168 | * output stream.
169 | *
170 | * @param in The InputStream
from which to get the un-minified
171 | * JSON
172 | * @param out The OutputStream
where the resulting minified JSON
173 | * will be streamed to
174 | * @throws IOException
175 | * @throws UnterminatedRegExpLiteralException
176 | * @throws UnterminatedCommentException
177 | * @throws UnterminatedStringLiteralException
178 | */
179 | public void minify(InputStream in, OutputStream out) throws IOException, UnterminatedRegExpLiteralException,
180 | UnterminatedCommentException, UnterminatedStringLiteralException {
181 |
182 | // Initialize
183 | this.in = new PushbackInputStream(in);
184 | this.out = out;
185 | this.line = 0;
186 | this.column = 0;
187 | currChar = '\n';
188 | action(Action.DELETE_NEXT);
189 |
190 | // Process input
191 | while (currChar != EOF) {
192 | switch (currChar) {
193 |
194 | case ' ':
195 | if (isAlphanum(nextChar)) {
196 | action(Action.OUTPUT_CURR);
197 | } else {
198 | action(Action.DELETE_CURR);
199 | }
200 | break;
201 |
202 | case '\n':
203 | switch (nextChar) {
204 | case '{':
205 | case '[':
206 | case '(':
207 | case '+':
208 | case '-':
209 | action(Action.OUTPUT_CURR);
210 | break;
211 | case ' ':
212 | action(Action.DELETE_NEXT);
213 | break;
214 | default:
215 | if (isAlphanum(nextChar)) {
216 | action(Action.OUTPUT_CURR);
217 | } else {
218 | action(Action.DELETE_CURR);
219 | }
220 | }
221 | break;
222 |
223 | default:
224 | switch (nextChar) {
225 | case ' ':
226 | if (isAlphanum(currChar)) {
227 | action(Action.OUTPUT_CURR);
228 | break;
229 | }
230 | action(Action.DELETE_NEXT);
231 | break;
232 | case '\n':
233 | switch (currChar) {
234 | case '}':
235 | case ']':
236 | case ')':
237 | case '+':
238 | case '-':
239 | case '"':
240 | case '\'':
241 | action(Action.OUTPUT_CURR);
242 | break;
243 | default:
244 | if (isAlphanum(currChar)) {
245 | action(Action.OUTPUT_CURR);
246 | } else {
247 | action(Action.DELETE_NEXT);
248 | }
249 | }
250 | break;
251 | default:
252 | action(Action.OUTPUT_CURR);
253 | break;
254 | }
255 | }
256 | }
257 | out.flush();
258 | }
259 |
260 | /**
261 | * Process the current character with an appropriate action.
262 | *
263 | * The action that occurs is determined by the current character. The options
264 | * are:
265 | *
266 | * 1. Output currChar: output currChar, copy nextChar to currChar, get the next
267 | * character and save it to nextChar 2. Delete currChar: copy nextChar to
268 | * currChar, get the next character and save it to nextChar 3. Delete nextChar:
269 | * get the next character and save it to nextChar
270 | *
271 | * This method essentially treats a string as a single character. Also
272 | * recognizes regular expressions if they are preceded by '(', ',', or '='.
273 | *
274 | * @param action The action to perform
275 | * @throws IOException
276 | * @throws UnterminatedRegExpLiteralException
277 | * @throws UnterminatedCommentException
278 | * @throws UnterminatedStringLiteralException
279 | */
280 | private void action(Action action) throws IOException, UnterminatedRegExpLiteralException,
281 | UnterminatedCommentException, UnterminatedStringLiteralException {
282 |
283 | // Process action
284 | switch (action) {
285 |
286 | case OUTPUT_CURR:
287 | out.write(currChar);
288 |
289 | case DELETE_CURR:
290 | currChar = nextChar;
291 |
292 | if (currChar == '\'' || currChar == '"') {
293 | for (; ; ) {
294 | out.write(currChar);
295 | currChar = get();
296 | if (currChar == nextChar) {
297 | break;
298 | }
299 | if (currChar <= '\n') {
300 | throw new UnterminatedStringLiteralException(line, column);
301 | }
302 | if (currChar == '\\') {
303 | out.write(currChar);
304 | currChar = get();
305 | }
306 | }
307 | }
308 |
309 | case DELETE_NEXT:
310 | nextChar = next();
311 | if (nextChar == '/' && (currChar == '(' || currChar == ',' || currChar == '=' || currChar == ':')) {
312 | out.write(currChar);
313 | out.write(nextChar);
314 | for (; ; ) {
315 | currChar = get();
316 | if (currChar == '/') {
317 | break;
318 | } else if (currChar == '\\') {
319 | out.write(currChar);
320 | currChar = get();
321 | } else if (currChar <= '\n') {
322 | throw new UnterminatedRegExpLiteralException(line, column);
323 | }
324 | out.write(currChar);
325 | }
326 | nextChar = next();
327 | }
328 | }
329 | }
330 |
331 | /**
332 | * Determines whether a given character is a letter, digit, underscore, dollar
333 | * sign, or non-ASCII character.
334 | *
335 | * @param c The character to compare
336 | * @return True if the character is a letter, digit, underscore, dollar sign, or
337 | * non-ASCII character. False otherwise.
338 | */
339 | private boolean isAlphanum(int c) {
340 | return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$'
341 | || c == '\\' || c > 126);
342 | }
343 |
344 | /**
345 | * Returns the next character from the input stream.
346 | *
347 | * Will pop the next character from the input stack. If the character is a
348 | * control character, translate it to a space or line feed.
349 | *
350 | * @return The next character from the input stream
351 | * @throws IOException
352 | */
353 | private int get() throws IOException {
354 | int c = in.read();
355 |
356 | if (c == '\n') {
357 | line++;
358 | column = 0;
359 | } else {
360 | column++;
361 | }
362 |
363 | if (c >= ' ' || c == '\n' || c == EOF) {
364 | return c;
365 | }
366 |
367 | if (c == '\r') {
368 | column = 0;
369 | return '\n';
370 | }
371 |
372 | return ' ';
373 | }
374 |
375 | /**
376 | * Returns the next character from the input stream without popping it from the
377 | * stack.
378 | *
379 | * @return The next character from the input stream
380 | * @throws IOException
381 | */
382 | private int peek() throws IOException {
383 | int lookaheadChar = in.read();
384 | in.unread(lookaheadChar);
385 | return lookaheadChar;
386 | }
387 |
388 | /**
389 | * Get the next character from the input stream, excluding comments.
390 | *
391 | * Will read from the input stream via the get()
method. Will
392 | * exclude characters that are part of comments. peek()
is used to
393 | * se if a '/' is followed by a '/' or a '*' for the purpose of identifying
394 | * comments.
395 | *
396 | * @return The next character from the input stream, excluding characters from
397 | * comments
398 | * @throws IOException
399 | * @throws UnterminatedCommentException
400 | */
401 | private int next() throws IOException, UnterminatedCommentException {
402 | int c = get();
403 |
404 | if (c == '/') {
405 | switch (peek()) {
406 |
407 | case '/':
408 | for (; ; ) {
409 | c = get();
410 | if (c <= '\n') {
411 | return c;
412 | }
413 | }
414 |
415 | case '*':
416 | get();
417 | for (; ; ) {
418 | switch (get()) {
419 | case '*':
420 | if (peek() == '/') {
421 | get();
422 | return ' ';
423 | }
424 | break;
425 | case EOF:
426 | throw new UnterminatedCommentException(line, column);
427 | }
428 | }
429 |
430 | default:
431 | return c;
432 | }
433 |
434 | }
435 | return c;
436 | }
437 |
438 | /**
439 | * Exception to be thrown when an unterminated comment appears in the input.
440 | */
441 | public static class UnterminatedCommentException extends Exception {
442 | private static final long serialVersionUID = 3L;
443 |
444 | public UnterminatedCommentException(int line, int column) {
445 | super("Unterminated comment at line " + line + " and column " + column);
446 | }
447 | }
448 |
449 | /**
450 | * Exception to be thrown when an unterminated string literal appears in the
451 | * input.
452 | */
453 | public static class UnterminatedStringLiteralException extends Exception {
454 | private static final long serialVersionUID = 2L;
455 |
456 | public UnterminatedStringLiteralException(int line, int column) {
457 | super("Unterminated string literal at line " + line + " and column " + column);
458 | }
459 | }
460 |
461 | /**
462 | * Exception to be thrown when an unterminated regular expression literal
463 | * appears in the input.
464 | */
465 | public static class UnterminatedRegExpLiteralException extends Exception {
466 | private static final long serialVersionUID = 1L;
467 |
468 | public UnterminatedRegExpLiteralException(int line, int column) {
469 | super("Unterminated regular expression at line " + line + " and column " + column);
470 | }
471 | }
472 | }
473 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/Output.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Calendar;
5 | import java.util.Date;
6 | import java.util.TimeZone;
7 |
8 | public class Output {
9 |
10 | private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
11 |
12 | public static void output(String string) {
13 | Date cal = Calendar.getInstance(TimeZone.getDefault()).getTime();
14 | String msg = sdf.format(cal.getTime()) + " | " + string;
15 | if (Config.stdout == null) {
16 | System.out.println(msg);
17 | } else {
18 | Config.stdout.println(msg);
19 | }
20 | }
21 |
22 | public static void outputError(String string) {
23 | Date cal = Calendar.getInstance(TimeZone.getDefault()).getTime();
24 | String msg = sdf.format(cal.getTime()) + " | " + string;
25 | if (Config.stderr == null) {
26 | System.err.println(msg);
27 | } else {
28 | Config.stderr.println(msg);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/PostBody.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition;
2 |
3 | import org.apache.commons.lang.StringUtils;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.regex.Pattern;
8 |
9 | public class PostBody extends ITokenPosition {
10 | private String token;
11 | private boolean found = false;
12 | private String body;
13 |
14 |
15 | public PostBody(List
";
55 | }
56 | }
57 | return timeClaimString+"";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/TokenCheck.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition;
2 |
3 | import com.auth0.jwt.JWT;
4 | import com.auth0.jwt.interfaces.DecodedJWT;
5 | import org.apache.commons.lang.StringUtils;
6 |
7 | public class TokenCheck {
8 | public static boolean isValidJWT(String jwt) {
9 |
10 | if (StringUtils.countMatches(jwt, ".") != 2) {
11 | return false;
12 | }
13 |
14 | jwt = jwt.trim();
15 | if (StringUtils.contains(jwt, " ")) {
16 | return false;
17 | }
18 |
19 | String[] sArray = StringUtils.split(jwt, ".");
20 | if (sArray.length < 3) {
21 | return false;
22 | }
23 | for (String value : sArray) {
24 | if (!value.matches("[A-Za-z0-9+/=_-]+")) {
25 | return false;
26 | }
27 | }
28 |
29 | try {
30 | DecodedJWT decoded = JWT.decode(jwt);
31 | decoded.getAlgorithm();
32 | return true;
33 | } catch (Exception exception) {
34 | }
35 |
36 | return false;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/algorithm/AlgorithmLinker.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition.algorithm;
2 |
3 | import com.auth0.jwt.algorithms.Algorithm;
4 | import org.apache.commons.lang.RandomStringUtils;
5 | import org.bouncycastle.util.encoders.Base64;
6 | import pingvin.tokenposition.Output;
7 | import pingvin.tokenposition.PublicKeyBroker;
8 |
9 | import java.io.UnsupportedEncodingException;
10 | import java.security.*;
11 | import java.security.interfaces.ECKey;
12 | import java.security.interfaces.RSAKey;
13 | import java.security.spec.EncodedKeySpec;
14 | import java.security.spec.PKCS8EncodedKeySpec;
15 | import java.security.spec.X509EncodedKeySpec;
16 |
17 | public class AlgorithmLinker {
18 |
19 | public static final String[] keyBeginMarkers = new String[]{"-----BEGIN PUBLIC KEY-----", "-----BEGIN CERTIFICATE-----"};
20 | public static final String[] keyEndMarkers = new String[]{"-----END PUBLIC KEY-----", "-----END CERTIFICATE-----"};
21 |
22 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper none =
23 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("none", AlgorithmType.none);
24 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper HS256 =
25 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("HS256", AlgorithmType.symmetric);
26 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper HS384 =
27 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("HS384", AlgorithmType.symmetric);
28 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper HS512 =
29 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("HS512", AlgorithmType.symmetric);
30 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper RS256 =
31 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("RS256", AlgorithmType.asymmetric);
32 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper RS384 =
33 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("RS384", AlgorithmType.asymmetric);
34 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper RS512 =
35 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("RS512", AlgorithmType.asymmetric);
36 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper ES256 =
37 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("ES256", AlgorithmType.asymmetric);
38 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper ES384 =
39 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("ES384", AlgorithmType.asymmetric);
40 | public static final pingvin.tokenposition.algorithm.AlgorithmWrapper ES512 =
41 | new pingvin.tokenposition.algorithm.AlgorithmWrapper("ES512", AlgorithmType.asymmetric);
42 |
43 | private static final pingvin.tokenposition.algorithm.AlgorithmWrapper[] supportedAlgorithms = {
44 | none, HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512};
45 |
46 | private static PublicKey generatePublicKeyFromString(String key, String algorithm) {
47 | PublicKey publicKey = null;
48 | if (key.length() > 1) {
49 | key = cleanKey(key);
50 | byte[] keyByteArray = java.util.Base64.getDecoder().decode(key);
51 | try {
52 | KeyFactory kf = KeyFactory.getInstance(algorithm);
53 | EncodedKeySpec keySpec = new X509EncodedKeySpec(keyByteArray);
54 | publicKey = kf.generatePublic(keySpec);
55 | } catch (Exception e) {
56 | Output.outputError(e.getMessage());
57 | }
58 | }
59 | return publicKey;
60 | }
61 |
62 | public static String cleanKey(String key) {
63 | for (String keyBeginMarker : keyBeginMarkers) {
64 | key = key.replace(keyBeginMarker, "");
65 | }
66 | for (String keyEndMarker : keyEndMarkers) {
67 | key = key.replace(keyEndMarker, "");
68 | }
69 | key = key.replaceAll("\\s+", "").replaceAll("\\r+", "").replaceAll("\\n+", "");
70 |
71 | return key;
72 | }
73 |
74 | private static PrivateKey generatePrivateKeyFromString(String key, String algorithm) {
75 | PrivateKey privateKey = null;
76 | if (key.length() > 1) {
77 | key = cleanKey(key);
78 | try {
79 | byte[] keyByteArray = Base64.decode(key);
80 | KeyFactory kf = KeyFactory.getInstance(algorithm);
81 | EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyByteArray);
82 | privateKey = kf.generatePrivate(keySpec);
83 | } catch (Exception e) {
84 | Output.outputError("Error generating private key with input string '" + key + "' and algorithm '" + algorithm + "' - " + e.getMessage() + " - ");
85 | }
86 | }
87 | return privateKey;
88 | }
89 |
90 | /**
91 | * @param algo
92 | * @param key - either the secret or the private key
93 | * @return the algorithm element from the library, if nothing matches the
94 | * none algorithm element is returned
95 | * @throws IllegalArgumentException
96 | * @throws UnsupportedEncodingException
97 | */
98 | public static Algorithm getVerifierAlgorithm(String algo, String key) throws UnsupportedEncodingException {
99 | return getAlgorithm(algo, key, false);
100 | }
101 |
102 | public static Algorithm getSignerAlgorithm(String algo, String key) throws UnsupportedEncodingException {
103 | return getAlgorithm(algo, key, true);
104 | }
105 |
106 | private static Algorithm getAlgorithm(String algo, String key, boolean IsKeyASignerKey)
107 | throws IllegalArgumentException, UnsupportedEncodingException {
108 | if (algo.equals(HS256.getAlgorithm())) {
109 | return Algorithm.HMAC256(key);
110 | }
111 | if (algo.equals(HS384.getAlgorithm())) {
112 | return Algorithm.HMAC384(key);
113 | }
114 | if (algo.equals(HS512.getAlgorithm())) {
115 | return Algorithm.HMAC512(key);
116 | }
117 | if (algo.equals(ES256.getAlgorithm())) {
118 | return Algorithm.ECDSA256((ECKey) getKeyInstance(key, "EC", IsKeyASignerKey));
119 | }
120 | if (algo.equals(ES384.getAlgorithm())) {
121 | return Algorithm.ECDSA384((ECKey) getKeyInstance(key, "EC", IsKeyASignerKey));
122 | }
123 | if (algo.equals(ES512.getAlgorithm())) {
124 | return Algorithm.ECDSA512((ECKey) getKeyInstance(key, "EC", IsKeyASignerKey));
125 | }
126 | if (algo.equals(RS256.getAlgorithm())) {
127 | return Algorithm.RSA256((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey));
128 | }
129 | if (algo.equals(RS384.getAlgorithm())) {
130 | return Algorithm.RSA384((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey));
131 | }
132 | if (algo.equals(RS512.getAlgorithm())) {
133 | return Algorithm.RSA512((RSAKey) getKeyInstance(key, "RSA", IsKeyASignerKey));
134 | }
135 |
136 | return Algorithm.none();
137 | }
138 |
139 | private static Key getKeyInstance(String key, String algorithm, boolean isPrivate) {
140 | return isPrivate ? generatePrivateKeyFromString(key, algorithm) : generatePublicKeyFromString(key, algorithm);
141 | }
142 |
143 | public static String getRandomKey(String algorithm) {
144 | String algorithmType = AlgorithmLinker.getTypeOf(algorithm);
145 |
146 | if (algorithmType.equals(AlgorithmType.symmetric)) {
147 | return RandomStringUtils.randomAlphanumeric(6);
148 | }
149 | if (algorithmType.equals(AlgorithmType.asymmetric) && algorithm.startsWith("RS")) {
150 | try {
151 | KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
152 | PublicKeyBroker.publicKey = Base64.toBase64String(keyPair.getPublic().getEncoded());
153 | return Base64.toBase64String((keyPair.getPrivate().getEncoded()));
154 | } catch (NoSuchAlgorithmException e) {
155 | Output.outputError(e.getMessage());
156 | }
157 | }
158 | if (algorithmType.equals(AlgorithmType.asymmetric) && algorithm.startsWith("ES")) {
159 | try {
160 | KeyPair keyPair = KeyPairGenerator.getInstance("EC").generateKeyPair();
161 | return Base64.toBase64String(keyPair.getPrivate().getEncoded());
162 | } catch (NoSuchAlgorithmException e) {
163 | Output.outputError(e.getMessage());
164 | }
165 | }
166 | throw new RuntimeException("Cannot get random key of provided algorithm as it does not seem valid HS, RS or ES");
167 | }
168 |
169 | /**
170 | * @return gets the type (asym, sym, none) of the provided @param algo
171 | */
172 | public static String getTypeOf(String algorithm) {
173 | for (pingvin.tokenposition.algorithm.AlgorithmWrapper supportedAlgorithm : supportedAlgorithms) {
174 | if (algorithm.equals(supportedAlgorithm.getAlgorithm())) {
175 | return supportedAlgorithm.getType();
176 | }
177 | }
178 | return AlgorithmType.none;
179 | }
180 |
181 | public static pingvin.tokenposition.algorithm.AlgorithmWrapper[] getSupportedAlgorithms() {
182 | return supportedAlgorithms;
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/algorithm/AlgorithmType.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition.algorithm;
2 |
3 | public class AlgorithmType {
4 | // dummy class that holds the different algorithm "types"
5 | public final static String none = "none";
6 | public final static String symmetric = "symmetric";
7 | public final static String asymmetric = "asymmetric";
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/pingvin/tokenposition/algorithm/AlgorithmWrapper.java:
--------------------------------------------------------------------------------
1 | package pingvin.tokenposition.algorithm;
2 |
3 | public class AlgorithmWrapper {
4 | private final String algorithm;
5 | private final String type;
6 |
7 | public AlgorithmWrapper(String algorithm, String none) {
8 | this.algorithm = algorithm;
9 | this.type = none;
10 | }
11 |
12 | public String getAlgorithm() {
13 | return algorithm;
14 | }
15 |
16 | public String getType() {
17 | return type;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------