27
27
28
28
#include "zend_smart_str.h"
29
29
#include "zend_exceptions.h"
30
+ #include "ext/spl/spl_exceptions.h"
30
31
#include "ext/json/php_json.h"
31
32
#include "ext/standard/base64.h"
32
33
#include "ext/standard/info.h"
37
38
38
39
#include "php_jwt.h"
39
40
41
+ /* Exceptions */
42
+ PHP_JWT_API zend_class_entry * jwt_signature_invalid_cex ;
43
+ PHP_JWT_API zend_class_entry * jwt_before_valid_cex ;
44
+ PHP_JWT_API zend_class_entry * jwt_expired_signature_cex ;
45
+ PHP_JWT_API zend_class_entry * jwt_invalid_issuer_cex ;
46
+ PHP_JWT_API zend_class_entry * jwt_invalid_aud_cex ;
47
+ PHP_JWT_API zend_class_entry * jwt_invalid_jti_cex ;
48
+ PHP_JWT_API zend_class_entry * jwt_invalid_iat_cex ;
49
+ PHP_JWT_API zend_class_entry * jwt_invalid_sub_cex ;
50
+
40
51
ZEND_DECLARE_MODULE_GLOBALS (jwt )
41
52
42
53
/* string to algorithm */
@@ -300,14 +311,15 @@ int jwt_array_equals(zend_array *arr1, zend_array *arr2) {
300
311
php_error_docref (NULL , E_WARNING , "Aud each item type must be string" );
301
312
}
302
313
}
303
- }ZEND_HASH_FOREACH_END ();
314
+ } ZEND_HASH_FOREACH_END ();
304
315
}
305
316
306
317
return 0 ;
307
318
}
308
319
309
320
int jwt_verify_body (char * body , zval * return_value )
310
321
{
322
+ zend_class_entry * ce ;
311
323
char * err_msg = NULL ;
312
324
time_t curr_time = time ((time_t * )NULL );
313
325
zend_string * vs = jwt_b64_url_decode (body );
@@ -317,8 +329,10 @@ int jwt_verify_body(char *body, zval *return_value)
317
329
zend_string_free (vs );
318
330
319
331
/* Expiration */
320
- if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration ))
332
+ if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration )) {
333
+ ce = jwt_expired_signature_cex ;
321
334
err_msg = "Expired token" ;
335
+ }
322
336
323
337
/* not before */
324
338
if (JWT_G (not_before ) && JWT_G (not_before ) > (curr_time + JWT_G (leeway ))) {
@@ -327,12 +341,15 @@ int jwt_verify_body(char *body, zval *return_value)
327
341
328
342
timeinfo = localtime (& JWT_G (not_before ));
329
343
strftime (buf , sizeof (buf ), "Cannot handle token prior to %Y-%m-%d %H:%M:%S" , timeinfo );
344
+ ce = jwt_before_valid_cex ;
330
345
err_msg = buf ;
331
346
}
332
347
333
348
/* iss */
334
- if (jwt_verify_claims (return_value , "iss" , JWT_G (iss )))
335
- err_msg = "Iss verify fail" ;
349
+ if (jwt_verify_claims (return_value , "iss" , JWT_G (iss ))) {
350
+ ce = jwt_invalid_issuer_cex ;
351
+ err_msg = "Invalid Issuer" ;
352
+ }
336
353
337
354
/* iat */
338
355
if (JWT_G (iat ) && JWT_G (iat ) > (curr_time + JWT_G (leeway ))) {
@@ -341,23 +358,30 @@ int jwt_verify_body(char *body, zval *return_value)
341
358
342
359
timeinfo = localtime (& JWT_G (iat ));
343
360
strftime (buf , sizeof (buf ), "Cannot handle token prior to %Y-%m-%d %H:%M:%S" , timeinfo );
361
+ ce = jwt_invalid_iat_cex ;
344
362
err_msg = buf ;
345
363
}
346
364
347
365
/* jti */
348
- if (jwt_verify_claims (return_value , "jti" , JWT_G (jti )))
349
- err_msg = "Tti verify fail" ;
366
+ if (jwt_verify_claims (return_value , "jti" , JWT_G (jti ))) {
367
+ ce = jwt_invalid_jti_cex ;
368
+ err_msg = "Invalid Jti" ;
369
+ }
350
370
351
371
/* aud */
352
- if (jwt_array_equals (JWT_G (aud ), jwt_hash_str_find_ht (return_value , "aud" )))
353
- err_msg = "Aud verify fail" ;
372
+ if (jwt_array_equals (JWT_G (aud ), jwt_hash_str_find_ht (return_value , "aud" ))) {
373
+ ce = jwt_invalid_aud_cex ;
374
+ err_msg = "Invalid Aud" ;
375
+ }
354
376
355
377
/* sub */
356
- if (jwt_verify_claims (return_value , "sub" , JWT_G (sub )))
357
- err_msg = "Sub verify fail" ;
378
+ if (jwt_verify_claims (return_value , "sub" , JWT_G (sub ))) {
379
+ ce = jwt_invalid_sub_cex ;
380
+ err_msg = "Invalid Sub" ;
381
+ }
358
382
359
383
if (err_msg ) {
360
- zend_throw_exception (zend_ce_exception , err_msg , 0 );
384
+ zend_throw_exception (ce , err_msg , 0 );
361
385
return FAILURE ;
362
386
}
363
387
@@ -419,7 +443,7 @@ PHP_FUNCTION(jwt_encode)
419
443
jwt -> alg = jwt_str_alg (alg );
420
444
421
445
if (jwt -> alg == JWT_ALG_INVAL ) {
422
- zend_throw_exception (zend_ce_exception , "Algorithm not supported" , 0 );
446
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Algorithm not supported" , 0 );
423
447
goto encode_done ;
424
448
}
425
449
@@ -451,16 +475,16 @@ PHP_FUNCTION(jwt_encode)
451
475
452
476
/* sign */
453
477
if (jwt -> alg == JWT_ALG_NONE ) {
454
- // alg none.
455
- smart_str_appendl (& segments , "." , 1 );
478
+ /* alg none */
479
+ smart_str_appendl (& segments , "." , 1 );
456
480
} else {
457
481
/* set jwt struct */
458
482
jwt -> key = key ;
459
483
jwt -> str = segments .s ;
460
484
461
485
/* sign */
462
486
if (jwt_sign (jwt , & sig , & sig_len )) {
463
- zend_throw_exception (zend_ce_exception , "Signature error " , 0 );
487
+ zend_throw_exception (spl_ce_DomainException , "OpenSSL unable to sign data " , 0 );
464
488
goto encode_done ;
465
489
}
466
490
@@ -506,15 +530,15 @@ PHP_FUNCTION(jwt_decode)
506
530
507
531
/* Parse options */
508
532
if (jwt_parse_options (options ) == FAILURE ) {
509
- zend_throw_exception (zend_ce_exception , "Options parse error" , 0 );
533
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Options parse error" , 0 );
510
534
goto decode_done ;
511
535
}
512
536
513
537
/* Algorithm */
514
538
jwt -> alg = jwt_str_alg (JWT_G (algorithm ));
515
539
516
540
if (jwt -> alg == JWT_ALG_INVAL ) {
517
- zend_throw_exception (zend_ce_exception , "Algorithm not supported" , 0 );
541
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Algorithm not supported" , 0 );
518
542
goto decode_done ;
519
543
}
520
544
@@ -542,7 +566,7 @@ PHP_FUNCTION(jwt_decode)
542
566
zend_string * json_h = jwt_b64_url_decode (head );
543
567
544
568
if (!json_h ) {
545
- zend_throw_exception (zend_ce_exception , "Base64 decode error" , 0 );
569
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Base64 decode error" , 0 );
546
570
goto decode_done ;
547
571
}
548
572
@@ -555,11 +579,11 @@ PHP_FUNCTION(jwt_decode)
555
579
zval_ptr_dtor (& zv );
556
580
557
581
if (strcmp (Z_STRVAL_P (zalg ), JWT_G (algorithm ))) {
558
- zend_throw_exception (zend_ce_exception , "Algorithm not allowed" , 0 );
582
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Algorithm not allowed" , 0 );
559
583
goto decode_done ;
560
584
}
561
585
} else {
562
- zend_throw_exception (zend_ce_exception , "Json decode error" , 0 );
586
+ zend_throw_exception (spl_ce_UnexpectedValueException , "Json decode error" , 0 );
563
587
goto decode_done ;
564
588
}
565
589
@@ -582,7 +606,7 @@ PHP_FUNCTION(jwt_decode)
582
606
jwt -> str = segments .s ;
583
607
584
608
if (jwt_verify (jwt , sig )) {
585
- zend_throw_exception (zend_ce_exception , "Signature verification failed" , 0 );
609
+ zend_throw_exception (jwt_signature_invalid_cex , "Signature verification failed" , 0 );
586
610
}
587
611
}
588
612
@@ -614,6 +638,40 @@ PHP_GINIT_FUNCTION(jwt) {
614
638
615
639
PHP_MINIT_FUNCTION (jwt )
616
640
{
641
+ zend_class_entry ce ;
642
+
643
+ /* SignatureInvalidException */
644
+ INIT_CLASS_ENTRY (ce , "SignatureInvalidException" , NULL );
645
+ jwt_signature_invalid_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
646
+
647
+ /* BeforeValidException */
648
+ INIT_CLASS_ENTRY (ce , "BeforeValidException" , NULL );
649
+ jwt_before_valid_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
650
+
651
+ /* ExpiredSignatureException */
652
+ INIT_CLASS_ENTRY (ce , "ExpiredSignatureException" , NULL );
653
+ jwt_expired_signature_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
654
+
655
+ /* InvalidIssuerException */
656
+ INIT_CLASS_ENTRY (ce , "InvalidIssuerException" , NULL );
657
+ jwt_invalid_issuer_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
658
+
659
+ /* InvalidAudException */
660
+ INIT_CLASS_ENTRY (ce , "InvalidAudException" , NULL );
661
+ jwt_invalid_aud_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
662
+
663
+ /* InvalidJtiException */
664
+ INIT_CLASS_ENTRY (ce , "InvalidJtiException" , NULL );
665
+ jwt_invalid_jti_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
666
+
667
+ /* InvalidIatException */
668
+ INIT_CLASS_ENTRY (ce , "InvalidIatException" , NULL );
669
+ jwt_invalid_iat_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
670
+
671
+ /* InvalidSubException */
672
+ INIT_CLASS_ENTRY (ce , "InvalidSubException" , NULL );
673
+ jwt_invalid_sub_cex = zend_register_internal_class_ex (& ce , zend_ce_exception );
674
+
617
675
return SUCCESS ;
618
676
}
619
677
0 commit comments