Skip to content

Commit

Permalink
Switch to remotePublicKey instead of remoteCertificatePath
Browse files Browse the repository at this point in the history
* For remote verification we dont' need ESIA's cert, but only it's public key.
But for our signature we need our cert.
* Backward compatible rename param to `remotePublicKey`
* Auto-generate public keys from certs.
  • Loading branch information
garex committed Sep 29, 2020
1 parent 2223337 commit 80a25ee
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -37,7 +37,7 @@ $provider = new EsiaProvider([
'defaultScopes' => ['openid', 'fullname', '...'],
// For work with test portal version
// 'remoteUrl' => 'https://esia-portal1.test.gosuslugi.ru',
// 'remoteCertificatePath' => EsiaProvider::RESOURCES.'esia.test.cer',
// 'remotePublicKey' => EsiaProvider::RESOURCES.'esia.test.public.key',
], [
'signer' => new OpensslPkcs7('/path/to/public/certificate.cer', '/path/to/private.key')
]);
Expand Down
6 changes: 6 additions & 0 deletions resources/README.md
Expand Up @@ -16,3 +16,9 @@ View

openssl asn1parse -i -in ekapusta.gost.test.cer
openssl asn1parse -i -in ekapusta.rsa.test.cer


Extract public keys from certs
------------------------------

for CERT in *.cer; do openssl x509 -engine gost -noout -pubkey -in $CERT -out ${CERT%.*}.public.key; done
6 changes: 6 additions & 0 deletions resources/another.gost.test.public.key
@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGqMCEGCCqFAwcBAQECMBUGCSqFAwcBAgECAQYIKoUDBwEBAgMDgYQABIGAAIk7
L7Nqb+U87NuCbLvc/GeuoyMEKkE82V2tCxGqFeJDtBKLFo7Qejnm6m9SSbVrZznD
3lPKWY8TBInwxUryn93r5PuhWU8r/Fiea2/hBi37N0pRA7vSB5O6jQW+0HXwOBLR
rwABtaZmSNkBaQXTwuL8eixeNYKqINMfzszLcRc=
-----END PUBLIC KEY-----
9 changes: 9 additions & 0 deletions resources/another.rsa.test.public.key
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs83shRDyThuqNdqc1bu5
Xt4CSv4xVZ2+pK32Pd/ZcQDqSSIDvHOUWRNjHTBtdlUitTi4mhXF2o8st7eQvITe
LtieUcnnPGSaWACO3fIru9QtSe7iNEYSBFBKVjEEopsBI0cIOwftTrgCfqEc02+N
/JQGs9FLG4DRmKnDNi2dMpdjGx9wyE4RIRv43WUEmCSSgIgDsBCWZLl0n8c+OXn3
cSlYA+LKE/JHIsI/3d2qA65NJvLnIDpz2Z0wvQ9CWOFP3wKeWS14I7EUws5sr1SD
h9G1me4lSNEuTB6/R3xKRqOiM/Lf+DimAGXtfmmmM/wTbIUEOSJ1xD7AV21a4a/n
5wIDAQAB
-----END PUBLIC KEY-----
5 changes: 5 additions & 0 deletions resources/ekapusta.gost.test.public.key
@@ -0,0 +1,5 @@
-----BEGIN PUBLIC KEY-----
MGMwHAYGKoUDAgITMBIGByqFAwICIwEGByqFAwICHgEDQwAEQMsUVDhzO/dY5+bf
7qbzh6l6ExJwH/q8m2suCh2ul0HK+2TcsnIWi6MoU1qZCXN4kzLU9+v/raX7wEBH
jHS4wUg=
-----END PUBLIC KEY-----
9 changes: 9 additions & 0 deletions resources/ekapusta.rsa.test.public.key
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3QT1Wsa9f/lczm3KJF6g
tMz0YE/fi/NNYFLA/2rJL5+rtYGLgtUaxyC+GGBBq7DRXiVDwlWnsixEmrmkaWqK
uXH0i09a1v8tjuyFGK9RiplFCZOJstQ7V5gUi6Sr1/kfCcHnGtWioeYTdzwwe+Eo
NCdnjE67X7kk/QSS890PNO8Qwy4nrNgZZ2VUYUGRu2pR490p5DDbSUJDf0xqTOno
jDkdJcWTxqOAeasYwZ4gKPBqsROjHHrbMoQrBlCTRC7n76QI+Lvh9sjTOE3q4O13
urGTYczr1ezfcHKDAqgCNjGYUOadP/luMJ9AiQZvGIvq6/orMHZ1pZ5LDo42Z9US
ewIDAQAB
-----END PUBLIC KEY-----
9 changes: 9 additions & 0 deletions resources/esia.prod.public.key
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg4/V4iNjYrC4gBSM7OlD
bYHNqpyfUYkoRoZ+GGcTU/Vd47srTLlhFADtTcC4GangTY9p1zpm1DGO7nhVRb6I
UKWt49jwRApvH2k/vo4Nlou6bwqZeeg1BVJZRGBH5UtnZ5k5gR3qKyntb+RpG3sA
WfZQicH6yfoWbBS6ypfJ0EJ7GNxaeAn5akjSYMwFx4mRVG2pYo+Ly2jjd5XlbWhq
nMle6sROvR4y7SaudqW2Bg7sE/8ZrYGJRBdgMn5d83M6uxOEhp4yp8TP3+NnXAxI
keK4IMaBMwzfw/OGjbS8a/UMnN1EMT4bkXbk0z/Y/5guI2H1MrrgsIQs6VQorf9J
zwIDAQAB
-----END PUBLIC KEY-----
9 changes: 9 additions & 0 deletions resources/esia.test.public.key
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Rw9xG1g+QQ0QgB8bwSq
xJxOU84tjHI7uhvwCnyJQAb9SNLRkeraBjmhA29oCAn9uv56kaYe9YNhqijRsNVG
yIAAZTB0EHv99xqIqdoOtv4io2o7JbxNomun7ENrOF2ZQT7Ukqr4b748FvKSGoX0
OVcB7Sru6HU7NAH1oNJ4bbNr8SeHcP4CGZsF20y/L0OjT+TENFQD9eNpOIuyWPL5
2F1apKIf5si4yTBxg9QZlBzrwuBGRW1ah2slBjJ95Fu7Q82uM5Zc7oqwFsYhni3v
HXxi1rX2HCtgAKeBb0QJ5z1KwNGovPhBNtmRPW0JTFeX0CgvHNRUsPgki566cVLb
AQIDAQAB
-----END PUBLIC KEY-----
13 changes: 9 additions & 4 deletions src/Provider/EsiaProvider.php
Expand Up @@ -27,7 +27,7 @@ class EsiaProvider extends AbstractProvider implements ProviderInterface

