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 */