Skip to content

Conversation

klemens-ya
Copy link

@klemens-ya klemens-ya commented Sep 24, 2025

This allows for accepting clients based on their certificate authority:

        x509-username-field issuer CN
        verify-x509-name    ...CA=ExampleCA_ match-prefix

tls-verify or plugin can do the equivalent, but require additional code
execution and always incur overhead or may not be an option when running with
reduced privileges, e.g. chroot.

Motivation:
ca contains the root CA and the intermediate CA issuing client certificates.

Under the same root CA, another intermediate CA exists, not intended for VPN.

The problem is that OpenVPN successfully validates all certificate chains, i.e.
with both intermediates, whilst one one of them should allow peers to connect.

AFAIU, this is expected OpenSSL behaviour, at least when OpenVPN peers send not
only their own, but also their issuer CA’s certificate via cert.

Thus reusing the customisable username mechanism allows for limiting to certain
CAs, i.e. rejecting unwanted peers, as early as possible during handshake.

(remote-cert-ku might be a viable alternative, but requires the X509v3
extension and respective key usage bits set up front; I have not tried that.)

Tested against

  • FreeBSD 13, OpenSSL 1.1.1t, OpenVPN 2.5.6
  • OpenBSD 7.7-stable, LibreSSL 4.1.0, OpenVPN 2.6.4
  • OpenBSD 7.7-current, LibreSSL 4.1.0, OpenVPN f7aedca

This allows for accepting clients based on their certificate authority:
        x509-username-field issuer CN
        verify-x509-name    ...CA=ExampleCA_ match-prefix

`tls-verify` or `plugin` can do the equivalent, but require additional code
execution and always incur overhead or may not be an option when running with
reduced privileges, e.g. `chroot`.

Motivation:
  `ca` contains the root CA and the intermediate CA issuing client certificates.

Under the same root CA, another intermediate CA exists, not intended for VPN.

The problem is that OpenVPN successfully validates all certificate chains, i.e.
with both intermediates, whilst one one of them should allow peers to connect.

AFAIU, this is expected OpenSSL behaviour, at least when OpenVPN peers send not
only their own, but also their issuer CA’s certificate via `cert`.

Thus reusing the customisable username mechanism allows for limiting to certain
CAs, i.e. rejecting unwanted peers, as early as possible during handshake.

(`remote-cert-ku` might be a viable alternative, but requires the X509v3
 extension and respective key usage bits set up front;  I have not tried that.)

Tested against
- FreeBSD 13,          OpenSSL 1.1.1t, OpenVPN 2.5.6
- OpenBSD 7.7-stable,  LibreSSL 4.1.0, OpenVPN 2.6.4
- OpenBSD 7.7-current, LibreSSL 4.1.0, OpenVPN f7aedca
@klemens-ya
Copy link
Author

This was initially sent via https://sourceforge.net/p/openvpn/mailman/message/59175602/, but for some reason my posts to the mailing lists get prefixed with [SPAM] and my last answer never even made it.

@schwabe
Copy link
Contributor

schwabe commented Sep 24, 2025

This reminds me of the --verify-hash feature we deprecated since nobody came up with a really good use case. The main argument was that if you want to accept only from certain sub CA, you would/should probably only have those CAs in your --capath directroy.

These seem to be in the same direction, so the question is the same. If you only want certain sub CAs to be accept, why to this complicated way instead of using --capath?

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

Successfully merging this pull request may close these issues.

2 participants