Skip to content

Commit

Permalink
Ensure Public Key derivation is consistent
Browse files Browse the repository at this point in the history
  • Loading branch information
paragonie-security committed Aug 3, 2021
1 parent 5743bb4 commit f18c4bd
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/Keys/AsymmetricPublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public static function v4(string $keyMaterial): self
public function encode(): string
{
if (hash_equals($this->protocol::header(), Version3::HEADER)) {
if (Binary::safeStrlen($this->key) === 49) {
Base64UrlSafe::encodeUnpadded($this->key);
} elseif (Binary::safeStrlen($this->key) === 98) {
Base64UrlSafe::encodeUnpadded(Hex::decode($this->key));
}
return Base64UrlSafe::encodeUnpadded(
Hex::decode(
Version3::getPublicKeyCompressed($this->key)
Expand All @@ -171,11 +176,15 @@ public function encode(): string
public static function fromEncodedString(string $encoded, ProtocolInterface $version = null): self
{
if (hash_equals($version::header(), Version3::HEADER)) {
$decoded = Version3::getPublicKeyPem(
Hex::encode(
Base64UrlSafe::decode($encoded)
)
);
$decodeString = Base64UrlSafe::decode($encoded);
$length = Binary::safeStrlen($encoded);
if ($length === 98) {
$decoded = Version3::getPublicKeyPem($decodeString);
} elseif ($length === 49) {
$decoded = Version3::getPublicKeyPem(Hex::encode($decodeString));
} else {
$decoded = $decodeString;
}
} else {
$decoded = Base64UrlSafe::decode($encoded);
}
Expand All @@ -184,6 +193,7 @@ public static function fromEncodedString(string $encoded, ProtocolInterface $ver

/**
* @return string
* @throws ParserException
*/
public function toHexString(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Keys/AsymmetricSecretKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public function getPublicKey(): AsymmetricPublicKey
/** @var PublicKey $pk */
$pk = SecretKey::importPem($this->key)->getPublicKey();
return new AsymmetricPublicKey(
$pk->toString(), // Compressed point
PublicKey::importPem($pk->exportPem())->toString(), // Compressed point
$this->protocol
);
default:
Expand Down
48 changes: 48 additions & 0 deletions tests/KeyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace ParagonIE\Paseto\Tests;

use ParagonIE\Paseto\Keys\AsymmetricPublicKey;
use ParagonIE\Paseto\Keys\AsymmetricSecretKey;
use ParagonIE\Paseto\Protocol\Version3;
use PHPUnit\Framework\TestCase;

class KeyTest extends TestCase
{
public function testV3SampleKeys()
{
$parameters = [
[
"-----BEGIN EC PRIVATE KEY-----\n" .
"MIGkAgEBBDAnSUGZvzGcMqhaW2kAaY0uvxVvLbAeJWeD+eaCYNzJiEoPr1eKuvBb\n" .
"hFvi/Ft/41qgBwYFK4EEACKhZANiAARpPMZ8TLmF1d4ZlZR6hUJsWxze4M8TN9iS\n" .
"waAjnoeGiIBT9fmpllDA8TR5lYvfS5zcN5ZcLtFHm4akAuen2cWEWtUYfxMfiGYx\n" .
"jIXJ55iqSEuhXlvJ+NNMzBTjPvk/moc=\n" .
"-----END EC PRIVATE KEY-----",
'03693cc67c4cb985d5de1995947a85426c5b1cdee0cf1337d892c1a0239e8786888053f5f9a99650c0f13479958bdf4b9c'
],

[
"-----BEGIN EC PRIVATE KEY-----\n" .
"MIGkAgEBBDDtEwLf2DPbrLWLYq42hdr15W6+xwgR8X1c9mXMe0728YGfVF2oQ4We\n" .
"1q9/i6m3sLagBwYFK4EEACKhZANiAATuATlkGO95N59tpwl2a9zUiGqLDq5k+ARa\n" .
"DGbupLQde6cyKzHcPj8remWkjkFNiZB+vctHKtn55KeY4D8PViv2l6TVBorzdYjR\n" .
"Z7OdnDOTd5S/q4psBWPW5kRZFrX1tOI=\n" .
"-----END EC PRIVATE KEY-----",
'02ee01396418ef79379f6da709766bdcd4886a8b0eae64f8045a0c66eea4b41d7ba7322b31dc3e3f2b7a65a48e414d8990'
]
];
foreach ($parameters as $params) {
$this->sampleKeyTrail(...$params);
}
}

public function sampleKeyTrail(string $secret, string $public)
{
$sk = AsymmetricSecretKey::v3($secret);
$pk = $sk->getPublicKey();
$this->assertSame($public, $pk->toHexString());
$pk2 = AsymmetricPublicKey::fromEncodedString($pk->encode(), new Version3);
$this->assertSame($public, $pk2->toHexString());
}
}

0 comments on commit f18c4bd

Please sign in to comment.