Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trust: How to import certificates programmatically via a plugin? #8141

Open
2 tasks done
fraenki opened this issue Dec 18, 2024 · 5 comments
Open
2 tasks done

Trust: How to import certificates programmatically via a plugin? #8141

fraenki opened this issue Dec 18, 2024 · 5 comments
Labels
support Community support

Comments

@fraenki
Copy link
Member

fraenki commented Dec 18, 2024

Important notices

Our forum is located at https://forum.opnsense.org , please consider joining discussions there in stead of using GitHub for these matters.

Before you ask a new question, we ask you kindly to acknowledge the following:

The Acme Client Plugin plugin frequently imports new certificates to the OPNsense Trust Storage. However, it still uses the legacy method of importing certificates, which has severe drawbacks.

So I'm wondering: is there a new method available? I couldn't find one. Please point me to the right direction (no in-depth example necessary). Thanks! 😊

@fraenki fraenki added the support Community support label Dec 18, 2024
@AdSchellevis
Copy link
Member

Hi Frank, from code on the machine, you can implement the model. Do you have a code snippet you're currently using to import certificates? maybe I can offer you a small example on how to do that using the model.

@fraenki
Copy link
Member Author

fraenki commented Dec 18, 2024

Sure, but it's not pretty. 😄

https://github.com/opnsense/plugins/blob/fc5629d810ac8b447f9aca1f6fac1f6c646b3739/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/LeCertificate.php#L271-L290

This is the part where the certificated is added to the config "the legacy way". In the lines before this the cert entry is crafted using the legacy cert_import() function.

@AdSchellevis
Copy link
Member

ok, so seek and update by refid, I'll try to glue an example today, no problem.

@fraenki
Copy link
Member Author

fraenki commented Dec 18, 2024

Converting my code to use the new cert uuid may also be an option, in case this matters.

@AdSchellevis
Copy link
Member

ok, here we go, first some functional example code to update a certificate, the description in this case, but other fields do work more or less the same:

/* make sure we can access modules, when using legacy code, an import of config.inc would do the same, not needed when fit into a controller as the autoloader handles this */
require_once("script/load_phalcon.php");

/* Import the things we need, can also refer to the classes using their full path  */
use \OPNsense\Trust\Cert;
use \OPNsense\Core\Config;
use \OPNsense\Base\ValidationException;

/* define the refid we're looking for */
$ref_id_to_locate = '566f19a720af4';

/* create a model and seek for the refid, we use $target_node to collect the result */
$mdl = new Cert();
$target_node = null;
foreach ($mdl->cert->iterateItems() as $node) {
   if ($node->refid == $ref_id_to_locate) {
       $target_node = $node;
       break;
   }
}

/* When not found, create a new node */
if ($target_node === null) {
    $target_node = $mdl->cert->Add();
}

/* as $target_node is a pointer, we can update the node now */
$target_node->descr = 'new_description';

/* now validate and persist */
try {
    $mdl->serializeToConfig();
    Config::getInstance()->save();
} catch (ValidationException $e){
   /* your error handler here */
    echo "handle validation error\n";
} 

When you risk concurrency, you can lock the operation using Config::getInstance()->lock();, but not when combining it with legacy code. (and you do need to make sure your operation doesn't lock the machine endlessly)

If the upsert by refid is a pattern used more often, I also don't mind adding a method in the model which retrieves a record or creates a new one based on the offered refid. uuid's are slightly easier to handle, but snice the refid's are used in more places there's nothing wrong with sticking to them.

Relevant functions to use certificates can be found in https://github.com/opnsense/core/blob/master/src/opnsense/mvc/app/library/OPNsense/Trust/Store.php, which should avoid the need for cert.inc as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support Community support
Development

No branches or pull requests

2 participants