Skip to content

Commit b2daf94

Browse files
authored
Merge 405695a into 68fb8bd
2 parents 68fb8bd + 405695a commit b2daf94

26 files changed

+1413
-271
lines changed

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,8 @@ SET_PARMAKES_OPT = \
874874
fi ; \
875875
PARMAKES_OPT="-j $${MAXPARMAKES}" ; \
876876
;; \
877-
esac
877+
esac ; \
878+
if [ x"$${V}$(V)" = x ]; then PARMAKES_OPT="$${PARMAKES_OPT} V=0" ; fi
878879

879880
all-quick: @dotMAKE@
880881
+@$(SET_PARMAKES_OPT); \

NEWS.adoc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,29 @@ https://github.com/networkupstools/nut/milestone/13
6060
query (for protocol version) to verify that handshake succeeded.
6161
This change impacted also the classic C `libupsclient` library.
6262
[issue #3387, PR #3402]
63+
* Updated OpenSSL code paths in the `libupsclient` C library to support
64+
features earlier only available with NSS builds, like specifying the
65+
client certificate+key, optionally with password, and pinning expected
66+
server certificates. For both backends such pinning should now honour
67+
the 'certverify' setting of the `CERTHOST` entry (e.g. not abort the
68+
connection attempt if that number is '0'). [issue #3331]
69+
* Updated SSL support in the `upsd` data server to handle `CERTREQUEST`
70+
(optional validation of clients identified by a certificate) also
71+
when built with OpenSSL, optionally using the `CERTPATH` with a
72+
collection of CA certificates (directory or a big PEM file).
73+
Also support `CERTIDENT` to provide a private key password and ensure
74+
that the certificate in `CERTFILE` has an expected subject name as an
75+
exact string, or that its CN or SAN match the provided string as a
76+
standard expression of host name (section 3.5 of RFC 1034) or IP address.
77+
[issue #3331]
78+
* The `libupsclient` API was extended with a `upscli_init2()` method which
79+
allows to pass the `certfile` argument needed for OpenSSL builds. [#3331]
80+
* The `libupsclient` (C) and `libnutclient` (C++) API were updated to
81+
report the ability to check `CERTIDENT` information. [#3331]
82+
83+
- `upsmon` client updates:
84+
* Introduced support for `CERTFILE` option, so the client can identify
85+
itself to the data server also in OpenSSL builds. [issue #3331]
6386

6487

6588
Release notes for NUT 2.8.5 - what's new since 2.8.4

clients/nutclient.cpp

Lines changed: 165 additions & 19 deletions
Large diffs are not rendered by default.

clients/nutclient.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@
6161
#endif
6262

6363
#define UPSCLI_SSL_CAPS_NONE 0 /* No ability to use SSL */
64-
#define UPSCLI_SSL_CAPS_OPENSSL 1 /* Can use OpenSSL-specific setup */
65-
#define UPSCLI_SSL_CAPS_NSS 2 /* Can use Mozilla NSS-specific setup */
64+
#define UPSCLI_SSL_CAPS_OPENSSL (1 << 0) /* Can use OpenSSL-specific setup */
65+
#define UPSCLI_SSL_CAPS_NSS (1 << 1) /* Can use Mozilla NSS-specific setup */
66+
#define UPSCLI_SSL_CAPS_CERTIDENT_PASS (1 << 2) /* Can use CERTIDENT (verify private key password) */
67+
#define UPSCLI_SSL_CAPS_CERTIDENT_NAME (1 << 3) /* Can use CERTIDENT (verify cert name) */
68+
#define UPSCLI_SSL_CAPS_CERTIDENT (UPSCLI_SSL_CAPS_CERTIDENT_PASS | UPSCLI_SSL_CAPS_CERTIDENT_NAME)
6669

6770

6871
namespace nut
@@ -109,22 +112,25 @@ class SSLConfig_OpenSSL : public SSLConfig
109112
SSLConfig_OpenSSL(bool force_ssl = false, int certverify = -1,
110113
const std::string& ca_path = "", const std::string& ca_file = "",
111114
const std::string& cert_file = "", const std::string& key_file = "",
112-
const std::string& key_pass = "")
115+
const std::string& key_pass = "", const std::string& certident_name = "")
113116
: SSLConfig(force_ssl, certverify), _ca_path(ca_path), _ca_file(ca_file),
114-
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass) {}
117+
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass),
118+
_certident_name(certident_name) {}
115119

116120
SSLConfig_OpenSSL(bool force_ssl, int certverify,
117121
const char *ca_path, const char *ca_file,
118122
const char *cert_file, const char *key_file,
119-
const char *key_pass)
123+
const char *key_pass, const char *certident_name = nullptr)
120124
: SSLConfig(force_ssl, certverify), _ca_path(ca_path), _ca_file(ca_file),
121-
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass) {}
125+
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass),
126+
_certident_name(certident_name) {}
122127

