Project

General

Profile

Actions

Bug #1538

closed

openvpn-client-export.inc -- issue with ca.crt lookup

Added by Epi Salamanca over 13 years ago. Updated over 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
Start date:
05/18/2011
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
Affected Version:
2.0
Affected Plus Version:
Affected Architecture:

Description

Hi,
I'm currently running pfSense 2.0 RC1.
I've just installed OpenVpn-client-export package. Whenever
that I try to export openvpn configuration for a given user.
An error is generated because 'server_ca' cannot be found.
I've check the source code for openvpn-client-export.inc,
and currently the code is as follows:

// lookup server certificate info
$server_cert = lookup_cert($settings['certref']);
$server_ca = lookup_ca($server_cert['caref']);
if (!$server_cert || !$server_ca) {
$input_errors[] = "Could not locate certificate.";
return false;
}

I've print out $server_cert array and there is no key named 'caref',
but 'caref' key exists on $settings array.
So after changing the code :
// lookup server certificate info
$server_cert = lookup_cert($settings['certref']);
//bug --> $server_ca = lookup_ca($server_cert['caref']);
//fix -->
$server_ca = lookup_ca($settings['caref']);
//fix <--
if (!$server_cert || !$server_ca) {
$input_errors[] = "Could not locate certificate.";
return false;
}

This error occurs at:

function openvpn_client_export_config(...);
function openvpn_client_export_installer(...);
function viscosity_openvpn_client_config_exporter(...)

Actions #1

Updated by Jim Pingle over 13 years ago

  • Status changed from New to Feedback

If the server certificate has no caref, then the system believes it wasn't generated against any CA. If the server certificate isn't from that CA, it isn't safe to use together.

Was the certificate/CA imported? Or made in the GUI? More detail is needed.

Actions #2

Updated by Epi Salamanca over 13 years ago

Jim,
you are right, the CA/certificate|key and server/certificate|key are both imported.
But the server/certificate is from that CA.

Actions #3

Updated by Jim Pingle over 13 years ago

How long ago did you import that certificate into a 2.0 install? I checked a CA/Cert I recently had imported into a VM and it had a proper caref.

Indeed the code does check to add a proper CA reference when importing a certificate:

    if($issuer <> $subject) {
        $issuer_crt =& lookup_ca_by_subject($issuer);
        if($issuer_crt)
            $cert['caref'] = $issuer_crt['refid'];
    }

So something about that CA/certificate must have made it not match up when you imported it (or perhaps you imported the cert before the CA, instead of the other way around).

Actions #4

Updated by Epi Salamanca over 13 years ago

I've just migrated, 2 days ago. So I imported it 1 day ago.
The issue seems to be with my ca_subject not matching to cert_issuer.

function & lookup_ca_by_subject($subject) {
        global $config;
        if (is_array($config['ca']))
                foreach ($config['ca'] as & $ca)
                {
                        $ca_subject = cert_get_subject($ca['crt']);
                        if ($ca_subject == $subject)
                                return $ca;
                }
        return false;
}

My current $ca_subject and $subject are:

ca_subject -> emailAddress=xxx, ST=xxx, OU=xx, O=xxx, L=xxx, CN=xxx, C=xxx
   subject -> emailAddress=xxx, CN=xxx, OU=xx, O=xxx, L=xxx, ST=xxx, C=xxx

So, yes they are a match, but they are not equal, in the strict syntax way.
($ca_subject and $subject here are a concatenation of strings ... )

I've looked into the code for certs.inc, and check how those strings are generated, and
everytime that subject is retrieved,see function cert_get_subject(...), the components
that made the array are sorted. Which is not the case for "issuer", see function cert_get_issuer(...)
-- Simple solution, that I've tested and it works, is to :

  function cert_get_issuer($str_crt, $decode = true) {

        if ($decode)
                $str_crt = base64_decode($str_crt);

        $inf_crt = openssl_x509_parse($str_crt);
        $components = $inf_crt['issuer'];

        if (!is_array($components))
                return "unknown";
//fix -->
        ksort($components);
//fix <--
        foreach ($components as $a => $v) {
                if (!strlen($issuer))
                        $issuer = "{$a}={$v}";
                else
                        $issuer = "{$a}={$v}, {$issuer}";
        }

        return $issuer;
}

Actions #5

Updated by Jim Pingle over 13 years ago

In the current code there is already a ksort there. I assume you upgraded to the official RC1 and not to a snapshot?

It was added in https://github.com/bsdperimeter/pfsense/commit/bfa992bc4eb8f8674f44b94e8617a032854356e9#etc/inc/certs.inc

Actions #6

Updated by Epi Salamanca over 13 years ago

Yes I updated to the official RC1.

So I guess it will be pushed on to the next RCx.

Mistery Solved :)

Thanks.

Actions #7

Updated by Jim Pingle over 13 years ago

  • Status changed from Feedback to Closed
Actions #8

Updated by Adam Thompson over 9 years ago

Still having what appears to be the same issue.
Generate a CSR from pfSense, get a signed cert (from StartSSL) for pfSense, import cert into pfSense.
Works great.
Assign that cert to OpenVPN server, try to use openvpn client export, get failure.

"The following input errors were detected:
Could not locate the CA reference for the server certificate.
Failed to export config files!"

Running on 2.2-RELEASE x86 (32-bit).
Public cert available for inspection at https://remote.avant.ca:8443/ and of course OpenVPN at that hostname, too.
Works perfectly with self-signed cert, but I don't want to force users to obtain and install self-signed cert, at least not until pfsense or openvpn provides a way to download it on demand.

Actions

Also available in: Atom PDF