Skip to content

Commit 0ef6de1

Browse files
committed
Fixes OKP keys
1 parent b7ac7af commit 0ef6de1

File tree

4 files changed

+153
-5
lines changed

4 files changed

+153
-5
lines changed

src/Component/KeyManagement/JWKFactory.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,23 @@ public static function createOKPKey(string $curve, array $values = []): JWK
106106
switch ($curve) {
107107
case 'X25519':
108108
$keyPair = sodium_crypto_box_keypair();
109-
$secret = $keyPair;
109+
$d = sodium_crypto_box_secretkey($keyPair);
110110
$x = sodium_crypto_box_publickey($keyPair);
111111

112112
break;
113113

114114
case 'Ed25519':
115115
$keyPair = sodium_crypto_sign_keypair();
116116
$secret = sodium_crypto_sign_secretkey($keyPair);
117+
$secretLength = mb_strlen($secret, '8bit');
118+
$d = mb_substr($secret, 0, -$secretLength / 2, '8bit');
117119
$x = sodium_crypto_sign_publickey($keyPair);
118120

119121
break;
120122

121123
default:
122124
throw new InvalidArgumentException(sprintf('Unsupported "%s" curve', $curve));
123125
}
124-
$secretLength = mb_strlen($secret, '8bit');
125-
$d = mb_substr($secret, 0, -$secretLength / 2, '8bit');
126126

127127
$values = array_merge(
128128
$values,

src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@ private function createOKPKey(string $curve): JWK
293293

294294
case 'Ed25519':
295295
$keyPair = sodium_crypto_sign_keypair();
296-
$d = sodium_crypto_sign_secretkey($keyPair);
296+
$secret = sodium_crypto_sign_secretkey($keyPair);
297+
$secretLength = mb_strlen($secret, '8bit');
298+
$d = mb_substr($secret, 0, -$secretLength / 2, '8bit');
297299
$x = sodium_crypto_sign_publickey($keyPair);
298300

299301
break;

tests/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHESKeyAgreementTest.php

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class ECDHESKeyAgreementTest extends TestCase
2626
*
2727
* @test
2828
*/
29-
public function getAgreementKey(): void
29+
public function getAgreementKeyWithEllipticCurveKey(): void
3030
{
3131
$receiver = new JWK([
3232
'kty' => 'EC',
@@ -51,6 +51,76 @@ public function getAgreementKey(): void
5151
static::assertArrayHasKey('y', $additional_header_values['epk']);
5252
}
5353

54+
/**
55+
* @see https://tools.ietf.org/html/rfc7518#appendix-C
56+
*
57+
* @test
58+
*/
59+
public function getAgreementKeyWithA128KeyWrapAndWithOctetKeyPairKey(): void
60+
{
61+
$header = [
62+
'enc' => 'A128GCM',
63+
];
64+
65+
$private = new JWK([
66+
'kty' => 'OKP',
67+
'crv' => 'X25519',
68+
'd' => 'uns2Byv3po_cjjG8XRCtU-lEOrOgLbsDr5cXHmgjVvA',
69+
'x' => 'k8IkMMO9I0foCYqEcbfM49DjEoWpHdho_GKNMXk1rFw',
70+
]);
71+
$public = $private->toPublic();
72+
73+
$cek = [
74+
4,
75+
211,
76+
31,
77+
197,
78+
84,
79+
157,
80+
252,
81+
254,
82+
11,
83+
100,
84+
157,
85+
250,
86+
63,
87+
170,
88+
106,
89+
206,
90+
107,
91+
124,
92+
212,
93+
45,
94+
111,
95+
107,
96+
9,
97+
219,
98+
200,
99+
177,
100+
0,
101+
240,
102+
143,
103+
156,
104+
44,
105+
207,
106+
];
107+
foreach ($cek as $key => $value) {
108+
$cek[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);
109+
}
110+
$cek = hex2bin(implode('', $cek));
111+
112+
$ecdh_es = new ECDHESA128KW();
113+
$encrypted_cek = $ecdh_es->wrapAgreementKey($public, null, $cek, 128, $header, $header);
114+
static::assertArrayHasKey('epk', $header);
115+
static::assertArrayHasKey('crv', $header['epk']);
116+
static::assertArrayHasKey('kty', $header['epk']);
117+
static::assertArrayHasKey('x', $header['epk']);
118+
static::assertArrayNotHasKey('y', $header['epk']);
119+
static::assertSame('X25519', $header['epk']['crv']);
120+
static::assertSame('OKP', $header['epk']['kty']);
121+
static::assertSame($cek, $ecdh_es->unwrapAgreementKey($private, null, $encrypted_cek, 128, $header));
122+
}
123+
54124
/**
55125
* @test
56126
*/

tests/EncryptionAlgorithm/KeyEncryption/ECDHSS/ECDHSSKeyAgreementTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,82 @@ public function getAgreementKey(): void
5252
static::assertArrayNotHasKey('epk', $additional_header_values);
5353
}
5454

55+
/**
56+
* @test
57+
*/
58+
public function getAgreementKeyWithA128KeyWrapAndOctetKeyPairKey(): void
59+
{
60+
$additional_header_values = [
61+
'enc' => 'A128GCM',
62+
];
63+
$sender = new JWK([
64+
'kty' => 'OKP',
65+
'crv' => 'X25519',
66+
'd' => 'uns2Byv3po_cjjG8XRCtU-lEOrOgLbsDr5cXHmgjVvA',
67+
'x' => 'k8IkMMO9I0foCYqEcbfM49DjEoWpHdho_GKNMXk1rFw',
68+
]);
69+
$receiver = new JWK([
70+
'kty' => 'EC',
71+
'crv' => 'X25519',
72+
'd' => 'tzF6dJQtUYj2G60lzzw70A8BGeE_KDDofUdwwm9qIEU',
73+
'x' => 'q9mRLLKfK-_SosZoBFs5LaDxSB9KaqbRaenvzy1_lAA',
74+
]);
75+
76+
$cek = [
77+
4,
78+
211,
79+
31,
80+
197,
81+
84,
82+
157,
83+
252,
84+
254,
85+
11,
86+
100,
87+
157,
88+
250,
89+
63,
90+
170,
91+
106,
92+
206,
93+
107,
94+
124,
95+
212,
96+
45,
97+
111,
98+
107,
99+
9,
100+
219,
101+
200,
102+
177,
103+
0,
104+
240,
105+
143,
106+
156,
107+
44,
108+
207,
109+
];
110+
foreach ($cek as $key => $value) {
111+
$cek[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);
112+
}
113+
$cek = hex2bin(implode('', $cek));
114+
115+
$ecdh_ss = new ECDHSSA128KW();
116+
$encrypted_cek = $ecdh_ss->wrapAgreementKey(
117+
$receiver->toPublic(),
118+
$sender,
119+
$cek,
120+
128,
121+
$additional_header_values,
122+
$additional_header_values
123+
);
124+
static::assertArrayNotHasKey('epk', $additional_header_values);
125+
static::assertSame(
126+
$cek,
127+
$ecdh_ss->unwrapAgreementKey($sender->toPublic(), $receiver, $encrypted_cek, 128, $additional_header_values)
128+
);
129+
}
130+
55131
/**
56132
* @test
57133
*/

0 commit comments

Comments
 (0)