mdavidsaver / pvxs

PVA protocol client/server library and utilities.
https://mdavidsaver.github.io/pvxs/
Other
19 stars 25 forks source link

TLS #53

Open mdavidsaver opened 10 months ago

mdavidsaver commented 10 months ago

Applying OpenSSL to PVXS.

Wire compatibility with existing (plain tcp) clients/servers is maintained. Likewise this PR is compatible with work by @kasemir adding TLS support to core.pva in the phoebus repository.

To maintain compatibility. When configured with a keychain file, client search requests include two "protocol" names: tcp and tls. Server listens on a second TCP port for TLS connections, prefers to respond with tls when both present.

Adds x509 AUTHZ method. Client advertises x509 when configured with a client certificate. Server prefers x509 to ca. If selected, uses client cert commonName as account name. eg. CN=foo appears to ACF logic as foo. (note, this really needs an extension to the ACF logic to account for different source of accounts)

TLS features/restrictions

New Configuration:

Building:

libevent must be built with optional openssl support (bundled build will detect). openssl is expected to be installed in the default search path. I have no plans to bundled openssl.

TODO:

Supersedes https://github.com/mdavidsaver/pvxs-dev/pull/2

mdavidsaver commented 10 months ago

I think this work has progressed far enough to be (somewhat) more widely testable. The unittest process creates a consistent set of TLS certificates which may be useful for some manual testing. Though I would not recommend them for anything beyond some basic exploration. Some knowledge of x509 certificates will be needed to go beyond the recipe shown below.

An example of running the ticker example server, and subscribing with pvxmonitor.

EPICS_PVA_TLS_KEYCHAIN=test/O.linux-x86_64/server1.p12 \
  ./example/O.linux-x86_64/ticker cnt
EPICS_PVA_TLS_KEYCHAIN=test/O.linux-x86_64/ca.p12 \
  ./bin/linux-x86_64-debug/pvxmonitor cnt

Verification is easier with an IOC.

cat <<EOF > tick.db
record(calc, "\$(P=)cnt") {
  field(INPA, "\$(P=)cnt")
  field(CALC, "A+1")
  field(SCAN, "1 second")
}
EOF
EPICS_PVA_TLS_KEYCHAIN=test/O.linux-x86_64/server1.p12
  ./bin/linux-x86_64/softIocPVX -d tick.db
INFO: PVXS QSRV2 is loaded and ENABLED.
Starting iocInit
...
epics> dbl
cnt
epics> pvxsr 3
...
TLS Cert. subject:CN=server1 issuer:CN=intermediateCA from: Aug 17 17:00:23 2023 GMT until: Aug 14 17:00:24 2033 GMT
    Peer[fe80::7816:e3ff:fe25:5208]%5:59152 backlog=0 TX=994 RX=120 auth=ca TLS
        Cred: ca/mdavidsaver@[fe80::7816:e3ff:fe25:5208]%5:59152
        cnt TX=927 RX=46         Executing ioid=268443648 MONITOR
epics>

On the client side, switching from ca.p12 to client1.p12 will use client certificate authentication. Then Cred: ca/mdavidsaver... becomes Cred: x509rootCA/client1....

...
TLS Cert. subject:CN=server1 issuer:CN=intermediateCA from: Aug 17 17:00:23 2023 GMT until: Aug 14 17:00:24 2033 GMT
    Peer[fe80::7816:e3ff:fe25:5208]%5:40564 backlog=0 TX=1035 RX=86 auth=x509 TLS
        Cred: x509rootCA/client1@[fe80::7816:e3ff:fe25:5208]%5:40564
        Cert: subject:CN=client1 issuer:CN=intermediateCA from: Aug 17 17:00:24 2023 GMT until: Aug 14 17:00:25 2033 GMT
        cnt TX=968 RX=46         Executing ioid=268443648 MONITOR
mdavidsaver commented 10 months ago

Update. @kasemir When built against what will become openssl 3.2.x, test/gen_test_certs.cpp will now produce .p12 files which work with java. (see #ifdef NID_oracle_jdk_trustedkeyusage) Note that this does not yet apply to files produced by openssl pkcs12 ....

AppVeyorBot commented 10 months ago

:x: Build pvxs 1.0.925 failed (commit https://github.com/mdavidsaver/pvxs/commit/2dd4c3047b by @mdavidsaver)

AppVeyorBot commented 9 months ago

:white_check_mark: Build pvxs 1.0.932 completed (commit https://github.com/mdavidsaver/pvxs/commit/17690ff5cf by @mdavidsaver)

mdavidsaver commented 9 months ago

Updated to add $EPICS_PVAS_TLS_OPTIONS $EPICS_PVA_TLS_OPTIONS as space separated list of key=value pairs. Currently supported are client_cert=optional (default) and client_cert=required. Where required causes a server to set SSL_VERIFY_FAIL_IF_NO_PEER_CERT so that the TLS handshake will fail unless a valid client cert is presented.

mdavidsaver commented 9 months ago

I have also added another make variable OPENSSL which should function like LIBEVENT to set an external/non-epics installation prefix path when these packages are outside of the default search paths.

Also like LIBEVENT, OPENSSL should only be set during PVXS builds. The result is captured and written to cfg/TOOLCHAIN_PVXS.$(T_A) for use by dependent modules.

So if all goes well, the added dependency on libssl should not require changes to downstream Makefiles...

AppVeyorBot commented 9 months ago

:white_check_mark: Build pvxs 1.0.940 completed (commit https://github.com/mdavidsaver/pvxs/commit/2ddbc86084 by @mdavidsaver)

AppVeyorBot commented 4 days ago

:x: Build pvxs 1.0.1004 failed (commit https://github.com/mdavidsaver/pvxs/commit/d451688aef by @mdavidsaver)