123128
const std::string& getCAPath() const { return _ca_path; }
124129
const std::string& getCAFile() const { return _ca_file; }
125130
const std::string& getCertFile() const { return _cert_file; }
126131
const std::string& getKeyFile() const { return _key_file; }
127132
const std::string& getKeyPass() const { return _key_pass; }
133+
const std::string& getCertIdentName() const { return _certident_name; }
128134

129135
virtual void apply(TcpClient& client) const override;
130136

@@ -134,6 +140,7 @@ class SSLConfig_OpenSSL : public SSLConfig
134140
std::string _cert_file;
135141
std::string _key_file;
136142
std::string _key_pass;
143+
std::string _certident_name;
137144
};
138145

139146
/**
@@ -826,8 +833,9 @@ class TcpClient : public Client
826833
* \param cert_file Path to a client certificate file (PEM format for OpenSSL) or nickname (NSS).
827834
* \param key_file Path to a client private key file (PEM format for OpenSSL).
828835
* \param key_pass Optional passphrase to decrypt the private key.
836+
* \param certident_name Expected name in the client certificate (CN or SAN).
829837
*/
830-
void setSSLConfig_OpenSSL(bool force_ssl, int certverify, const char *ca_path, const char *ca_file, const char *cert_file, const char *key_file, const char *key_pass);
838+
void setSSLConfig_OpenSSL(bool force_ssl, int certverify, const char *ca_path, const char *ca_file, const char *cert_file, const char *key_file, const char *key_pass, const char *certident_name = nullptr);
831839

832840
/**
833841
* Set SSL configuration for OpenSSL.
@@ -838,8 +846,9 @@ class TcpClient : public Client
838846
* \param cert_file Path to a client certificate file (PEM format for OpenSSL) or nickname (NSS).
839847
* \param key_file Path to a client private key file (PEM format for OpenSSL).
840848
* \param key_pass Optional passphrase to decrypt the private key.
849+
* \param certident_name Expected name in the client certificate (CN or SAN).
841850
*/
842-
void setSSLConfig_OpenSSL(bool force_ssl, int certverify, const std::string& ca_path, const std::string& ca_file, const std::string& cert_file, const std::string& key_file, const std::string& key_pass);
851+
void setSSLConfig_OpenSSL(bool force_ssl, int certverify, const std::string& ca_path, const std::string& ca_file, const std::string& cert_file, const std::string& key_file, const std::string& key_pass, const std::string& certident_name = "");
843852

844853
/**
845854
* Set SSL configuration for Mozilla NSS
@@ -1486,11 +1495,13 @@ NUTCLIENT_TCP_t nutclient_tcp_create_client_ssl_OpenSSL(
14861495
const char* host, uint16_t port, int try_ssl,
14871496
int force_ssl, int certverify,
14881497
const char *ca_path, const char *ca_file,
1489-
const char *cert_file, const char *key_file, const char *key_pass);
1498+
const char *cert_file, const char *key_file,
1499+
const char *key_pass, const char *certident_name);
14901500
void nutclient_tcp_set_ssl_config_OpenSSL(NUTCLIENT_TCP_t client,
14911501
int force_ssl, int certverify,
14921502
const char *ca_path, const char *ca_file,
1493-
const char *cert_file, const char *key_file, const char *key_pass);
1503+
const char *cert_file, const char *key_file,
1504+
const char *key_pass, const char *certident_name);
14941505

14951506
NUTCLIENT_TCP_t nutclient_tcp_create_client_ssl_NSS(
14961507
const char* host, uint16_t port, int try_ssl,

0 commit comments

Comments
 (0)