Failed Conditions
Push — v7 ( 838dcb )
by Florent
04:30
created

AESGCMKW::getMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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 Assert\Assertion;
15
use Base64Url\Base64Url;
16
use Jose\Object\JWKInterface;
17
18
/**
19
 * Class AESGCMKW.
20
 */
21
abstract class AESGCMKW implements KeyWrappingInterface
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    public function wrapKey(JWKInterface $key, string $cek, array $complete_headers, array &$additional_headers): string
27
    {
28
        $this->checkKey($key);
29
        $kek = Base64Url::decode($key->get('k'));
30
        $iv = random_bytes(96 / 8);
31
        $additional_headers['iv'] = Base64Url::encode($iv);
32
33
        $mode = $this->getMode($kek);
34
        $tag = null;
35
        $tag_length = 128;
36
        $encrypted_cek = openssl_encrypt($cek, $mode, $kek, OPENSSL_RAW_DATA, $iv, $tag, null, $tag_length / 8);
37
        Assertion::true(false !== $encrypted_cek, 'Unable to encrypt the data.');
38
39
        $additional_headers['tag'] = Base64Url::encode($tag);
40
41
        return $encrypted_cek;
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function unwrapKey(JWKInterface $key, string $encrypted_cek, array $header): string
48
    {
49
        $this->checkKey($key);
50
        $this->checkAdditionalParameters($header);
51
52
        $kek = Base64Url::decode($key->get('k'));
53
        $tag = Base64Url::decode($header['tag']);
54
        $iv = Base64Url::decode($header['iv']);
55
        $mode = $this->getMode($kek);
56
57
        return openssl_decrypt($encrypted_cek, $mode, $kek, OPENSSL_RAW_DATA, $iv, $tag, null);
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getKeyManagementMode(): string
64
    {
65
        return self::MODE_WRAP;
66
    }
67
68
    /**
69
     * @param JWKInterface $key
70
     */
71
    protected function checkKey(JWKInterface $key)
72
    {
73
        Assertion::eq($key->get('kty'), 'oct', 'Wrong key type.');
74
        Assertion::true($key->has('k'), 'The key parameter "k" is missing.');
75
    }
76
77
    /**
78
     * @param array $header
79
     */
80
    protected function checkAdditionalParameters(array $header)
81
    {
82
        Assertion::keyExists($header, 'iv', 'Parameter "iv" is missing.');
83
        Assertion::keyExists($header, 'tag', 'Parameter "tag" is missing.');
84
    }
85
86
    /**
87
     * @return int
88
     */
89
    abstract protected function getKeySize(): int;
90
91
    /**
92
     * @param string $kek
93
     *
94
     * @return string
95
     */
96
    private function getMode(string $kek): string
97
    {
98
        $key_length = mb_strlen($kek, '8bit') * 8;
99
100
        return 'aes-'.($key_length).'-gcm';
101
    }
102
}
103