@@ -225,49 +225,106 @@ zend_string *jwt_b64_url_decode(const char *src)
225225
226226char * jwt_hash_str_find_str (zval * arr , char * key )
227227{
228- char * str = NULL ;
228+ char * str = NULL , err_msg [ 128 ] ;
229229 zval * zv = zend_hash_str_find (Z_ARRVAL_P (arr ), key , strlen (key ));
230230
231231 if (zv != NULL ) {
232- str = Z_STRVAL_P (zv );
233- }
232+ if (Z_TYPE_P (zv ) == IS_STRING ) {
233+ str = Z_STRVAL_P (zv );
234+ } else {
235+ sprintf (err_msg , "%s type must be string" , key );
236+ zend_throw_exception (zend_ce_exception , err_msg , 0 );
237+ }
238+ }
234239
235240 return str ;
236241}
237242
238243long jwt_hash_str_find_long (zval * arr , char * key )
239244{
245+ char err_msg [128 ];
240246 zval * zv = zend_hash_str_find (Z_ARRVAL_P (arr ), key , strlen (key ));
241247
242248 if (zv != NULL ) {
243- return Z_LVAL_P (zv );
249+ if (Z_TYPE_P (zv ) == IS_LONG ) {
250+ return Z_LVAL_P (zv );
251+ } else {
252+ sprintf (err_msg , "%s type must be long" , key );
253+ zend_throw_exception (zend_ce_exception , err_msg , 0 );
254+ }
244255 }
245256
246257 return 0 ;
247258}
248259
260+ zend_array * jwt_hash_str_find_ht (zval * arr , char * key )
261+ {
262+ char err_msg [128 ];
263+ zval * zv = zend_hash_str_find (Z_ARRVAL_P (arr ), key , strlen (key ));
264+
265+ if (zv != NULL ) {
266+ if (Z_TYPE_P (zv ) == IS_ARRAY ) {
267+ return Z_ARRVAL_P (zv );
268+ } else {
269+ sprintf (err_msg , "%s type must be array" , key );
270+ zend_throw_exception (zend_ce_exception , err_msg , 0 );
271+ }
272+ }
273+
274+ return NULL ;
275+ }
276+
249277int jwt_verify_claims (zval * arr , char * key , char * str )
250278{
251279 char * rs = jwt_hash_str_find_str (arr , key );
252- if (rs && strcmp (rs , str )) {
280+ if (rs && str && strcmp (rs , str )) {
253281 return FAILURE ;
254282 }
255283
256284 return 0 ;
257285}
258286
287+ int jwt_array_equals (zend_array * arr1 , zend_array * arr2 ) {
288+ zend_ulong i ;
289+ zval * value = NULL ;
290+
291+ if (arr1 && arr2 ) {
292+ if (zend_array_count (arr1 ) != zend_array_count (arr2 )) {
293+ return FAILURE ;
294+ }
295+
296+ ZEND_HASH_FOREACH_NUM_KEY_VAL (arr1 , i , value ) {
297+ zval * tmp = zend_hash_index_find (arr2 , i );
298+
299+ if (value && tmp ){
300+ if (Z_TYPE_P (value ) == IS_STRING && Z_TYPE_P (tmp ) == IS_STRING ) {
301+ if (strcmp (Z_STRVAL_P (value ), Z_STRVAL_P (tmp ))) {
302+ return FAILURE ;
303+ }
304+ } else {
305+ zend_throw_exception (zend_ce_exception , "Aud each item type must be string" , 0 );
306+ return FAILURE ;
307+ }
308+ }
309+ }ZEND_HASH_FOREACH_END ();
310+ }
311+
312+ return 0 ;
313+ }
314+
259315int jwt_verify_body (char * body , zval * return_value )
260316{
261317 char * err_msg = NULL ;
262318 time_t curr_time = time ((time_t * )NULL );
263319 zend_string * vs = jwt_b64_url_decode (body );
320+
321+ /* decode json to array */
264322 php_json_decode_ex (return_value , ZSTR_VAL (vs ), ZSTR_LEN (vs ), PHP_JSON_OBJECT_AS_ARRAY , 512 );
265323 zend_string_free (vs );
266324
267325 /* Expiration */
268- if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration )) {
326+ if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration ))
269327 err_msg = "Expired token" ;
270- }
271328
272329 /* not before */
273330 if (JWT_G (not_before ) && JWT_G (not_before ) > (curr_time + JWT_G (leeway ))) {
@@ -280,7 +337,7 @@ int jwt_verify_body(char *body, zval *return_value)
280337 }
281338
282339 /* iss */
283- if (JWT_G ( iss ) && jwt_verify_claims (return_value , "iss" , JWT_G (iss )))
340+ if (jwt_verify_claims (return_value , "iss" , JWT_G (iss )))
284341 err_msg = "Iss verify fail" ;
285342
286343 /* iat */
@@ -294,15 +351,15 @@ int jwt_verify_body(char *body, zval *return_value)
294351 }
295352
296353 /* jti */
297- if (JWT_G ( jti ) && jwt_verify_claims (return_value , "jti" , JWT_G (jti )))
354+ if (jwt_verify_claims (return_value , "jti" , JWT_G (jti )))
298355 err_msg = "Tti verify fail" ;
299356
300357 /* aud */
301- if (JWT_G (aud ) && jwt_verify_claims (return_value , "aud" , JWT_G ( aud )))
358+ if (jwt_array_equals ( JWT_G (aud ), jwt_hash_str_find_ht (return_value , "aud" )))
302359 err_msg = "Aud verify fail" ;
303360
304361 /* sub */
305- if (JWT_G ( sub ) && jwt_verify_claims (return_value , "sub" , JWT_G (sub )))
362+ if (jwt_verify_claims (return_value , "sub" , JWT_G (sub )))
306363 err_msg = "Sub verify fail" ;
307364
308365 if (err_msg ) {
@@ -330,7 +387,7 @@ int jwt_parse_options(zval *options)
330387 JWT_G (leeway ) = jwt_hash_str_find_long (options , "leeway" );
331388 JWT_G (iss ) = jwt_hash_str_find_str (options , "iss" );
332389 JWT_G (jti ) = jwt_hash_str_find_str (options , "jti" );
333- JWT_G (aud ) = jwt_hash_str_find_str (options , "aud" );
390+ JWT_G (aud ) = jwt_hash_str_find_ht (options , "aud" );
334391 JWT_G (sub ) = jwt_hash_str_find_str (options , "sub" );
335392 }
336393 break ;
0 commit comments