Skip to content

Commit 33e338b

Browse files
authored
Merge b318821 into 68fb8bd
2 parents 68fb8bd + b318821 commit 33e338b

25 files changed

+1206
-241
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: 159 additions & 19 deletions
Large diffs are not rendered by default.

clients/nutclient.h

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@
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 (1 << 2) /* Can use CERTIDENT (verify cert */
67+
/* name, private key password) */
6668

6769

6870
namespace nut
@@ -109,22 +111,25 @@ class SSLConfig_OpenSSL : public SSLConfig
109111
SSLConfig_OpenSSL(bool force_ssl = false, int certverify = -1,
110112
const std::string& ca_path = "", const std::string& ca_file = "",
111113
const std::string& cert_file = "", const std::string& key_file = "",
112-
const std::string& key_pass = "")
114+
const std::string& key_pass = "", const std::string& certident_name = "")
113115
: 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) {}
116+
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass),
117+
_certident_name(certident_name) {}
115118

116119
SSLConfig_OpenSSL(bool force_ssl, int certverify,
117120
const char *ca_path, const char *ca_file,
118121
const char *cert_file, const char *key_file,
119-
const char *key_pass)
122+
const char *key_pass, const char *certident_name = nullptr)
120123
: 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) {}
124+
_cert_file(cert_file), _key_file(key_file), _key_pass(key_pass),
125+
_certident_name(certident_name) {}
122126

123127
const std::string& getCAPath() const { return _ca_path; }
124128
const std::string& getCAFile() const { return _ca_file; }
125129
const std::string& getCertFile() const { return _cert_file; }
126130
const std::string& getKeyFile() const { return _key_file; }
127131
const std::string& getKeyPass() const { return _key_pass; }
132+
const std::string& getCertIdentName() const { return _certident_name; }
128133

129134
virtual void apply(TcpClient& client) const override;
130135

@@ -134,6 +139,7 @@ class SSLConfig_OpenSSL : public SSLConfig
134139
std::string _cert_file;
135140
std::string _key_file;
136141
std::string _key_pass;
142+
std::string _certident_name;
137143
};
138144

139145
/**
@@ -826,8 +832,9 @@ class TcpClient : public Client
826832
* \param cert_file Path to a client certificate file (PEM format for OpenSSL) or nickname (NSS).
827833
* \param key_file Path to a client private key file (PEM format for OpenSSL).
828834
* \param key_pass Optional passphrase to decrypt the private key.
835+
* \param certident_name Expected name in the client certificate (CN or SAN).
829836
*/
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);
837+
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);
831838

832839
/**
833840
* Set SSL configuration for OpenSSL.
@@ -838,8 +845,9 @@ class TcpClient : public Client
838845
* \param cert_file Path to a client certificate file (PEM format for OpenSSL) or nickname (NSS).
839846
* \param key_file Path to a client private key file (PEM format for OpenSSL).
840847
* \param key_pass Optional passphrase to decrypt the private key.
848+
* \param certident_name Expected name in the client certificate (CN or SAN).
841849
*/
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);
850+
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 = "");
843851

844852
/**
845853
* Set SSL configuration for Mozilla NSS
@@ -1486,11 +1494,13 @@ NUTCLIENT_TCP_t nutclient_tcp_create_client_ssl_OpenSSL(
14861494
const char* host, uint16_t port, int try_ssl,
14871495
int force_ssl, int certverify,
14881496
const char *ca_path, const char *ca_file,
1489-
const char *cert_file, const char *key_file, const char *key_pass);
1497+
const char *cert_file, const char *key_file,
1498+
const char *key_pass, const char *certident_name);
14901499
void nutclient_tcp_set_ssl_config_OpenSSL(NUTCLIENT_TCP_t client,
14911500
int force_ssl, int certverify,
14921501
const char *ca_path, const char *ca_file,
1493-
const char *cert_file, const char *key_file, const char *key_pass);
1502+
const char *cert_file, const char *key_file,
1503+
const char *key_pass, const char *certident_name);
14941504

14951505
NUTCLIENT_TCP_t nutclient_tcp_create_client_ssl_NSS(
14961506
const char* host, uint16_t port, int try_ssl,

0 commit comments

Comments
 (0)