Skip to content
Advertisement

Using openpgp-php with the Symfony framework Attempted to load class “OpenPGP_SecretKeyPacket” from namespace “AppController”

I found this answer and it helped me half the way: How do you use the PHP OpenPGP library?

First of all, due to dependencies I really failed to set it up properly by just downloading it. But as I have Symfony running and installed with composer, I finally got pgp installed (but not working) in Symfony by running composer require singpolyma/openpgp-php which installed it and the dependencies into the vendor folder.

I can use pgp in a standalone php-file if I requires as follows, but this does not work in the controller (even if I add the requires it does not fail more or less than without)

require("../vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php");
require("../vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php");
require("../vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php");
require("../vendor/singpolyma/openpgp-php/lib/openpgp_crypt_rsa.php");

In the AbstractController of Symfony it does not work that way. I crushed my Brain which “use” command I should use and I just have no more ideas.

from composer.json the name is

"name": "singpolyma/openpgp-php",

but a minus is not a valid name in a namespace.

I usually get the error

Attempted to load class “OpenPGP_SecretKeyPacket” from namespace “AppController”. Did you forget a “use” statement for another namespace?

<?php
namespace AppController;

use SymfonyComponentHttpFoundationResponse;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentRoutingAnnotationRoute;
use DoctrineORMEntityManagerInterface;

class PageApiController extends AbstractController
{
    /**
    @Route("/ApiTest", methods={"GET"})
    */
    public function ApiTest(EntityManagerInterface $entityManager)
    {
        $rsa = new phpseclibCryptRSA(); // HERE comes the ERROR
        $k = $rsa->createKey(512);
        $rsa->loadKey($k['privatekey']);

        $nkey = new OpenPGP_SecretKeyPacket(array(
        'n' => $rsa->modulus->toBytes(),
        'e' => $rsa->publicExponent->toBytes(),
        'd' => $rsa->exponent->toBytes(),
        'p' => $rsa->primes[2]->toBytes(),
        'q' => $rsa->primes[1]->toBytes(),
        'u' => $rsa->coefficients[2]->toBytes()
        ));

        $uid = new OpenPGP_UserIDPacket('Test <test@example.com>');

        $wkey = new OpenPGP_Crypt_RSA($nkey);
        $m = $wkey->sign_key_userid(array($nkey, $uid));

        // Serialize private key
        $Data = $m->to_bytes();

        return $this->json(['Test' => $Data]);
    }
}

I must admit I am not used to namespaces in php and I know I do not really understand what is going on in symfony yet. I am very grateful for any hint to namespaces in Symfony.

Advertisement

Answer

There are actually two libraries involved here. The phpseclib is namespaced so things like the RSA class can be used with a simple new RSA(). However, the OpenPGP stuff is not namespaced and does not seem to support classic autoloading. Personally I would look for another more up to date library however you can use composer.json files capability to load the necessary include files. At which point you can create the secret key packet class cleanly. Which is as far as I went with testing.

# create a new project
symfony new --full pgp
cd pgp
composer require singpolyma/openpgp-php

# Edit composer.json
    "autoload": {
        "psr-4": {
            "App\": "src/"
        },
        "files": [
            "vendor/singpolyma/openpgp-php/lib/openpgp.php",
            "vendor/singpolyma/openpgp-php/lib/openpgp_crypt_rsa.php"
        ]
    },
# refresh autoload.php
composer dump-autoload

# Add a test command
namespace AppCommand;

use phpseclibCryptRSA;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;

class PgpCommand extends Command
{
    protected static $defaultName = 'pgp:test';

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $rsa = new RSA();
        $k = $rsa->createKey(512);
        $rsa->loadKey($k['privatekey']);

        // Note the leading back slash
        $nkey = new OpenPGP_SecretKeyPacket(array(
            'n' => $rsa->modulus->toBytes(),
            'e' => $rsa->publicExponent->toBytes(),
            'd' => $rsa->exponent->toBytes(),
            'p' => $rsa->primes[2]->toBytes(),
            'q' => $rsa->primes[1]->toBytes(),
            'u' => $rsa->coefficients[2]->toBytes()
        ));
        return Command::SUCCESS;
    }
}

# and test
bin/console pgp:test
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement