Skip to content

Commit a02ec51

Browse files
committed
Basic authentication, crypto and randomness stuff
1 parent 2299f6a commit a02ec51

File tree

6 files changed

+402
-85
lines changed

6 files changed

+402
-85
lines changed

Crypto.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?PHP
2+
/*-
3+
* Copyright (c) 2018 Etienne Bagnoud <[email protected]>
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25+
* SUCH DAMAGE.
26+
*/
27+
Namespace artnum;
28+
29+
/* Mainly to initialize and abstract algo while using algo available in Stanford Javascript Crypto Library https://bitwiseshiftleft.github.io/sjcl/ */
30+
class Crypto {
31+
private $HAlgo;
32+
private $CAlgo;
33+
34+
function __construct($halgo = NULL, $calgo = NULL) {
35+
if (is_null($halgo)) {
36+
$this->HAlgo = 'sha1';
37+
$algos = hash_algos();
38+
/* select strongest hash function */
39+
foreach (array('sha512', 'sha256') as $hash) {
40+
if (in_array($hash, $algos)) {
41+
$this->HAlgo = $hash;
42+
break;
43+
}
44+
}
45+
} else {
46+
$this->HAlgo = $halgo;
47+
}
48+
49+
if (is_null($calgo)) {
50+
$this->CAlgo = 'aes-128-cbc';
51+
$algos = openssl_get_cipher_methods();
52+
foreach (array('aes-256-cbc', 'aes-192-cbc') as $cipher) {
53+
if (in_array($cipher, $algos)) {
54+
$this->CAlgo = $cipher;
55+
break;
56+
}
57+
}
58+
} else {
59+
$this->CAlgo = $calgo;
60+
}
61+
}
62+
63+
function gethalgo() {
64+
return $this->HAlgo;
65+
}
66+
67+
function getcalgo() {
68+
return $this->CAlgo;
69+
}
70+
71+
/* hmac */
72+
function hmac($value, $key) {
73+
$signed = hash_hmac($this->HAlgo, $value, $key, true);
74+
return array(base64_encode($signed), $this->HAlgo);
75+
}
76+
77+
function hash($value) {
78+
$hashed = hash($this->HAlgo, $value, true);
79+
return array(base64_encode($hashed), $this->HAlgo);
80+
}
81+
82+
function compare($value1, $value2) {
83+
if (function_exists('hash_equals')) {
84+
return hash_equals($value1, $value2);
85+
} else {
86+
return strcmp($value1, $value2) == 0;
87+
}
88+
}
89+
90+
/* Symmetric encryption/decryption */
91+
function sencrypt($value, $key) {
92+
$iv = '';
93+
if (openssl_cipher_iv_length($this->CAlgo)) {
94+
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($this->CAlgo));
95+
}
96+
$crypted = openssl_encrypt($value, $this->CAlgo, $key, OPENSSL_RAW_DATA, $iv);
97+
return array($crypted, $iv, $this->CAlgo);
98+
}
99+
100+
function sdecrypt($crypted, $key, $iv = '') {
101+
$value = openssl_decrypt($crypted, $this->CAlgo, $key, OPENSSL_RAW_DATA, $iv);
102+
return $value;
103+
}
104+
}
105+
?>

Files.php

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,52 @@
2929
class Files {
3030
/* Write data to file if it's writable */
3131
function toFile ($content, $file) {
32-
$write = false;
33-
if (!file_exists($file)) {
32+
if ($this->writable($file)) {
33+
return file_put_contents($file, $content);
34+
}
35+
return false;
36+
}
37+
38+
/* check if file is writable, if file doesn't exist, check if the directory is writable */
39+
function writable($file) {
40+
if (file_exists($file) && is_file($file) && is_writable($file)) {
41+
return true;
42+
} else {
3443
if (is_dir(dirname($file)) && is_writable(dirname($file))) {
35-
$write = true;
44+
return true;
3645
}
37-
} else {
38-
if (is_writable($file) && is_file($file)) {
39-
$write = true;
46+
}
47+
return false;
48+
}
49+
50+
/* alias */
51+
function writeable($file) {
52+
return $this->writable($file);
53+
}
54+
55+
/* verify if file exists and is readable but if file doesn't exist, check if it could be written */
56+
function mayExist($file) {
57+
if (file_exists($file)) {
58+
if ($this->readable($file)) {
59+
return true;
4060
}
4161
}
62+
if ($this->writeable($file)) {
63+
return true;
64+
}
65+
return false;
66+
}
67+
68+
function readable($file) {
69+
if (file_exists($file) && is_file($file) && is_readable($file)) {
70+
return true;
71+
}
72+
return false;
73+
}
4274

43-
if ($write) {
44-
return file_put_contents($file, $content);
75+
function fromFile($file) {
76+
if ($this->readable($file)) {
77+
return file_get_contents($file);
4578
}
4679
return false;
4780
}

JStore/Auth.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?PHP
2+
/*-
3+
* Copyright (c) 2018 Etienne Bagnoud <[email protected]>
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25+
* SUCH DAMAGE.
26+
*/
27+
Namespace artnum\JStore;
28+
29+
class Auth {
30+
function __construct($session, $user) {
31+
$this->Session = $session;
32+
$this->UserInterface = $user;
33+
$this->Random = new \artnum\Random();
34+
$this->Crypto = new \artnum\Crypto('sha256');
35+
}
36+
37+
function getName() {
38+
return 'Artnum.GenericAuth';
39+
}
40+
41+
function handle($request) {
42+
switch($request->getVerb()) {
43+
case 'POST':
44+
case 'GET':
45+
return $this->authenticate($request);
46+
case 'PATCH':
47+
return $this->update($request);
48+
}
49+
50+
return false;
51+
}
52+
53+
function verify($request) {
54+
return $this->Session->set('auth-valid');
55+
}
56+
57+
function authorize($request) {
58+
/* todo autorization part */
59+
return $this->verify($request);
60+
}
61+
62+
/* set password */
63+
function update($request) {
64+
return;
65+
}
66+
67+
function authenticate($request) {
68+
if ($request->getVerb() == 'GET') {
69+
$challenge = $this->Random->str(128);
70+
if (!$challenge) {
71+
return -1;
72+
}
73+
$this->Session->set('auth-challenge', $challenge);
74+
75+
$sleep = $this->UserInterface->fail('get', $request->getItem());
76+
usleep(10000 * $sleep);
77+
78+
return array('challenge' => $challenge);
79+
} else if ($request->getVerb() == 'POST') {
80+
/* second pass */
81+
$key = $this->Random->str(256);
82+
$_key = $this->UserInterface->getkey($request->getItem());
83+
if (!is_null($_key)) {
84+
$key = $_key;
85+
}
86+
87+
if ($this->Crypto->compare($this->Crypto->hmac($this->Session->get('auth-challenge'), $key)[0], $request->getParameter('response'))) {
88+
$this->UserInterface->fail('reset', $request->getItem());
89+
$this->Session->set('auth-valid', true);
90+
return array('auth-success' => true);
91+
} else {
92+
$this->UserInterface->fail('inc', $request->getItem());
93+
$this->Session->set('auth-valid', true);
94+
return array('auth-success' => false);
95+
}
96+
}
97+
}
98+
}
99+
100+
?>

0 commit comments

Comments
 (0)