protected $remoteUrl = 'https://esia.gosuslugi.ru';

protected $remoteCertificatePath = self::RESOURCES.'esia.prod.cer';
protected $remotePublicKey = self::RESOURCES.'esia.prod.public.key';

/**
* @var SignerInterface
Expand All @@ -41,12 +41,17 @@ class EsiaProvider extends AbstractProvider implements ProviderInterface

public function __construct(array $options = [], array $collaborators = [])
{
// Backward compatibility as of rename remoteCertificatePath -> remotePublicKey
if (isset($options['remoteCertificatePath'])) {
$options['remotePublicKey'] = $options['remoteCertificatePath'];
}

parent::__construct($options, $collaborators);
if (!filter_var($this->remoteUrl, FILTER_VALIDATE_URL)) {
throw new InvalidArgumentException('Remote URL is not provided!');
}
if (!file_exists($this->remoteCertificatePath)) {
throw new InvalidArgumentException('Remote certificate is not provided!');
if (!file_exists($this->remotePublicKey)) {
throw new InvalidArgumentException('Remote public key is not provided!');
}

if (isset($collaborators['signer']) && $collaborators['signer'] instanceof SignerInterface) {
Expand Down Expand Up @@ -189,7 +194,7 @@ protected function checkResponse(ResponseInterface $response, $data)

protected function createAccessToken(array $response, AbstractGrant $grant)
{
return new EsiaAccessToken($response, $this->remoteCertificatePath);
return new EsiaAccessToken($response, $this->remotePublicKey);
}

protected function createResourceOwner(array $response, AccessToken $token)
Expand Down
18 changes: 14 additions & 4 deletions tests/Provider/EsiaProviderTest.php
Expand Up @@ -48,7 +48,7 @@ protected function setUp()
'clientId' => 'EKAP01',
'redirectUri' => $this->redirectUri,
'remoteUrl' => 'https://esia-portal1.test.gosuslugi.ru',
'remoteCertificatePath' => EsiaProvider::RESOURCES.'esia.test.cer',
'remotePublicKey' => EsiaProvider::RESOURCES.'esia.test.public.key',
'defaultScopes' => [
// needed for authenticating
'openid',
Expand Down Expand Up @@ -164,11 +164,21 @@ public function testRemoteUrlIsRequired()

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Remote certificate is not provided!
* @expectedExceptionMessage Remote public key is not provided!
*/
public function testRemoteCertificateIsRequired()
public function testRemotePublicKeyIsRequired()
{
new EsiaProvider(['remoteCertificatePath' => ''], ['signer' => $this->signer]);
new EsiaProvider(['remotePublicKey' => ''], ['signer' => $this->signer]);
}

/**
* Provider uses remoteCertificate as alias of remotePublicKey.
*/
public function testRemoteCertificateIsRenamedToPublicKey()
{
new EsiaProvider(['remoteCertificatePath' => '/dev/null', 'remotePublicKey' => ''], ['signer' => $this->signer]);

$this->assertTrue(true);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions tests/Token/EsiaAccessTokenTest.php
Expand Up @@ -27,15 +27,15 @@ public function testInvalidAsBadSignature()
{
Factory::createAccessToken(
Factory::KEYS.'ekapusta.rsa.test.key',
Factory::KEYS.'another.rsa.test.cer'
Factory::KEYS.'another.rsa.test.public.key'
);
}

public function testFullyValid()
{
$esiaToken = Factory::createAccessToken(
Factory::KEYS.'ekapusta.rsa.test.key',
Factory::KEYS.'ekapusta.rsa.test.cer'
Factory::KEYS.'ekapusta.rsa.test.public.key'
);

$this->assertInstanceOf(EsiaAccessToken::class, $esiaToken);
Expand Down

0 comments on commit 80a25ee

Please sign in to comment.