Skip to content

Commit b90a600

Browse files
committed
Add none algorithm support
1 parent fa924ab commit b90a600

File tree

10 files changed

+132
-56
lines changed

10 files changed

+132
-56
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ $ make && make install
2323
## Quick Example
2424

2525
```php
26-
$key = "example_key";
27-
$claims = array(
26+
$key = "example-hmac-key";
27+
$payload = array(
2828
"data" => [
2929
"name" => "ZiHang Gao",
3030
"admin" => true
@@ -34,7 +34,7 @@ $claims = array(
3434
);
3535

3636
// default HS256 algorithm
37-
$token = jwt_encode($claims, $key);
37+
$token = jwt_encode($payload, $key);
3838

3939
echo $token . PHP_EOL;
4040
//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
@@ -63,14 +63,14 @@ Array
6363

6464
![Benchmarks](https://cdoco.com/images/jwt-benchmarks.png "Benchmarks")
6565

66-
## Methods
66+
## Functions
6767

6868
```php
6969
//encode
7070
string jwt_encode(array $claims, string $key [, string $alg = 'HS256'])
7171

7272
//decode
73-
array jwt_decode(string $token, string $key [, string $alg = 'HS256'])
73+
array jwt_decode(string $token, string $key [, array $options = ['algorithm' => 'HS256']])
7474
```
7575

7676
## The algorithm of support

example/ecdsa.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
-----END PUBLIC KEY-----
1818
EOD;
1919

20-
$claims = array(
20+
$payload = array(
2121
"data" => [
2222
"name" => "ZiHang Gao",
2323
"admin" => true
@@ -26,7 +26,7 @@
2626
"sub" => "1234567890",
2727
);
2828

29-
$token = jwt_encode($claims, $privateKey, 'ES256');
29+
$token = jwt_encode($payload, $privateKey, 'ES256');
3030

3131
echo $token . PHP_EOL;
32-
print_r(jwt_decode($token, $publicKey, 'ES256'));
32+
print_r(jwt_decode($token, $publicKey, ['algorithm' => 'ES256']));

example/hmac.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
$key = "example_key";
4-
$claims = array(
4+
$payload = array(
55
"data" => [
66
"name" => "ZiHang Gao",
77
"admin" => true
@@ -11,7 +11,7 @@
1111
);
1212

1313
// default HS256 algorithm
14-
$token = jwt_encode($claims, $key);
14+
$token = jwt_encode($payload, $key);
1515

1616
echo $token . PHP_EOL;
1717
print_r(jwt_decode($token, $key));

example/none.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
$payload = array(
4+
"data" => [
5+
"name" => "ZiHang Gao",
6+
"admin" => true
7+
],
8+
"iss" => "http://example.org",
9+
"sub" => "1234567890",
10+
);
11+
12+
// none algorithm
13+
$token = jwt_encode($payload, null, 'none');
14+
15+
echo $token . PHP_EOL;
16+
print_r(jwt_decode($token, null, false));

example/rsa.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
-----END PUBLIC KEY-----
2929
EOD;
3030

31-
$claims = array(
31+
$payload = array(
3232
"data" => [
3333
"name" => "ZiHang Gao",
3434
"admin" => true
@@ -37,7 +37,7 @@
3737
"sub" => "1234567890",
3838
);
3939

40-
$token = jwt_encode($claims, $privateKey, 'RS256');
40+
$token = jwt_encode($payload, $privateKey, 'RS256');
4141

4242
echo $token . PHP_EOL;
43-
print_r(jwt_decode($token, $publicKey, 'RS256'));
43+
print_r(jwt_decode($token, $publicKey, ['algorithm' => 'RS256']));

jwt.c

+60-35
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,13 @@ void jwt_parse_body(char *body, zval *return_value)
229229
zend_string_free(vs);
230230
}
231231

232-
233232
PHP_FUNCTION(jwt_encode)
234233
{
235234
zval *claims = NULL, header;
236235
zend_string *key = NULL;
237236
smart_str json_header = {0}, json_claims = {0}, segments = {0};
238237

239-
char *sig = NULL, *alg = NULL;
238+
char *sig = NULL, *alg = "HS256";
240239
unsigned int sig_len;
241240
size_t alg_len;
242241
jwt_t *jwt = NULL;
@@ -248,9 +247,6 @@ PHP_FUNCTION(jwt_encode)
248247
/* init jwt */
249248
jwt_new(&jwt);
250249

251-
/* not set algorithm */
252-
alg = (alg == NULL) ? "HS256" : alg;
253-
254250
/* check algorithm */
255251
jwt->alg = jwt_str_alg(alg);
256252

@@ -280,23 +276,29 @@ PHP_FUNCTION(jwt_encode)
280276
smart_str_free(&json_header);
281277
smart_str_free(&json_claims);
282278

283-
/* set jwt struct */
284-
jwt->key = key;
285-
jwt->str = segments.s;
286-
287279
/* sign */
288-
if (jwt_sign(jwt, &sig, &sig_len)) {
289-
zend_throw_exception(zend_ce_exception, "Signature error", 0);
290-
goto encode_done;
291-
}
280+
if (jwt->alg == JWT_ALG_NONE) {
281+
// alg none.
282+
smart_str_appendl(&segments, ".", 1);
283+
} else {
284+
/* set jwt struct */
285+
jwt->key = key;
286+
jwt->str = segments.s;
287+
288+
/* sign */
289+
if (jwt_sign(jwt, &sig, &sig_len)) {
290+
zend_throw_exception(zend_ce_exception, "Signature error", 0);
291+
goto encode_done;
292+
}
292293

293-
/* string concatenation */
294-
smart_str_appends(&segments, ".");
294+
/* string concatenation */
295+
smart_str_appends(&segments, ".");
295296

296-
zend_string *sig_str = zend_string_init(sig, sig_len, 0);
297+
zend_string *sig_str = zend_string_init(sig, sig_len, 0);
297298

298-
smart_str_appends(&segments, jwt_b64_url_encode(sig_str));
299-
zend_string_free(sig_str);
299+
smart_str_appends(&segments, jwt_b64_url_encode(sig_str));
300+
zend_string_free(sig_str);
301+
}
300302

301303
smart_str_0(&segments);
302304

@@ -315,24 +317,42 @@ PHP_FUNCTION(jwt_encode)
315317
PHP_FUNCTION(jwt_decode)
316318
{
317319
zend_string *token = NULL, *key = NULL;
320+
zval *options = NULL;
318321
smart_str segments = {0};
319-
char *alg = NULL, *body = NULL, *sig = NULL;
320-
size_t alg_len;
322+
char *alg = "HS256", *body = NULL, *sig = NULL;
321323
jwt_t *jwt = NULL;
322324

323-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|s", &token, &key, &alg, &alg_len) == FAILURE) {
325+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|z", &token, &key, &options) == FAILURE) {
324326
return;
325327
}
326328

327-
/* not set algorithm */
328-
alg = (alg == NULL) ? "HS256" : alg;
329-
330329
char *head = estrdup(ZSTR_VAL(token));
331330

332331
/* jwt init */
333332
jwt_new(&jwt);
334333

335-
/* check algorithm */
334+
/* check options */
335+
if (options != NULL) {
336+
switch(Z_TYPE_P(options)) {
337+
case IS_ARRAY:
338+
/* check algorithm */
339+
{
340+
zval *zv_algorithm = zend_hash_str_find(Z_ARRVAL_P(options), "algorithm", strlen("algorithm"));
341+
if (zv_algorithm != NULL) {
342+
alg = Z_STRVAL_P(zv_algorithm);
343+
}
344+
}
345+
break;
346+
case IS_NULL:
347+
case IS_FALSE:
348+
alg = "none";
349+
break;
350+
default:
351+
php_error(E_ERROR, "jwt wrong zval type");
352+
break;
353+
}
354+
}
355+
336356
jwt->alg = jwt_str_alg(alg);
337357

338358
if (jwt->alg == JWT_ALG_INVAL) {
@@ -388,17 +408,22 @@ PHP_FUNCTION(jwt_decode)
388408
/* parse body */
389409
jwt_parse_body(body, return_value);
390410

391-
/* set jwt struct */
392-
jwt->key = key;
411+
/* verify */
412+
if (jwt->alg == JWT_ALG_NONE) {
413+
/* done */
414+
} else {
415+
/* set jwt struct */
416+
jwt->key = key;
393417

394-
smart_str_appends(&segments, head);
395-
smart_str_appends(&segments, ".");
396-
smart_str_appends(&segments, body);
418+
smart_str_appends(&segments, head);
419+
smart_str_appends(&segments, ".");
420+
smart_str_appends(&segments, body);
397421

398-
jwt->str = segments.s;
422+
jwt->str = segments.s;
399423

400-
if (jwt_verify(jwt, sig)) {
401-
zend_throw_exception(zend_ce_exception, "Signature verification failed", 0);
424+
if (jwt_verify(jwt, sig)) {
425+
zend_throw_exception(zend_ce_exception, "Signature verification failed", 0);
426+
}
402427
}
403428

404429
smart_str_free(&segments);
@@ -438,14 +463,14 @@ PHP_MINFO_FUNCTION(jwt)
438463
php_info_print_table_end();
439464
}
440465

441-
static const zend_module_dep jwt_dep_deps[] = {
466+
static const zend_module_dep jwt_deps[] = {
442467
ZEND_MOD_REQUIRED("json")
443468
ZEND_MOD_END
444469
};
445470

446471
zend_module_entry jwt_module_entry = {
447472
STANDARD_MODULE_HEADER_EX, NULL,
448-
jwt_dep_deps,
473+
jwt_deps,
449474
"jwt",
450475
jwt_functions,
451476
PHP_MINIT(jwt),

tests/002.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Check for jwt HMAC algorithm (HS256)
55
--FILE--
66
<?php
77
$key = "example_key";
8-
$claims = array(
8+
$payload = array(
99
"data" => [
1010
"name" => "ZiHang Gao",
1111
"admin" => true
@@ -14,7 +14,7 @@ $claims = array(
1414
"sub" => "1234567890",
1515
);
1616

17-
$token = jwt_encode($claims, $key);
17+
$token = jwt_encode($payload, $key);
1818

1919
echo $token . PHP_EOL;
2020
print_r(jwt_decode($token, $key));

tests/003.phpt

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ UnR8tSdwUqI3119zAQIDAQAB
3232
-----END PUBLIC KEY-----
3333
EOD;
3434

35-
$claims = array(
35+
$payload = array(
3636
"data" => [
3737
"name" => "ZiHang Gao",
3838
"admin" => true
@@ -41,10 +41,10 @@ $claims = array(
4141
"sub" => "1234567890",
4242
);
4343

44-
$token = jwt_encode($claims, $privateKey, 'RS256');
44+
$token = jwt_encode($payload, $privateKey, 'RS256');
4545

4646
echo $token . PHP_EOL;
47-
print_r(jwt_decode($token, $publicKey, 'RS256'));
47+
print_r(jwt_decode($token, $publicKey, ['algorithm' => 'RS256']));
4848
?>
4949
--EXPECT--
5050
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJkYXRhIjp7Im5hbWUiOiJaaUhhbmcgR2FvIiwiYWRtaW4iOnRydWV9LCJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsInN1YiI6IjEyMzQ1Njc4OTAifQ.iSpiBRxW0RKDK0KZRDTwEQmllzkS-WQKMzQ8j3pSSA8NI3ukj0EjZCWIsWfgmb20xKViT5UhUAf_1UQwxwu5k0laEkJ8Ze04gj1P8KO--7BkxUFp4UerkDex49lwHSJmvTJBRZBy9t7BDqCaouEpUe0vZ6z_siMX95VMvVrk0g0

tests/004.phpt

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ qN3tlSZmUEZ3w3c6KYJfK97PMOSZQaUdeydBoq/IOglQQOj8zLqubq5IpaaUiDQ5
2121
-----END PUBLIC KEY-----
2222
EOD;
2323

24-
$claims = array(
24+
$payload = array(
2525
"data" => [
2626
"name" => "ZiHang Gao",
2727
"admin" => true
@@ -30,8 +30,8 @@ $claims = array(
3030
"sub" => "1234567890",
3131
);
3232

33-
$token = jwt_encode($claims, $privateKey, 'ES256');
34-
print_r(jwt_decode($token, $publicKey, 'ES256'));
33+
$token = jwt_encode($payload, $privateKey, 'ES256');
34+
print_r(jwt_decode($token, $publicKey, ['algorithm' => 'ES256']));
3535
?>
3636
--EXPECT--
3737
Array

tests/005.phpt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
Check for jwt none algorithm
3+
--SKIPIF--
4+
<?php if (!extension_loaded("jwt")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
$payload = array(
9+
"data" => [
10+
"name" => "ZiHang Gao",
11+
"admin" => true
12+
],
13+
"iss" => "http://example.org",
14+
"sub" => "1234567890",
15+
);
16+
17+
// none algorithm
18+
$token = jwt_encode($payload, null, 'none');
19+
20+
echo $token . PHP_EOL;
21+
print_r(jwt_decode($token, null, false));
22+
?>
23+
--EXPECT--
24+
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJkYXRhIjp7Im5hbWUiOiJaaUhhbmcgR2FvIiwiYWRtaW4iOnRydWV9LCJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsInN1YiI6IjEyMzQ1Njc4OTAifQ.
25+
Array
26+
(
27+
[data] => Array
28+
(
29+
[name] => ZiHang Gao
30+
[admin] => 1
31+
)
32+
33+
[iss] => http://example.org
34+
[sub] => 1234567890
35+
)

0 commit comments

Comments
 (0)