1 module jwtd.jwt_phobos;
2 
3 version (UsePhobos) {
4 	import jwtd.jwt;
5 
6 	string sign(string msg, string key, JWTAlgorithm algo = JWTAlgorithm.HS256) {
7 		import std.digest.sha;
8 		import std.digest.hmac;
9 
10 		ubyte[] sign;
11 
12 		void sign_hs(SHA)() {
13 			import std.string : representation;
14 
15 			auto hmac = HMAC!SHA(key.representation);
16 			hmac.put(msg.representation);
17 			sign = hmac.finish().dup;
18 		}
19 
20 		switch(algo) {
21 			case JWTAlgorithm.NONE: {
22 				break;
23 			}
24 			case JWTAlgorithm.HS256: {
25 				sign_hs!SHA256();
26 				break;
27 			}
28 			case JWTAlgorithm.HS384: {
29 				sign_hs!SHA384();
30 				break;
31 			}
32 			case JWTAlgorithm.HS512: {
33 				sign_hs!SHA512();
34 				break;
35 			}
36 			case JWTAlgorithm.RS256:
37 			case JWTAlgorithm.RS384:
38 			case JWTAlgorithm.RS512:
39 			case JWTAlgorithm.ES256:
40 			case JWTAlgorithm.ES384:
41 			case JWTAlgorithm.ES512:
42 				throw new SignException("Unsupported algorithm.");
43 			default:
44 				throw new SignException("Wrong algorithm.");
45 		}
46 
47 		return cast(string)sign;
48 	}
49 
50 	bool verifySignature(string signature, string signing_input, string key, JWTAlgorithm algo = JWTAlgorithm.HS256) {
51 		switch(algo) {
52 			case JWTAlgorithm.NONE:
53 				return key.length == 0;
54 			case JWTAlgorithm.HS256:
55 			case JWTAlgorithm.HS384:
56 			case JWTAlgorithm.HS512:
57 				return signature == sign(signing_input, key, algo);
58 			case JWTAlgorithm.RS256:
59 			case JWTAlgorithm.RS384:
60 			case JWTAlgorithm.RS512:
61 			case JWTAlgorithm.ES256:
62 			case JWTAlgorithm.ES384:
63 			case JWTAlgorithm.ES512:
64 				throw new SignException("Unsupported algorithm.");
65 			default:
66 				throw new VerifyException("Wrong algorithm.");
67 		}
68 	}
69 
70     unittest {
71         import std.exception : assertThrown;
72 
73         auto unsupportedAlgos = [
74             JWTAlgorithm.RS256,
75             JWTAlgorithm.RS384,
76             JWTAlgorithm.RS512,
77             JWTAlgorithm.ES256,
78             JWTAlgorithm.ES384,
79             JWTAlgorithm.ES512,
80             cast(JWTAlgorithm)"bogus_algo" ];
81 
82         foreach (algo; unsupportedAlgos) {
83             assertThrown(sign("message", "key", algo));
84             assertThrown(verifySignature("signature", "input", "key", algo));
85         }
86     }
87 }
88