Skip to content

Commit 839a44b

Browse files
author
Greg Bowler
committed
Implement decryption of response cipher
1 parent 3a7e555 commit 839a44b

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

src/Token.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Token {
88
const ENCRYPTION_METHOD = "aes128";
99

1010
private string $key;
11-
private string $secretIv;
11+
private InitVector $secretIv;
1212
private InitVector $iv;
1313

1414
public function __construct(
@@ -21,6 +21,10 @@ public function __construct(
2121
$this->iv = $iv ?? new InitVector();
2222
}
2323

24+
public function getIv():InitVector {
25+
return $this->iv;
26+
}
27+
2428
// The request cipher is sent to the remote provider in the querystring. It
2529
// consists of the secret IV, encrypted with the client key. The remote provider
2630
// will decrypt the secret and use it as the key when encrypting the response
@@ -45,7 +49,10 @@ public function decryptResponseCipher(string $cipher):UserData {
4549
$decrypted = openssl_decrypt(
4650
base64_decode($cipher),
4751
self::ENCRYPTION_METHOD,
48-
$this->secretIv->getBytes(),
52+
implode("|", [
53+
$this->key,
54+
$this->secretIv->getBytes(),
55+
]),
4956
0,
5057
$this->iv->getBytes()
5158
);
@@ -68,8 +75,4 @@ public function decryptResponseCipher(string $cipher):UserData {
6875

6976
return new UserData($obj->uuid, $obj->email);
7077
}
71-
72-
public function getIv():InitVector {
73-
return $this->iv;
74-
}
7578
}

test/phpunit/TokenTest.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
namespace Authwave\Test;
33

44
use Authwave\InitVector;
5+
use Authwave\InvalidUserDataSerializationException;
6+
use Authwave\ResponseCipherDecryptionException;
57
use Authwave\Token;
8+
use Authwave\UserData;
69
use PHPUnit\Framework\TestCase;
710

811
class TokenTest extends TestCase {
@@ -32,4 +35,65 @@ public function testGetIv() {
3235
$sut = new Token("", null, $iv);
3336
self::assertSame($iv, $sut->getIv());
3437
}
38+
39+
public function testDecryptResponseCipherInvalid() {
40+
$cipher = "0123456789abcdef";
41+
$sut = new Token("test-key");
42+
self::expectException(ResponseCipherDecryptionException::class);
43+
$sut->decryptResponseCipher($cipher);
44+
}
45+
46+
public function testDecryptResponseCipherBadJson() {
47+
$key = uniqid("test-key-");
48+
$secretIv = self::createMock(InitVector::class);
49+
$secretIv->method("getBytes")
50+
->willReturn(str_repeat("0", 16));
51+
$iv = self::createMock(InitVector::class);
52+
$iv->method("getBytes")
53+
->willReturn(str_repeat("f", 16));
54+
$cipher = openssl_encrypt(
55+
"{badly-formed: json]",
56+
Token::ENCRYPTION_METHOD,
57+
implode("|", [$key, $secretIv->getBytes()]),
58+
0,
59+
$iv->getBytes()
60+
);
61+
$cipher = base64_encode($cipher);
62+
$sut = new Token($key, $secretIv, $iv);
63+
self::expectException(InvalidUserDataSerializationException::class);
64+
$sut->decryptResponseCipher($cipher);
65+
}
66+
67+
public function testDecryptResponseCipher() {
68+
$key = uniqid("test-key-");
69+
$secretIv = self::createMock(InitVector::class);
70+
$secretIv->method("getBytes")
71+
->willReturn(str_repeat("0", 16));
72+
$iv = self::createMock(InitVector::class);
73+
$iv->method("getBytes")
74+
->willReturn(str_repeat("f", 16));
75+
76+
$uuid = "aabb-ccdd-eeff";
77+
$email = "user@example.com";
78+
$json = <<<JSON
79+
{
80+
"uuid": "$uuid",
81+
"email": "$email"
82+
}
83+
JSON;
84+
85+
$cipher = openssl_encrypt(
86+
$json,
87+
Token::ENCRYPTION_METHOD,
88+
implode("|", [$key, $secretIv->getBytes()]),
89+
0,
90+
$iv->getBytes()
91+
);
92+
$cipher = base64_encode($cipher);
93+
$sut = new Token($key, $secretIv, $iv);
94+
$userData = $sut->decryptResponseCipher($cipher);
95+
self::assertInstanceOf(UserData::class, $userData);
96+
self::assertEquals($uuid, $userData->getUuid());
97+
self::assertEquals($email, $userData->getEmail());
98+
}
3599
}

0 commit comments

Comments
 (0)