Merge branch '3.0'

This commit is contained in:
terrafrost 2020-09-19 08:55:40 -05:00
commit 92eb7b670f
2 changed files with 70 additions and 1 deletions

View File

@ -61,6 +61,56 @@ abstract class PKCS1 extends Progenitor
{
self::initialize_static_variables();
if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) {
$components = [];
preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches);
$decoded = parent::load($matches[0], $password);
$decoded = ASN1::decodeBER($decoded);
if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER');
}
$ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP);
if (!is_array($ecPrivate)) {
throw new \RuntimeException('Unable to perform ASN1 mapping');
}
if (isset($ecPrivate['parameters'])) {
$components['curve'] = self::loadCurveByParam($ecPrivate['parameters']);
}
preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches);
$decoded = parent::load($matches[0], '');
$decoded = ASN1::decodeBER($decoded);
if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER');
}
$ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP);
if (!is_array($ecParams)) {
throw new \RuntimeException('Unable to perform ASN1 mapping');
}
$ecParams = self::loadCurveByParam($ecParams);
// comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes
// even if the modulo is the same
if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) {
throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY');
}
if (!isset($components['curve'])) {
$components['curve'] = $ecParams;
}
$temp = new BigInteger($ecPrivate['privateKey'], 256);
$components['dA'] = $components['curve']->convertInteger($temp);
$components['QA'] = isset($ecPrivate['publicKey']) ?
self::extractPoint($ecPrivate['publicKey'], $components['curve']) :
$components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']);
return $components;
}
$key = parent::load($key, $password);
$decoded = ASN1::decodeBER($key);
@ -77,12 +127,17 @@ abstract class PKCS1 extends Progenitor
if (!is_array($key)) {
throw new \RuntimeException('Unable to perform ASN1 mapping');
}
if (!isset($key['parameters'])) {
throw new \RuntimeException('Key cannot be loaded without parameters');
}
$components = [];
$components['curve'] = self::loadCurveByParam($key['parameters']);
$temp = new BigInteger($key['privateKey'], 256);
$components['dA'] = $components['curve']->convertInteger($temp);
$components['QA'] = self::extractPoint($key['publicKey'], $components['curve']);
$components['QA'] = isset($ecPrivate['publicKey']) ?
self::extractPoint($ecPrivate['publicKey'], $components['curve']) :
$components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']);
return $components;
}

View File

@ -16,6 +16,20 @@ use phpseclib3\Crypt\EC\PrivateKey;
class Unit_Crypt_EC_LoadKeyTest extends PhpseclibTestCase
{
public function testBinaryPKCS1PrivateParameters()
{
$key = PublicKeyLoader::load('-----BEGIN EC PARAMETERS-----
BgUrgQQAIg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDBPoZHEeuf9UjjhevAbGxWwsmmWw34vkxJwtZ0AknmSUAHo0OAowJSQ
Stf/0U65RhWgBwYFK4EEACKhZANiAASVZJGIs6m/TZhbFoTwBtpvU1JcyixD2YI3
5YnoIx/6Q1oqJg1vrrmUoXaeEpaO6JH8RgItTl9lYMdmOk5309WJka6tI1QAAK3+
Jq9z4moG4whp3JsuiBQG9wnaHVrQPA4=
-----END EC PRIVATE KEY-----');
$this->assertSame('secp384r1', $key->getCurve());
}
// openssl ecparam -name secp256k1 -genkey -noout -out secp256k1.pem
public function testPKCS1PrivateKey()
{