Completed
Push — master ( 1a6759...15a726 )
by Florent
03:45
created

PBES2AESKW::getKeyManagementMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose\Algorithm\KeyEncryption;
13
14
use Base64Url\Base64Url;
15
use Jose\Object\JWKInterface;
16
17
/**
18
 * Class PBES2AESKW.
19
 */
20
abstract class PBES2AESKW implements KeyEncryptionInterface
21
{
22
    /**
23
     * @var int
24
     */
25
    private $salt_size;
26
    
27
    /**
28
     * @var int
29
     */
30
    private $nb_count;
31
    
32
    /**
33
     * @param int $salt_size
34
     * @param int $nb_count
35
     */
36
    public function __construct($salt_size = 64, $nb_count = 4096)
37
    {
38
        $this->salt_size = $salt_size;
39
        $this->nb_count = $nb_count;
40
    }
41
    
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function encryptKey(JWKInterface $key, $cek, array &$header)
46
    {
47
        $this->checkKey($key);
48
        $this->checkHeaderAlgorithm($header);
49
        $wrapper = $this->getWrapper();
50
        $hash_algorithm = $this->getHashAlgorithm();
51
        $key_size = $this->getKeySize();
52
        $salt = openssl_random_pseudo_bytes($this->salt_size / 8);
53
        $password = Base64Url::decode($key->get('k'));
54
55
        // We set headers parameters
56
        $header['p2s'] = Base64Url::encode($salt);
57
        $header['p2c'] = $this->nb_count;
58
59
        $derived_key = hash_pbkdf2($hash_algorithm, $password, $header['alg']."\x00".$salt, $this->nb_count, $key_size, true);
60
61
        return $wrapper->wrap($derived_key, $cek);
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function decryptKey(JWKInterface $key, $encryted_cek, array $header)
68
    {
69
        $this->checkKey($key);
70
        $this->checkHeaderAlgorithm($header);
71
        $this->checkHeaderAdditionalParameters($header);
72
        $wrapper = $this->getWrapper();
73
        $hash_algorithm = $this->getHashAlgorithm();
74
        $key_size = $this->getKeySize();
75
        $salt = $header['alg']."\x00".Base64Url::decode($header['p2s']);
76
        $count = $header['p2c'];
77
        $password = Base64Url::decode($key->get('k'));
78
79
        $derived_key = hash_pbkdf2($hash_algorithm, $password, $salt, $count, $key_size, true);
80
81
        return $wrapper->unwrap($derived_key, $encryted_cek);
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function getKeyManagementMode()
88
    {
89
        return self::MODE_WRAP;
90
    }
91
92
    /**
93
     * @param JWKInterface $key
94
     */
95
    protected function checkKey(JWKInterface $key)
96
    {
97
        if ('oct' !== $key->get('kty') || !$key->has('k')) {
98
            throw new \InvalidArgumentException('The key is not valid');
99
        }
100
    }
101
102
    /**
103
     * @param array $header
104
     */
105
    protected function checkHeaderAlgorithm(array $header)
106
    {
107
        if (!isset($header['alg']) || empty($header['alg'])) {
108
            throw new \InvalidArgumentException("The header parameter 'alg' is missing or invalid.");
109
        }
110
    }
111
112
    /**
113
     * @param array $header
114
     */
115
    protected function checkHeaderAdditionalParameters(array $header)
116
    {
117
        if (!array_key_exists('p2s', $header) || !array_key_exists('p2c', $header) || empty($header['p2s']) || empty($header['p2c'])) {
118
            throw new \InvalidArgumentException("The header is not valid. 'p2s' or 'p2c' parameter is missing or invalid.");
119
        }
120
    }
121
122
    /**
123
     * @return \AESKW\A128KW|\AESKW\A192KW|\AESKW\A256KW
124
     */
125
    abstract protected function getWrapper();
126
127
    /**
128
     * @return string
129
     */
130
    abstract protected function getHashAlgorithm();
131
132
    /**
133
     * @return int
134
     */
135
    abstract protected function getKeySize();
136
}
137