Completed
Push — v2.0.x ( 11273c...f488cd )
by Florent
04:53 queued 01:28
created

AESGCMContentEncryptionTest   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5
Metric Value
wmc 11
lcom 1
cbo 5
dl 0
loc 119
rs 10
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
use Base64Url\Base64Url;
13
use Jose\Algorithm\ContentEncryption\A128GCM;
14
use Jose\Algorithm\ContentEncryption\A192GCM;
15
use Jose\Algorithm\ContentEncryption\A256GCM;
16
17
/**
18
 * Class AESGCMContentEncryptionTest.
19
 */
20
class AESGCMContentEncryptionTest extends \PHPUnit_Framework_TestCase
21
{
22
    /**
23
     *
24
     */
25
    public function testA128GCMEncryptAndDecrypt()
26
    {
27
        if (!$this->isCryptooExtensionInstalled()) {
28
            $this->markTestSkipped('Crypto extension not available');
29
30
            return;
31
        }
32
        $header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A128GCM']));
33
        $tag = null;
34
35
        $algorithm = new A128GCM();
36
37
        $cek = openssl_random_pseudo_bytes(128 / 8);
38
        $iv = openssl_random_pseudo_bytes(96 / 8);
39
        $plaintext = 'Je suis Charlie';
40
41
        $cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
42
43
        $this->assertNotNull($tag);
44
        $this->assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
45
    }
46
47
    /**
48
     *
49
     */
50
    public function testA192GCMEncryptAndDecrypt()
51
    {
52
        if (!$this->isCryptooExtensionInstalled()) {
53
            $this->markTestSkipped('Crypto extension not available');
54
55
            return;
56
        }
57
        $header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A192GCM']));
58
        $tag = null;
59
60
        $algorithm = new A192GCM();
61
62
        $cek = openssl_random_pseudo_bytes(192 / 8);
63
        $iv = openssl_random_pseudo_bytes(96 / 8);
64
        $plaintext = 'Je suis Charlie';
65
66
        $cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
67
68
        $this->assertNotNull($tag);
69
        $this->assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
70
    }
71
72
    /**
73
     *
74
     */
75
    public function testA256GCMEncryptAndDecrypt()
76
    {
77
        if (!$this->isCryptooExtensionInstalled()) {
78
            $this->markTestSkipped('Crypto extension not available');
79
80
            return;
81
        }
82
        $header = Base64Url::encode(json_encode(['alg' => 'ECDH-ES', 'enc' => 'A256GCM']));
83
        $tag = null;
84
85
        $algorithm = new A256GCM();
86
87
        $cek = openssl_random_pseudo_bytes(256 / 8);
88
        $iv = openssl_random_pseudo_bytes(96 / 8);
89
        $plaintext = 'Je suis Charlie';
90
91
        $cyphertext = $algorithm->encryptContent($plaintext, $cek, $iv, null, $header, $tag);
92
93
        $this->assertNotNull($tag);
94
        $this->assertEquals($plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
95
    }
96
97
    /**
98
     * @see https://tools.ietf.org/html/rfc7516#appendix-A.1
99
     */
100
    public function testA256GCMDecryptTestVector()
101
    {
102
        if (!$this->isCryptooExtensionInstalled()) {
103
            $this->markTestSkipped('Crypto extension not available');
104
105
            return;
106
        }
107
        $algorithm = new A256GCM();
108
109
        $header = Base64Url::encode(json_encode(['alg' => 'RSA-OAEP', 'enc' => 'A256GCM']));
110
        $cek = $this->convertArrayToBinString([177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252]);
111
        $iv = $this->convertArrayToBinString([227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219]);
112
        $tag = $this->convertArrayToBinString([92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145]);
113
        $cyphertext = $this->convertArrayToBinString([229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122, 233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111, 104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32, 123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205, 160, 109, 64, 63, 192]);
114
        $expected_plaintext = 'The true sign of intelligence is not knowledge but imagination.';
115
116
        $this->assertEquals('eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ', $header);
117
        $this->assertEquals($expected_plaintext, $algorithm->decryptContent($cyphertext, $cek, $iv, null, $header, $tag));
118
    }
119
120
    /**
121
     * @param array $data
122
     *
123
     * @return string
124
     */
125
    private function convertArrayToBinString(array $data)
126
    {
127
        foreach ($data as $key => $value) {
128
            $data[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);
129
        }
130
131
        return hex2bin(implode('', $data));
132
    }
133
134
    private function isCryptooExtensionInstalled()
135
    {
136
        return class_exists('\Crypto\Cipher');
137
    }
138
}
139