mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-12-27 11:52:48 +00:00
ECDSA: make it so toString() can setspecified / named curve use
This commit is contained in:
parent
557676edd9
commit
a431a1959a
@ -261,20 +261,12 @@ abstract class ECDSA extends AsymmetricKey
|
||||
return $this->curveName;
|
||||
}
|
||||
|
||||
$namedCurves = PKCS1::isUsingNamedCurves();
|
||||
PKCS1::useNamedCurve();
|
||||
|
||||
$params = $this->getParameters();
|
||||
$params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]);
|
||||
$decoded = ASN1::extractBER($params);
|
||||
$decoded = ASN1::decodeBER($decoded);
|
||||
$decoded = ASN1::asn1map($decoded[0], ECParameters::MAP);
|
||||
if (isset($decoded['namedCurve'])) {
|
||||
$this->curveName = $decoded['namedCurve'];
|
||||
|
||||
if (!$namedCurves) {
|
||||
PKCS1::useSpecifiedCurve();
|
||||
}
|
||||
|
||||
return $decoded['namedCurve'];
|
||||
}
|
||||
|
||||
|
@ -342,23 +342,26 @@ trait Common
|
||||
*
|
||||
* @todo Maybe at some point this could be moved to __toString() for each of the curves?
|
||||
* @param \phpseclib\Crypt\ECDSA\BaseCurves\Base $curve
|
||||
* @param bool $returnArray
|
||||
* @param bool $returnArray optional
|
||||
* @param array $options optional
|
||||
* @return string|false
|
||||
*/
|
||||
private static function encodeParameters(BaseCurve $curve, $returnArray = false)
|
||||
private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = [])
|
||||
{
|
||||
$useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves;
|
||||
|
||||
$reflect = new \ReflectionClass($curve);
|
||||
$name = $reflect->getShortName();
|
||||
if (isset(self::$curveOIDs[$name]) && self::$useNamedCurves) {
|
||||
if ($reflect->isFinal()) {
|
||||
$reflect = $reflect->getParentClass();
|
||||
$name = $reflect->getShortName();
|
||||
if ($useNamedCurves) {
|
||||
if (isset(self::$curveOIDs[$name])) {
|
||||
if ($reflect->isFinal()) {
|
||||
$reflect = $reflect->getParentClass();
|
||||
$name = $reflect->getShortName();
|
||||
}
|
||||
return $returnArray ?
|
||||
['namedCurve' => $name] :
|
||||
ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP);
|
||||
}
|
||||
return $returnArray ?
|
||||
['namedCurve' => $name] :
|
||||
ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP);
|
||||
}
|
||||
if (self::$useNamedCurves) {
|
||||
foreach (new \DirectoryIterator(__DIR__ . '/../Curves/') as $file) {
|
||||
if ($file->getExtension() != 'php') {
|
||||
continue;
|
||||
@ -549,14 +552,4 @@ trait Common
|
||||
{
|
||||
self::$useNamedCurves = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if named curves are being used by default
|
||||
*
|
||||
* If a named curve is not being used by default than specified curves are being utilized
|
||||
*/
|
||||
public static function isUsingNamedCurves()
|
||||
{
|
||||
return self::$useNamedCurves;
|
||||
}
|
||||
}
|
@ -92,7 +92,7 @@ abstract class PKCS1 extends Progenitor
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public static function saveParameters(BaseCurve $curve)
|
||||
public static function saveParameters(BaseCurve $curve, array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
@ -100,7 +100,7 @@ abstract class PKCS1 extends Progenitor
|
||||
throw new UnsupportedCurveException('TwistedEdwards Curves are not supported');
|
||||
}
|
||||
|
||||
$key = self::encodeParameters($curve);
|
||||
$key = self::encodeParameters($curve, false, $options);
|
||||
|
||||
return "-----BEGIN EC PARAMETERS-----\r\n" .
|
||||
chunk_split(Base64::encode($key), 64) .
|
||||
|
@ -169,9 +169,10 @@ abstract class PKCS8 extends Progenitor
|
||||
* @access public
|
||||
* @param \phpseclib\Crypt\ECDSA\BaseCurves\Base $curve
|
||||
* @param \phpseclib\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param array $optiona optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePublicKey(BaseCurve $curve, array $publicKey)
|
||||
public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
@ -183,7 +184,7 @@ abstract class PKCS8 extends Progenitor
|
||||
);
|
||||
}
|
||||
|
||||
$params = new ASN1\Element(self::encodeParameters($curve));
|
||||
$params = new ASN1\Element(self::encodeParameters($curve, false, $options));
|
||||
|
||||
$key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes();
|
||||
|
||||
@ -218,7 +219,7 @@ abstract class PKCS8 extends Progenitor
|
||||
|
||||
$publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes();
|
||||
|
||||
$params = new ASN1\Element(self::encodeParameters($curve));
|
||||
$params = new ASN1\Element(self::encodeParameters($curve, false, $options));
|
||||
|
||||
$key = [
|
||||
'version' => 'ecPrivkeyVer1',
|
||||
@ -229,6 +230,6 @@ abstract class PKCS8 extends Progenitor
|
||||
|
||||
$key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP);
|
||||
|
||||
return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', $options);
|
||||
return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options);
|
||||
}
|
||||
}
|
||||
|
@ -365,9 +365,10 @@ abstract class XML
|
||||
*
|
||||
* @param \phpseclib\Crypt\ECDSA\BaseCurves\Base $curve
|
||||
* @param \phpseclib\Math\Common\FiniteField\Integer[] $publicKey
|
||||
* @param array $options optional
|
||||
* @return string
|
||||
*/
|
||||
public static function savePublicKey(BaseCurve $curve, array $publicKey)
|
||||
public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = [])
|
||||
{
|
||||
self::initialize_static_variables();
|
||||
|
||||
@ -384,7 +385,7 @@ abstract class XML
|
||||
|
||||
if (self::$rfc4050) {
|
||||
return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" .
|
||||
self::encodeXMLParameters($curve, $pre) . "\r\n" .
|
||||
self::encodeXMLParameters($curve, $pre, $options) . "\r\n" .
|
||||
'<' . $pre . 'PublicKey>' . "\r\n" .
|
||||
'<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" .
|
||||
'<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" .
|
||||
@ -395,7 +396,7 @@ abstract class XML
|
||||
$publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes();
|
||||
|
||||
return '<' . $pre . 'ECKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" .
|
||||
self::encodeXMLParameters($curve, $pre) . "\r\n" .
|
||||
self::encodeXMLParameters($curve, $pre, $options) . "\r\n" .
|
||||
'<' . $pre . 'PublicKey>' . Base64::encode($publicKey) . '</' . $pre . 'PublicKey>' . "\r\n" .
|
||||
'</' . $pre . 'ECKeyValue>';
|
||||
}
|
||||
@ -405,11 +406,12 @@ abstract class XML
|
||||
*
|
||||
* @param \phpseclib\Crypt\ECDSA\BaseCurves\Base $curve
|
||||
* @param string $pre
|
||||
* @param array $options optional
|
||||
* @return string|false
|
||||
*/
|
||||
private static function encodeXMLParameters(BaseCurve $curve, $pre)
|
||||
private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = [])
|
||||
{
|
||||
$result = self::encodeParameters($curve, true);
|
||||
$result = self::encodeParameters($curve, true, $options);
|
||||
|
||||
if (isset($result['namedCurve'])) {
|
||||
$namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />';
|
||||
|
@ -103,21 +103,13 @@ class PrivateKey extends ECDSA implements Common\PrivateKey
|
||||
}
|
||||
|
||||
if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
|
||||
$namedCurves = PKCS8::isUsingNamedCurves();
|
||||
|
||||
// use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve;
|
||||
// doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even
|
||||
// has curve-specific optimizations
|
||||
PKCS8::useSpecifiedCurve();
|
||||
|
||||
$signature = '';
|
||||
// altho PHP's OpenSSL bindings only supported ECDSA key creation in PHP 7.1 they've long
|
||||
// supported signing / verification
|
||||
$result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash());
|
||||
|
||||
if ($namedCurves) {
|
||||
PKCS8::useNamedCurve();
|
||||
}
|
||||
// we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve;
|
||||
// doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even
|
||||
// has curve-specific optimizations
|
||||
$result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
|
||||
|
||||
if ($result) {
|
||||
if ($shortFormat == 'ASN1') {
|
||||
|
@ -109,17 +109,9 @@ class PublicKey extends ECDSA implements Common\PublicKey
|
||||
extract($params);
|
||||
|
||||
if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
|
||||
$namedCurves = PKCS8::isUsingNamedCurves();
|
||||
|
||||
PKCS8::useSpecifiedCurve();
|
||||
|
||||
$sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature;
|
||||
|
||||
$result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash());
|
||||
|
||||
if ($namedCurves) {
|
||||
PKCS8::useNamedCurve();
|
||||
}
|
||||
$result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash());
|
||||
|
||||
if ($result != -1) {
|
||||
return (bool) $result;
|
||||
|
Loading…
Reference in New Issue
Block a user