Completed
Push — master ( eaa085...85b293 )
by Jonathan
02:25
created

functions.php ➔ seal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
c 2
b 0
f 0
nc 1
nop 4
dl 0
loc 13
rs 9.4285
1
<?php
2
namespace Iron;
3
4
use InvalidArgumentException as Iae;
5
6
/**
7
 * @param mixed $data
8
 * @param string|PasswordInterface $password
9
 * @param integer $ttl
10
 * @param string $cipherMethod
11
 *
12
 * @return string
13
 */
14
function seal(
15
    $data,
16
    $password,
17
    int $ttl = 0,
18
    string $cipherMethod = Iron::DEFAULT_ENCRYPTION_METHOD
19
) {
20
    return (string) (new Iron($cipherMethod))
21
        ->encrypt(
22
            normalize_password($password), 
23
            json_encode($data), 
24
            $ttl
25
        );
26
}
27
28
/**
29
 * @param string $sealed
30
 * @param string|PasswordInterface $password
31
 * @param string $cipherMethod
32
 * @param callable $keyProvider
33
 * @param callable $saltGenerator
34
 *
35
 * @return mixed
36
 */
37
function unseal(
38
    string $sealed,
39
    $password,
40
    string $cipherMethod = Iron::DEFAULT_ENCRYPTION_METHOD,
41
    callable $keyProvider = null,
42
    callable $saltGenerator = null
43
) {
44
    $password = normalize_password($password);
45
    $token = Token::fromSealed(
46
        $password, 
47
        $sealed,
48
        true,
49
        $keyProvider ?: default_key_provider(),
50
        $saltGenerator ?: default_salt_generator()
51
    );
52
    
53
    $json = (new Iron($cipherMethod))
54
        ->decryptToken($token, $password);
55
    
56
    return json_decode($json, true);
57
}
58
59
function base64_encode(string $binary): string 
60
{
61
    return rtrim(strtr(\base64_encode($binary), [
62
        '+' => '-',
63
        '/' => '_',
64
    ]), '=');
65
}
66
67
function base64_decode(string $data): string 
68
{
69
    return \base64_decode(strtr($data, [
70
        '-' => '+',
71
        '_' => '/',
72
    ]));
73
}
74
75
function default_key_provider(): callable
76
{
77
    return __NAMESPACE__ . '\\generate_key';
78
}
79
80
/**
81
 * @param PasswordInterface $p
82
 * @param string $salt
83
 * @param int $length
84
 * @param int $iterations
85
 *
86
 * @return bool|string
87
 */
88
function generate_key(
89
    PasswordInterface $p,
90
    string $salt,
91
    int $length = 32,
92
    int $iterations = 1
93
): string {
94
    return hash_pbkdf2(
95
        'sha1',
96
        $p->getPassword(),
97
        $salt,
98
        $iterations,
99
        $length,
100
        true
101
    );
102
}
103
104
function default_salt_generator(): callable
105
{
106
    return __NAMESPACE__ . '\\generate_salt';
107
}
108
109
function generate_salt(int $length = 32): string
110
{
111
    return bin2hex(random_bytes($length));
112
}
113
114
/**
115
 * @param string|PasswordInterface $password
116
 *
117
 * @throws Iae
118
 *
119
 * @return PasswordInterface
120
 */
121
function normalize_password($password): PasswordInterface
122
{
123
    if (is_string($password)) {
124
        return new Password($password);
125
    }
126
127
    if ($password instanceof PasswordInterface) {
128
        return $password;
129
    }
130
131
    throw new Iae('Passwords must be strings or instances of'
132
        . ' Iron\\PasswordInterface');
133
}
134