1 #!/usr/bin/env dub
2 /+ dub.sdl:
3     name "bench_libjwt"
4     libs "jwt" "jansson" "crypto"
5 +/
6 
7 module benchmarks.libjwt;
8 import core.stdc.string;
9 import std.conv;
10 import std.datetime.stopwatch;
11 import std.stdio;
12 import std.string;
13 
14 int main(string[] args)
15 {
16     // args: enc/dec/val, cycle count, alg, token/payload, signature
17     // output:
18     //   payload/token/true
19     //   msecs taken
20     //   GC used bytes
21 
22     if (args.length != 6) { writeln("Invalid args"); return 1; }
23     size_t cycles = args[2].to!size_t;
24 
25     jwt_alg alg = ("JWT_ALG_" ~ args[3]).to!jwt_alg;
26 
27     {
28         StopWatch sw;
29         sw.start();
30         scope (exit)
31         {
32             sw.stop();
33             writeln(sw.peek.total!"msecs");
34             writeln(0); // C library, no GC used
35         }
36 
37         if (args[1] == "val") return validate(cycles, alg, args[4], args[5]);
38         else if (args[1] == "dec") return decode(cycles, alg, args[4], args[5]);
39         else if (args[1] == "enc") return encode(cycles, alg, args[4], args[5]);
40     }
41 
42     writeln("Invalid command: ", args[1]);
43     return 1;
44 }
45 
46 int validate(size_t cycles, jwt_alg alg, string token, string secret)
47 {
48     jwt_t* jwt;
49     auto tokenz = token.toStringz;
50     bool ret;
51 
52     foreach (_; 0..cycles)
53     {
54         ret = 0 == jwt_decode(&jwt, tokenz, cast(const(ubyte)*)secret.ptr, cast(int)secret.length);
55         if (!jwt) return 1;
56         jwt_free(jwt);
57     }
58 
59     writeln(ret);
60     return 0;
61 }
62 
63 int decode(size_t cycles, jwt_alg alg, string token, string secret)
64 {
65     jwt_t* jwt;
66     auto tokenz = token.toStringz;
67     bool ret;
68     char* tok;
69 
70     foreach (_; 0..cycles)
71     {
72         ret = 0 == jwt_decode(&jwt, tokenz, cast(const(ubyte)*)secret.ptr, cast(int)secret.length);
73         if (!jwt) return 1;
74         if (tok) jwt_free_str(tok);
75         tok = jwt_dump_str(jwt, 0);
76         jwt_free(jwt);
77     }
78 
79     auto t = tok[0..strlen(tok)];
80     import std.algorithm : countUntil;
81     immutable idx = t.countUntil("}.{"); // we need to split out the header to return just payload
82     if (idx < 0) return 1;
83     writeln(t[idx+2..$]);
84     return 0;
85 }
86 
87 int encode(size_t cycles, jwt_alg alg, string payload, string secret)
88 {
89     auto payz = payload.toStringz;
90     char* tok;
91     jwt_t* jwt;
92     foreach (_; 0..cycles)
93     {
94         if (tok) jwt_free_str(tok);
95         auto ret = jwt_new(&jwt);
96         if (ret != 0 || !jwt) return 1;
97         scope (exit) jwt_free(jwt);
98 
99         ret = jwt_set_alg(jwt, alg, cast(const(ubyte)*)secret.ptr, cast(int)secret.length);
100         if (ret < 0) return 1;
101 
102         jwt_add_grants_json(jwt, payz);
103         tok = jwt_encode_str(jwt);
104     }
105 
106     writeln(tok[0..strlen(tok)]);
107     jwt_free_str(tok);
108     return 0;
109 }
110 
111 
112 // dstep generated bindings from libjwt.h
113 
114 import core.stdc.config;
115 import core.stdc.stdio;
116 import core.stdc.time;
117 
118 extern (C) nothrow @nogc:
119 
120 /** Opaque JWT object. */
121 struct jwt;
122 alias jwt_t = jwt;
123 
124 /** Opaque JWT validation object. */
125 struct jwt_valid;
126 alias jwt_valid_t = jwt_valid;
127 
128 /** JWT algorithm types. */
129 enum jwt_alg
130 {
131     JWT_ALG_NONE = 0,
132     JWT_ALG_HS256 = 1,
133     JWT_ALG_HS384 = 2,
134     JWT_ALG_HS512 = 3,
135     JWT_ALG_RS256 = 4,
136     JWT_ALG_RS384 = 5,
137     JWT_ALG_RS512 = 6,
138     JWT_ALG_ES256 = 7,
139     JWT_ALG_ES384 = 8,
140     JWT_ALG_ES512 = 9,
141     JWT_ALG_TERM = 10
142 }
143 
144 alias jwt_alg_t = jwt_alg;
145 
146 enum JWT_ALG_INVAL = jwt_alg_t.JWT_ALG_TERM;
147 
148 /** JWT Validation exception types. These are bit values. */
149 enum JWT_VALIDATION_SUCCESS = 0x0000;
150 enum JWT_VALIDATION_ERROR = 0x0001; /* General failures */
151 enum JWT_VALIDATION_ALG_MISMATCH = 0x0002;
152 enum JWT_VALIDATION_EXPIRED = 0x0004;
153 enum JWT_VALIDATION_TOO_NEW = 0x0008;
154 enum JWT_VALIDATION_ISS_MISMATCH = 0x0010;
155 enum JWT_VALIDATION_SUB_MISMATCH = 0x0020;
156 enum JWT_VALIDATION_AUD_MISMATCH = 0x0040;
157 enum JWT_VALIDATION_GRANT_MISSING = 0x0080;
158 enum JWT_VALIDATION_GRANT_MISMATCH = 0x0100;
159 
160 /** JWT Memory allocation overrides */
161 alias jwt_malloc_t = void* function (size_t);
162 alias jwt_realloc_t = void* function (void*, size_t);
163 alias jwt_free_t = void function (void*);
164 
165 /**
166  * @defgroup jwt_new JWT Object Creation
167  * Functions used to create and destroy JWT objects.
168  *
169  * Generally, one would use the jwt_new() function to create an object
170  * from scratch and jwt_decode() to create and verify and object from an
171  * existing token.
172  *
173  * Note, when using RSA keys (e.g. with RS256), the key is expected to be
174  * a private key in PEM format. If the RSA private key requires a passphrase,
175  * the default is to request it on the command line from stdin. However,
176  * you can override this using OpenSSL's default_passwd routines. For
177  * example, using SSL_CTX_set_default_passwd_cb().
178  * @{
179  */
180 
181 /**
182  * Allocate a new, empty, JWT object.
183  *
184  * This is used to create a new object for a JWT. After you have finished
185  * with the object, use jwt_free() to clean up the memory used by it.
186  *
187  * @param jwt Pointer to a JWT object pointer. Will be allocated on
188  *     success.
189  * @return 0 on success, valid errno otherwise.
190  */
191 int jwt_new (jwt_t** jwt);
192 
193 /**
194  * Verify an existing JWT and allocate a new JWT object from it.
195  *
196  * Decodes a JWT string and verifies the signature (if one is supplied).
197  * If no signature is used (JWS, alg="none") or key is NULL, then no
198  * validation is done other than formatting. It is not suggested to use
199  * this on a string that has a signature without passing the key to
200  * verify it. If the JWT is encrypted and no key is supplied, an error
201  * is returned.
202  *
203  * @param jwt Pointer to a JWT object pointer. Will be allocated on
204  *     success.
205  * @param token Pointer to a valid JWT string, nul terminated.
206  * @param key Pointer to the key for validating the JWT signature or for
207  *     decrypting the token or NULL if no validation is to be performed.
208  * @param key_len The length of the above key.
209  * @return 0 on success, valid errno otherwise.
210  *
211  * @remark If a key is supplied, the token must pass sig check or decrypt
212  *     for it to be parsed without error. If no key is supplied, then a
213  *     non-encrypted token will be parsed without any checks for a valid
214  *     signature, however, standard validation of the token is still
215  *     performed.
216  */
217 int jwt_decode (
218     jwt_t** jwt,
219     const(char)* token,
220     const(ubyte)* key,
221     int key_len);
222 
223 /**
224  * Free a JWT object and any other resources it is using.
225  *
226  * After calling, the JWT object referenced will no longer be valid and
227  * its memory will be freed.
228  *
229  * @param jwt Pointer to a JWT object previously created with jwt_new()
230  *            or jwt_decode().
231  */
232 void jwt_free (jwt_t* jwt);
233 
234 /**
235  * Duplicate an existing JWT object.
236  *
237  * Copies all grants and algorithm specific bits to a new JWT object.
238  *
239  * @param jwt Pointer to a JWT object.
240  * @return A new object on success, NULL on error with errno set
241  *     appropriately.
242  */
243 jwt_t* jwt_dup (jwt_t* jwt);
244 
245 /** @} */
246 
247 /**
248  * @defgroup jwt_grant JWT Grant Manipulation
249  * These functions allow you to add, remove and retrieve grants from a JWT
250  * object.
251  * @{
252  */
253 
254 /**
255  * Return the value of a string grant.
256  *
257  * Returns the string value for a grant (e.g. "iss"). If it does not exist,
258  * NULL will be returned.
259  *
260  * @param jwt Pointer to a JWT object.
261  * @param grant String containing the name of the grant to return a value
262  *     for.
263  * @return Returns a string for the value, or NULL when not found.
264  *
265  * Note, this will only return grants with JSON string values. Use
266  * jwt_get_grant_json() to get the JSON representation of more complex
267  * values (e.g. arrays) or use jwt_get_grant_int() to get simple integer
268  * values.
269  */
270 const(char)* jwt_get_grant (jwt_t* jwt, const(char)* grant);
271 
272 /**
273  * Return the value of an integer grant.
274  *
275  * Returns the int value for a grant (e.g. "exp"). If it does not exist,
276  * 0 will be returned.
277  *
278  * @param jwt Pointer to a JWT object.
279  * @param grant String containing the name of the grant to return a value
280  *     for.
281  * @return Returns an int for the value. Sets errno to ENOENT when not
282  * found.
283  *
284  * Note, this will only return grants with JSON integer values. Use
285  * jwt_get_grant_json() to get the JSON representation of more complex
286  * values (e.g. arrays) or use jwt_get_grant() to get string values.
287  */
288 c_long jwt_get_grant_int (jwt_t* jwt, const(char)* grant);
289 
290 /**
291  * Return the value of an boolean grant.
292  *
293  * Returns the int value for a grant (e.g. "exp"). If it does not exist,
294  * 0 will be returned.
295  *
296  * @param jwt Pointer to a JWT object.
297  * @param grant String containing the name of the grant to return a value
298  *     for.
299  * @return Returns a boolean for the value. Sets errno to ENOENT when not
300  * found.
301  *
302  * Note, this will only return grants with JSON boolean values. Use
303  * jwt_get_grant_json() to get the JSON representation of more complex
304  * values (e.g. arrays) or use jwt_get_grant() to get string values.
305  */
306 int jwt_get_grant_bool (jwt_t* jwt, const(char)* grant);
307 
308 /**
309  * Return the value of a grant as JSON encoded object string.
310  *
311  * Returns the JSON encoded string value for a grant (e.g. "iss"). If it
312  * does not exist, NULL will be returned.
313  *
314  * @param jwt Pointer to a JWT object.
315  * @param grant String containing the name of the grant to return a value
316  *     for. If this is NULL, all grants will be returned as a JSON encoded
317  *     hash.
318  * @return Returns a string for the value, or NULL when not found. The
319  *     returned string must be freed by the caller.
320  */
321 char* jwt_get_grants_json (jwt_t* jwt, const(char)* grant);
322 
323 /**
324  * Add a new string grant to this JWT object.
325  *
326  * Creates a new grant for this object. The string for grant and val
327  * are copied internally, so do not require that the pointer or string
328  * remain valid for the lifetime of this object. It is an error if you
329  * try to add a grant that already exists.
330  *
331  * @param jwt Pointer to a JWT object.
332  * @param grant String containing the name of the grant to add.
333  * @param val String containing the value to be saved for grant. Can be
334  *     an empty string, but cannot be NULL.
335  * @return Returns 0 on success, valid errno otherwise.
336  *
337  * Note, this only allows for string based grants. If you wish to add
338  * integer grants, then use jwt_add_grant_int(). If you wish to add more
339  * complex grants (e.g. an array), then use jwt_add_grants_json().
340  */
341 int jwt_add_grant (jwt_t* jwt, const(char)* grant, const(char)* val);
342 
343 /**
344  * Add a new integer grant to this JWT object.
345  *
346  * Creates a new grant for this object. The string for grant
347  * is copied internally, so do not require that the pointer or string
348  * remain valid for the lifetime of this object. It is an error if you
349  * try to add a grant that already exists.
350  *
351  * @param jwt Pointer to a JWT object.
352  * @param grant String containing the name of the grant to add.
353  * @param val int containing the value to be saved for grant.
354  * @return Returns 0 on success, valid errno otherwise.
355  *
356  * Note, this only allows for integer based grants. If you wish to add
357  * string grants, then use jwt_add_grant(). If you wish to add more
358  * complex grants (e.g. an array), then use jwt_add_grants_json().
359  */
360 int jwt_add_grant_int (jwt_t* jwt, const(char)* grant, c_long val);
361 
362 /**
363  * Add a new boolean grant to this JWT object.
364  *
365  * Creates a new grant for this object. The string for grant
366  * is copied internally, so do not require that the pointer or string
367  * remain valid for the lifetime of this object. It is an error if you
368  * try to add a grant that already exists.
369  *
370  * @param jwt Pointer to a JWT object.
371  * @param grant String containing the name of the grant to add.
372  * @param val boolean containing the value to be saved for grant.
373  * @return Returns 0 on success, valid errno otherwise.
374  *
375  * Note, this only allows for boolean based grants. If you wish to add
376  * string grants, then use jwt_add_grant(). If you wish to add more
377  * complex grants (e.g. an array), then use jwt_add_grants_json().
378  */
379 int jwt_add_grant_bool (jwt_t* jwt, const(char)* grant, int val);
380 
381 /**
382  * Add grants from a JSON encoded object string.
383  *
384  * Loads a grant from an existing JSON encoded object string. Overwrites
385  * existing grant. If grant is NULL, then the JSON encoded string is
386  * assumed to be a JSON hash of all grants being added and will be merged
387  * into the grant listing.
388  *
389  * @param jwt Pointer to a JWT object.
390  * @param json String containing a JSON encoded object of grants.
391  * @return Returns 0 on success, valid errno otherwise.
392  */
393 int jwt_add_grants_json (jwt_t* jwt, const(char)* json);
394 
395 /**
396  * Delete a grant from this JWT object.
397  *
398  * Deletes the named grant from this object. It is not an error if there
399  * is no grant matching the passed name. If grant is NULL, then all grants
400  * are deleted from this JWT.
401  *
402  * @param jwt Pointer to a JWT object.
403  * @param grant String containing the name of the grant to delete. If this
404  *    is NULL, then all grants are deleted.
405  * @return Returns 0 on success, valid errno otherwise.
406  */
407 int jwt_del_grants (jwt_t* jwt, const(char)* grant);
408 
409 /**
410  * @deprecated
411  * Delete a grant from this JWT object.
412  *
413  * Deletes the named grant from this object. It is not an error if there
414  * is no grant matching the passed name.
415  *
416  * @param jwt Pointer to a JWT object.
417  * @param grant String containing the name of the grant to delete.
418  * @return Returns 0 on success, valid errno otherwise.
419  */
420 int jwt_del_grant (jwt_t* jwt, const(char)* grant);
421 
422 /** @} */
423 
424 /**
425  * @defgroup jwt_header JWT Header Manipulation
426  * These functions allow you to add, remove and retrieve headers from a JWT
427  * object.
428  * @{
429  */
430 
431 /**
432  * Return the value of a string header.
433  *
434  * Returns the string value for a header (e.g. ""). If it does not exist,
435  * NULL will be returned.
436  *
437  * @param jwt Pointer to a JWT object.
438  * @param header String containing the name of the header to return a value
439  *     for.
440  * @return Returns a string for the value, or NULL when not found.
441  *
442  * Note, this will only return headers with JSON string values. Use
443  * jwt_get_header_json() to get the JSON representation of more complex
444  * values (e.g. arrays) or use jwt_get_header_int() to get simple integer
445  * values.
446  */
447 const(char)* jwt_get_header (jwt_t* jwt, const(char)* header);
448 
449 /**
450  * Return the value of an integer header.
451  *
452  * Returns the int value for a header (e.g. ""). If it does not exist,
453  * 0 will be returned.
454  *
455  * @param jwt Pointer to a JWT object.
456  * @param header String containing the name of the header to return a value
457  *     for.
458  * @return Returns an int for the value. Sets errno to ENOENT when not
459  * found.
460  *
461  * Note, this will only return headers with JSON integer values. Use
462  * jwt_get_header_json() to get the JSON representation of more complex
463  * values (e.g. arrays) or use jwt_get_header() to get string values.
464  */
465 c_long jwt_get_header_int (jwt_t* jwt, const(char)* header);
466 
467 /**
468  * Return the value of an boolean header.
469  *
470  * Returns the int value for a header (e.g. ""). If it does not exist,
471  * 0 will be returned.
472  *
473  * @param jwt Pointer to a JWT object.
474  * @param header String containing the name of the header to return a value
475  *     for.
476  * @return Returns a boolean for the value. Sets errno to ENOENT when not
477  * found.
478  *
479  * Note, this will only return headers with JSON boolean values. Use
480  * jwt_get_header_json() to get the JSON representation of more complex
481  * values (e.g. arrays) or use jwt_get_header() to get string values.
482  */
483 int jwt_get_header_bool (jwt_t* jwt, const(char)* header);
484 
485 /**
486  * Return the value of a header as JSON encoded object string.
487  *
488  * Returns the JSON encoded string value for a header (e.g. ""). If it
489  * does not exist, NULL will be returned.
490  *
491  * @param jwt Pointer to a JWT object.
492  * @param header String containing the name of the header to return a value
493  *     for. If this is NULL, all headers will be returned as a JSON encoded
494  *     hash.
495  * @return Returns a string for the value, or NULL when not found. The
496  *     returned string must be freed by the caller.
497  */
498 char* jwt_get_headers_json (jwt_t* jwt, const(char)* header);
499 
500 /**
501  * Add a new string header to this JWT object.
502  *
503  * Creates a new header for this object. The string for header and val
504  * are copied internally, so do not require that the pointer or string
505  * remain valid for the lifetime of this object. It is an error if you
506  * try to add a header that already exists.
507  *
508  * @param jwt Pointer to a JWT object.
509  * @param header String containing the name of the header to add.
510  * @param val String containing the value to be saved for header. Can be
511  *     an empty string, but cannot be NULL.
512  * @return Returns 0 on success, valid errno otherwise.
513  *
514  * Note, this only allows for string based headers. If you wish to add
515  * integer headers, then use jwt_add_header_int(). If you wish to add more
516  * complex headers (e.g. an array), then use jwt_add_headers_json().
517  */
518 int jwt_add_header (jwt_t* jwt, const(char)* header, const(char)* val);
519 
520 /**
521  * Add a new integer header to this JWT object.
522  *
523  * Creates a new header for this object. The string for header
524  * is copied internally, so do not require that the pointer or string
525  * remain valid for the lifetime of this object. It is an error if you
526  * try to add a header that already exists.
527  *
528  * @param jwt Pointer to a JWT object.
529  * @param header String containing the name of the header to add.
530  * @param val int containing the value to be saved for header.
531  * @return Returns 0 on success, valid errno otherwise.
532  *
533  * Note, this only allows for integer based headers. If you wish to add
534  * string headers, then use jwt_add_header(). If you wish to add more
535  * complex headers (e.g. an array), then use jwt_add_headers_json().
536  */
537 int jwt_add_header_int (jwt_t* jwt, const(char)* header, c_long val);
538 
539 /**
540  * Add a new boolean header to this JWT object.
541  *
542  * Creates a new header for this object. The string for header
543  * is copied internally, so do not require that the pointer or string
544  * remain valid for the lifetime of this object. It is an error if you
545  * try to add a header that already exists.
546  *
547  * @param jwt Pointer to a JWT object.
548  * @param header String containing the name of the header to add.
549  * @param val boolean containing the value to be saved for header.
550  * @return Returns 0 on success, valid errno otherwise.
551  *
552  * Note, this only allows for boolean based headers. If you wish to add
553  * string headers, then use jwt_add_header(). If you wish to add more
554  * complex headers (e.g. an array), then use jwt_add_headers_json().
555  */
556 int jwt_add_header_bool (jwt_t* jwt, const(char)* header, int val);
557 
558 /**
559  * Add headers from a JSON encoded object string.
560  *
561  * Loads a header from an existing JSON encoded object string. Overwrites
562  * existing header. If header is NULL, then the JSON encoded string is
563  * assumed to be a JSON hash of all headers being added and will be merged
564  * into the header listing.
565  *
566  * @param jwt Pointer to a JWT object.
567  * @param json String containing a JSON encoded object of headers.
568  * @return Returns 0 on success, valid errno otherwise.
569  */
570 int jwt_add_headers_json (jwt_t* jwt, const(char)* json);
571 
572 /**
573  * Delete a header from this JWT object.
574  *
575  * Deletes the named header from this object. It is not an error if there
576  * is no header matching the passed name. If header is NULL, then all headers
577  * are deleted from this JWT.
578  *
579  * @param jwt Pointer to a JWT object.
580  * @param header String containing the name of the header to delete. If this
581  *    is NULL, then all headers are deleted.
582  * @return Returns 0 on success, valid errno otherwise.
583  */
584 int jwt_del_headers (jwt_t* jwt, const(char)* header);
585 
586 /** @} */
587 
588 /**
589  * @defgroup jwt_encode JWT Output Functions
590  * Functions that enable seeing the plain text or fully encoded version of
591  * a JWT object.
592  * @{
593  */
594 
595 /**
596  * Output plain text representation to a FILE pointer.
597  *
598  * This function will write a plain text representation of this JWT object
599  * without Base64 encoding. This only writes the header and body, and does
600  * not compute the signature or encryption (if such an algorithm were being
601  * used).
602  *
603  * Note, this may change the content of JWT header if algorithm is set
604  * on the JWT object. If algorithm is set (jwt_set_alg was called
605  * on the jwt object) then dumping JWT attempts to append 'typ' header.
606  * If the 'typ' header already exists, then it is left untouched,
607  * otherwise it is added with default value of "JWT".
608  *
609  * @param jwt Pointer to a JWT object.
610  * @param fp Valid FILE pointer to write data to.
611  * @param pretty Enables better visual formatting of output. Generally only
612  *     used for debugging.
613  * @return Returns 0 on success, valid errno otherwise.
614  */
615 int jwt_dump_fp (jwt_t* jwt, FILE* fp, int pretty);
616 
617 /**
618  * Return plain text representation as a string.
619  *
620  * Similar to jwt_dump_fp() except that a string is returned. The string
621  * must be freed by the caller.
622  *
623  * Note, this may change the content of JWT header if algorithm is set
624  * on the JWT object. If algorithm is set (jwt_set_alg was called
625  * on the jwt object) then dumping JWT attempts to append 'typ' header.
626  * If the 'typ' header already exists, then it is left untouched,
627  * otherwise it is added with default value of "JWT".
628  *
629  * @param jwt Pointer to a JWT object.
630  * @param pretty Enables better visual formatting of output. Generally only
631  *     used for debugging.
632  * @return A nul terminated string on success, NULL on error with errno
633  *     set appropriately.
634  */
635 char* jwt_dump_str (jwt_t* jwt, int pretty);
636 
637 /**
638  * Fully encode a JWT object and write it to FILE.
639  *
640  * This will create and write the complete JWT object to FILE. All parts
641  * will be Base64 encoded and signatures or encryption will be applied if
642  * the algorithm specified requires it.
643  *
644  * @param jwt Pointer to a JWT object.
645  * @param fp Valid FILE pointer to write data to.
646  * @return Returns 0 on success, valid errno otherwise.
647  */
648 int jwt_encode_fp (jwt_t* jwt, FILE* fp);
649 
650 /**
651  * Fully encode a JWT object and return as a string.
652  *
653  * Similar to jwt_encode_fp() except that a string is returned. The string
654  * must be freed by the caller. If you changed the allocation method using
655  * jwt_set_alloc, then you must use jwt_free_str() to free the memory.
656  *
657  * @param jwt Pointer to a JWT object.
658  * @return A null terminated string on success, NULL on error with errno
659  *     set appropriately.
660  */
661 char* jwt_encode_str (jwt_t* jwt);
662 
663 /**
664  * Free a string returned from the library.
665  *
666  * @param str Pointer to a string previously created with
667  *     jwt_encode_str().
668  */
669 void jwt_free_str (char* str);
670 
671 /** @} */
672 
673 /**
674  * @defgroup jwt_alg JWT Algorithm Functions
675  * Set and check algorithms and algorithm specific values.
676  *
677  * When working with functions that require a key, the underlying library
678  * takes care to scrub memory when the key is no longer used (e.g. when
679  * calling jwt_free() or when changing the algorithm, the old key, if it
680  * exists, is scrubbed).
681  * @{
682  */
683 
684 /**
685  * Set an algorithm from jwt_alg_t for this JWT object.
686  *
687  * Specifies an algorithm for a JWT object. If JWT_ALG_NONE is used, then
688  * key must be NULL and len must be 0. All other algorithms must have a
689  * valid pointer to key data, which may be specific to the algorithm (e.g
690  * RS256 expects a PEM formatted RSA key).
691  *
692  * @param jwt Pointer to a JWT object.
693  * @param alg A valid jwt_alg_t specifier.
694  * @param key The key data to use for the algorithm.
695  * @param len The length of the key data.
696  * @return Returns 0 on success, valid errno otherwise.
697  */
698 int jwt_set_alg (jwt_t* jwt, jwt_alg_t alg, const(ubyte)* key, int len);
699 
700 /**
701  * Get the jwt_alg_t set for this JWT object.
702  *
703  * Returns the jwt_alg_t type for this JWT object.
704  *
705  * @param jwt Pointer to a JWT object.
706  * @returns Returns a jwt_alg_t type for this object.
707  */
708 jwt_alg_t jwt_get_alg (jwt_t* jwt);
709 
710 /**
711  * Convert alg type to it's string representation.
712  *
713  * Returns a string that matches the alg type provided.
714  *
715  * @param alg A valid jwt_alg_t specifier.
716  * @returns Returns a string (e.g. "RS256") matching the alg or NULL for
717  *     invalid alg.
718  */
719 const(char)* jwt_alg_str (jwt_alg_t alg);
720 
721 /**
722  * Convert alg string to type.
723  *
724  * Returns an alg type based on the string representation.
725  *
726  * @param alg A valid string algorithm type (e.g. "RS256").
727  * @returns Returns an alg type matching the string or JWT_ALG_INVAL if no
728  *     matches were found.
729  *
730  * Note, this only works for algorithms that LibJWT supports or knows about.
731  */
732 jwt_alg_t jwt_str_alg (const(char)* alg);
733 
734 /** @} */
735 
736 /**
737  * @defgroup jwt_memory JWT memory functions
738  * These functions allow you to get or set memory allocation functions.
739  * @{
740  */
741 
742 /**
743  * Set functions to be used for allocating and freeing memory.
744  *
745  * By default, LibJWT uses malloc, realloc, and free for memory
746  * management. This function allows the user of the library to
747  * specify its own memory management functions. This is especially
748  * useful on Windows where mismatches in runtimes across DLLs can
749  * cause problems.
750  *
751  * The caller can specify either a valid function pointer for
752  * any of the parameters or NULL to use the corresponding default
753  * allocator function.
754  *
755  * Note that this function will also set the memory allocator
756  * for the Jansson library.
757  *
758  * @param pmalloc The function to use for allocating memory or
759  *     NULL to use malloc
760  * @param prealloc The function to use for reallocating memory or
761  *     NULL to use realloc
762  * @param pfree The function to use for freeing memory or
763  *     NULL to use free
764  * @returns 0 on success or errno otherwise.
765  */
766 int jwt_set_alloc (jwt_malloc_t pmalloc, jwt_realloc_t prealloc, jwt_free_t pfree);
767 
768 /**
769  * Get functions used for allocating and freeing memory.
770  *
771  * @param pmalloc Pointer to malloc function output variable, or NULL
772  * @param prealloc Pointer to realloc function output variable, or NULL
773  * @param pfree Pointer to free function output variable, or NULL
774  */
775 void jwt_get_alloc (jwt_malloc_t* pmalloc, jwt_realloc_t* prealloc, jwt_free_t* pfree);
776 
777 /** @} */
778 
779 /**
780  * @defgroup jwt_vaildate JWT validation functions
781  * These functions allow you to define requirements for JWT validation.
782  *
783  * The most basic validation is that the JWT uses the expected algorithm.
784  *
785  * When replicating claims in header (usually for encrypted JWT), validation
786  * tests that they match claims in the body (iss, sub, aud).
787  *
788  * Time-based claims can also be validated (nbf, exp).
789  *
790  * Finally, validation can test that claims be present and have certain value.
791  *
792  * @{
793  */
794 
795 /**
796  * Validate a JWT object with a validation object.
797  *
798  * @param jwt Pointer to a JWT object.
799  * @param jwt_valid Pointer to a JWT validation object.
800  *
801  * @return bitwide OR if possible validation errors or 0 on success
802  */
803 uint jwt_validate (jwt_t* jwt, jwt_valid_t* jwt_valid);
804 
805 /**
806  * Allocate a new, JWT validation object.
807  *
808  * This is used to create a new object for a JWT validation. After you have
809  * finished with the object, use jwt_valid_free() to clean up the memory used by
810  * it.
811  *
812  * @param jwt_valid Pointer to a JWT validation object pointer. Will be allocated
813  *     on success.
814  * @return 0 on success, valid errno otherwise.
815  *
816  */
817 int jwt_valid_new (jwt_valid_t** jwt_valid, jwt_alg_t alg);
818 
819 /**
820  * Free a JWT validation object and any other resources it is using.
821  *
822  * After calling, the JWT validation object referenced will no longer be valid
823  * and its memory will be freed.
824  *
825  * @param jwt_valid Pointer to a JWT validation object previously created with
826  *     jwt_valid_new().
827  */
828 void jwt_valid_free (jwt_valid_t* jwt_valid);
829 
830 /**
831  * Return the status string for the validation object.
832  *
833  * The status of validation object is primarily for describing the reason
834  * jwt_validate() failed.
835  *
836  * @param jwt_valid Pointer to a JWT validation object.
837  * @return Returns current validation status as a bitwise OR of possible
838  *   errors, or 0 if validation is currently successful.
839  */
840 uint jwt_valid_get_status (jwt_valid_t* jwt_valid);
841 
842 /**
843  * Add a new string grant requirement to this JWT validation object.
844  *
845  * @param jwt_valid Pointer to a JWT validation object.
846  * @param grant String containing the name of the grant to add.
847  * @param val String containing the value to be saved for grant. Can be
848  *     an empty string, but cannot be NULL.
849  * @return Returns 0 on success, valid errno otherwise.
850  *
851  * Note, this only allows for string based grants. If you wish to add
852  * integer grants, then use jwt_valid_add_grant_int(). If you wish to add more
853  * complex grants (e.g. an array), then use jwt_valid_add_grants_json().
854  */
855 int jwt_valid_add_grant (jwt_valid_t* jwt_valid, const(char)* grant, const(char)* val);
856 
857 /**
858  * Return the value of a string required grant.
859  *
860  * Returns the string value for a grant (e.g. "iss"). If it does not exist,
861  * NULL will be returned.
862  *
863  * @param jwt_valid Pointer to a JWT validation object.
864  * @param grant String containing the name of the grant to return a value
865  *     for.
866  * @return Returns a string for the value, or NULL when not found.
867  *
868  * Note, this will only return grants with JSON string values. Use
869  * jwt_valid_get_grants_json() to get the JSON representation of more complex
870  * values (e.g. arrays) or use jwt_valid_get_grant_int() to get simple integer
871  * values.
872  */
873 const(char)* jwt_valid_get_grant (jwt_valid_t* jwt_valid, const(char)* grant);
874 
875 /**
876  * Add a new integer grant requirement to this JWT validation object.
877  *
878  * @param jwt_valid Pointer to a JWT validation object.
879  * @param grant String containing the name of the grant to add.
880  * @param val int containing the value to be saved for grant.
881  * @return Returns 0 on success, valid errno otherwise.
882  *
883  * Note, this only allows for integer based grants. If you wish to add
884  * string grants, then use jwt_valid_add_grant(). If you wish to add more
885  * complex grants (e.g. an array), then use jwt_valid_add_grants_json().
886  */
887 int jwt_valid_add_grant_int (jwt_valid_t* jwt_valid, const(char)* grant, c_long val);
888 
889 /**
890  * Return the value of an integer required grant.
891  *
892  * Returns the int value for a grant (e.g. "exp"). If it does not exist,
893  * 0 will be returned.
894  *
895  * @param jwt_valid Pointer to a JWT validation object.
896  * @param grant String containing the name of the grant to return a value
897  *     for.
898  * @return Returns an int for the value. Sets errno to ENOENT when not
899  * found.
900  *
901  * Note, this will only return grants with JSON integer values. Use
902  * jwt_valid_get_grants_json() to get the JSON representation of more complex
903  * values (e.g. arrays) or use jwt_valid_get_grant() to get string values.
904  */
905 c_long jwt_valid_get_grant_int (jwt_valid_t* jwt_valid, const(char)* grant);
906 
907 /**
908  * Add a new boolean required grant to this JWT validation object.
909  *
910  * Creates a new grant for this object. The string for grant
911  * is copied internally, so do not require that the pointer or string
912  * remain valid for the lifetime of this object. It is an error if you
913  * try to add a grant that already exists.
914  *
915  * @param jwt_valid Pointer to a JWT validation object.
916  * @param grant String containing the name of the grant to add.
917  * @param val boolean containing the value to be saved for grant.
918  * @return Returns 0 on success, valid errno otherwise.
919  *
920  * Note, this only allows for boolean based grants. If you wish to add
921  * string grants, then use jwt_valid_add_grant(). If you wish to add more
922  * complex grants (e.g. an array), then use jwt_valid_add_grants_json().
923  */
924 int jwt_valid_add_grant_bool (jwt_valid_t* jwt_valid, const(char)* grant, int val);
925 
926 /**
927  * Return the value of an boolean required grant.
928  *
929  * Returns the int value for a grant (e.g. "exp"). If it does not exist,
930  * 0 will be returned.
931  *
932  * @param jwt_valid Pointer to a JWT validation object.
933  * @param grant String containing the name of the grant to return a value
934  *     for.
935  * @return Returns a boolean for the value. Sets errno to ENOENT when not
936  * found.
937  *
938  * Note, this will only return grants with JSON boolean values. Use
939  * jwt_valid_get_grants_json() to get the JSON representation of more complex
940  * values (e.g. arrays) or use jwt_valid_get_grant() to get string values.
941  */
942 int jwt_valid_get_grant_bool (jwt_valid_t* jwt_valid, const(char)* grant);
943 
944 /**
945  * Add required grants from a JSON encoded object string.
946  *
947  * Loads a grant from an existing JSON encoded object string. Overwrites
948  * existing grant.
949  *
950  * @param jwt_valid Pointer to a JWT validation object.
951  * @param json String containing a JSON encoded object of grants.
952  * @return Returns 0 on success, valid errno otherwise.
953  */
954 int jwt_valid_add_grants_json (jwt_valid_t* jwt_valid, const(char)* json);
955 
956 /**
957  * Return the value of a grant as JSON encoded object string.
958  *
959  * Returns the JSON encoded string value for a grant (e.g. "iss"). If it
960  * does not exist, NULL will be returned.
961  *
962  * @param jwt_valid Pointer to a JWT validation object.
963  * @param grant String containing the name of the grant to return a value
964  *     for.
965  * @return Returns a string for the value, or NULL when not found. The
966  *     returned string must be freed by the caller.
967  */
968 char* jwt_valid_get_grants_json (jwt_valid_t* jwt_valid, const(char)* grant);
969 
970 /**
971  * Delete a grant from this JWT object.
972  *
973  * Deletes the named grant from this object. It is not an error if there
974  * is no grant matching the passed name. If grant is NULL, then all grants
975  * are deleted from this JWT.
976  *
977  * @param jwt_valid Pointer to a JWT validation object.
978  * @param grant String containing the name of the grant to delete. If this
979  *    is NULL, then all grants are deleted.
980  * @return Returns 0 on success, valid errno otherwise.
981  */
982 int jwt_valid_del_grants (jwt_valid_t* jwt, const(char)* grant);
983 
984 /**
985  * Set the time for which expires and not-before claims should be evaluated.
986  *
987  * @param jwt_valid Pointer to a JWT validation object.
988  * @param now Time to use when considering nbf and exp claims.
989  * @return Returns 0 on success, valid errno otherwise.
990  *
991  * @remark jwt_validate() will not fail based on time if no expires or
992  *     not-before claims exist in a JWT object.
993  */
994 int jwt_valid_set_now (jwt_valid_t* jwt_valid, const time_t now);
995 
996 /**
997  * Set validation for replicated claims in headers.
998  *
999  * When set, validation tests for presence of iss, sub, aud in jwt headers and
1000  * tests match for same claims in body.
1001  *
1002  * @param jwt_valid Pointer to a JWT validation object.
1003  * @param hdr When true, test header claims
1004  * @return Returns 0 on success, valid errno otherwise.
1005  *
1006  * @remark jwt_validate() will not fail if iss, sub, aud are not present in JWT
1007  *     header or body.
1008  */
1009 int jwt_valid_set_headers (jwt_valid_t* jwt_valid, int hdr);
1010 
1011 /** @} */
1012 
1013 /* JWT_H */