/** * @param $base64 * @return array */ public function unserialize($base64) { $binary = base64_decode($base64, true); if ($binary === false) { throw new \InvalidArgumentException('Invalid base64'); } $values = []; $pos = 0; $end = strlen($binary); for ($i = 0; $i < 3; $i++) { if ($end - $pos < 4) { throw new \RuntimeException('Length marker too short'); } $length = unpack("N", substr($binary, $pos, 4))[1]; $pos += 4; if ($end - $pos < $length) { throw new \RuntimeException('Not enough data'); } $value = substr($binary, $pos, $length); $pos += $length; $values[$i] = $value; } $curveName = $values[1]; $pointHex = unpack("H*", $values[2])[1]; $curve = Curves::curve($curveName); $generator = Curves::generator($curveName); $point = $this->pointSerializer->unserialize($curve, $pointHex); $publicKey = new PublicKey($this->math, $generator, $point); return [$curve, $publicKey]; }
/** * @param InputInterface $input * @param OutputInterface $output * @return void */ protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln('<comment>Supported Curves</comment>'); $output->writeln(''); $output->writeln("The following curves are supported: "); foreach (Curves::listAll() as $curve) { $output->writeln(sprintf(" <info>%s</info>", $curve)); } }
/** * @dataProvider getCurveNames */ public function testLoad($name) { $load = Curves::load($name); $this->assertEquals(2, count($load)); /** * @var NamedCurveFp $curve * @var GeneratorPoint $generator */ list($curve, $generator) = $load; $this->assertInstanceOf('\\Mdanter\\Ecc\\Curves\\NamedCurveFp', $curve); $this->assertInstanceOf('\\Mdanter\\Ecc\\Primitives\\GeneratorPoint', $generator); $this->assertEquals($curve->getName(), $generator->getCurve()->getName()); }
/** * @dataProvider getVectors * @param string $curveName * @param string|int $multiplier * @param string $expectedPub */ public function testSerialize($curveName, $multiplier, $expectedPub) { /** @var GeneratorPoint $generator */ $generator = Curves::generator($curveName); $privateKey = $generator->getPrivateKeyFrom(gmp_init($multiplier, 10)); $public = $privateKey->getPublicKey(); $adapter = EccFactory::getAdapter(); $serializer = new SshPublicKeySerializer($adapter, new UncompressedPointSerializer($adapter)); $serialized = $serializer->serialize($curveName, $public); $this->assertEquals($expectedPub, $serialized); list($curve, $publicKey) = $serializer->unserialize($serialized); $this->assertTrue($public->getPoint()->equals($publicKey->getPoint())); }
/** * @param InputInterface $input * @param OutputInterface $output * @param QuestionHelper $helper * @param string $curveName * @param bool $useEncryption * @return array */ public function generateKeyData(InputInterface $input, OutputInterface $output, QuestionHelper $helper, $curveName, $useEncryption) { if (!is_bool($useEncryption)) { throw new \InvalidArgumentException('useEncryption parameter must be a boolean'); } /** * @var GeneratorPoint $generator */ list(, $generator) = Curves::load($curveName); $key = $generator->createPrivateKey(); if ($useEncryption) { $password = $this->promptForPassword($input, $output, $helper); $encrypted = new EncryptedPrivateKey($key, 'AES-128-CBC', random_bytes(16)); $serializer = new EncryptedPrivateKeySerializer(new DerPrivateKeySerializer()); $keyData = $serializer->serialize($encrypted, $password); } else { $serializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer()); $keyData = $serializer->serialize($key); } $adapter = EccFactory::getAdapter(); $publicKey = $key->getPublicKey(); $publicSerializer = new SshPublicKeySerializer($adapter, new UncompressedPointSerializer($adapter)); $publicData = $publicSerializer->serialize($curveName, $publicKey); $localUser = posix_getpwuid(posix_geteuid()); $localHost = gethostname(); $publicData = sprintf("ecdsa-sha2-%s %s %s@%s\n", $curveName, $publicData, $localUser['name'], $localHost); return [$keyData, $publicData]; }
/** * @expectedException \RuntimeException */ public function testSerializeFailsToEncrypt() { /** @var GeneratorPoint $generator */ $generator = Curves::generator('nistp256'); $privateKey = $generator->getPrivateKeyFrom(gmp_init('1')); $method = 'not-a-method'; $iv = random_bytes(16); $cryptKey = new EncryptedPrivateKey($privateKey, $method, $iv); $adapter = EccFactory::getAdapter(); $serializer = new EncryptedPrivateKeySerializer(new DerPrivateKeySerializer($adapter)); $serializer->serialize($cryptKey, 'password'); }