commit - e64b43bec6df27f7e951b1c8878d1898928966b2
commit + 36dd1e7a7bf9f6dccf52a294d7d29221aef265f4
blob - 6c3d538ed4e09c5b81ac4bf4e384ded17b27ee87
blob + 05cf30a0f5855a076be4af9a203d7805172f6cbd
--- parse.y
+++ parse.y
-/* $OpenBSD: parse.y,v 1.262 2026/04/06 09:14:54 kirill Exp $ */
+/* $OpenBSD: parse.y,v 1.263 2026/05/15 13:57:24 rsadowski Exp $ */
/*
* Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org>
struct relay *relay_inherit(struct relay *, struct relay *);
int getservice(char *);
int is_if_in_group(const char *, const char *);
+static struct keyname *proto_keyname(char *);
typedef struct {
union {
free($3);
}
| KEYPAIR STRING {
- struct keyname *name;
+ struct keyname *kname = NULL;
- if (strlen($2) >= PATH_MAX) {
- yyerror("keypair name too long");
+ if ((kname = proto_keyname($2)) == NULL) {
free($2);
YYERROR;
}
- if ((name = calloc(1, sizeof(*name))) == NULL) {
- yyerror("calloc");
+ free($2);
+ }
+ | KEYPAIR STRING CERTIFICATE STRING {
+ struct keyname *kname = NULL;
+
+ if ((kname = proto_keyname($2)) == NULL) {
free($2);
+ free($4);
YYERROR;
}
- name->name = $2;
- TAILQ_INSERT_TAIL(&proto->tlscerts, name, entry);
+
+ if (strlen($4) >= PATH_MAX) {
+ yyerror("keypair cert too long");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+ if (strlcpy(kname->certificate, $4,
+ sizeof(kname->certificate)) >=
+ sizeof(kname->certificate)) {
+ yyerror("keypair certificate truncated");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+ free($2);
+ free($4);
}
+ | KEYPAIR STRING KEY STRING {
+ struct keyname *kname = NULL;
+
+ if ((kname = proto_keyname($2)) == NULL) {
+ free($2);
+ free($4);
+ YYERROR;
+ }
+
+ if (strlen($4) >= PATH_MAX) {
+ yyerror("keypair certificate key too long");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+
+ if (strlcpy(kname->key, $4,
+ sizeof(kname->key)) >=
+ sizeof(kname->key)) {
+ yyerror("keypair certificate key truncated");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+ free($2);
+ free($4);
+ }
+ | KEYPAIR STRING OCSP STRING {
+ struct keyname *kname = NULL;
+
+ if ((kname = proto_keyname($2)) == NULL) {
+ free($2);
+ free($4);
+ YYERROR;
+ }
+
+ if (strlen($4) >= PATH_MAX) {
+ yyerror("keypair ocsp file too long");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+
+ if (strlcpy(kname->ocsp, $4,
+ sizeof(kname->ocsp)) >=
+ sizeof(kname->ocsp)) {
+ yyerror("ocsp truncated");
+ free($2);
+ free($4);
+ YYERROR;
+ }
+ free($2);
+ free($4);
+ }
| CLIENT CA STRING {
if (strlcpy(proto->tlsclientca, $3,
sizeof(proto->tlsclientca)) >=
} '{' optnl relayopts_l '}' {
struct relay *r;
struct relay_config *rlconf = &rlay->rl_conf;
- struct keyname *name;
+ struct keyname *kname;
if (relay_findbyname(conf, rlconf->name) != NULL ||
relay_findbyaddr(conf, rlconf) != NULL) {
rlay->rl_conf.name);
YYERROR;
}
- TAILQ_FOREACH(name, &rlay->rl_proto->tlscerts, entry) {
+ TAILQ_FOREACH(kname, &rlay->rl_proto->tlscerts, entry) {
if (relay_load_certfiles(conf,
- rlay, name->name) == -1) {
+ rlay, kname) == -1) {
yyerror("cannot load keypair %s"
- " for relay %s", name->name,
+ " for relay %s", kname->name,
rlay->rl_conf.name);
YYERROR;
}
goto err;
}
TAILQ_FOREACH(name, &rb->rl_proto->tlscerts, entry) {
- if (relay_load_certfiles(conf, rb, name->name) == -1) {
+ if (relay_load_certfiles(conf, rb, name) == -1) {
yyerror("cannot load keypair %s for relay %s",
name->name, rb->rl_conf.name);
goto err;
close(s);
return (ret);
}
+
+struct keyname*
+proto_keyname(char *name)
+{
+ struct keyname *kname = NULL, *key;
+
+ if (strlen(name) >= PATH_MAX) {
+ yyerror("keypair name too long");
+ return NULL;
+ }
+
+
+ TAILQ_FOREACH(key, &proto->tlscerts, entry) {
+ if (strcmp(key->name, name) == 0)
+ return key;
+ }
+
+ if ((kname = calloc(1, sizeof(*kname))) == NULL) {
+ return NULL;
+ }
+
+ if ((kname->name = strdup(name)) == NULL) {
+ free(kname);
+ return NULL;
+ }
+ TAILQ_INSERT_TAIL(&proto->tlscerts, kname, entry);
+ return kname;
+}
blob - 9eb1b452d8122be2aaf05dd19dcb84e15b560d49
blob + 92c4320ce130adc612f1a667ea292a357b7dd874
--- relayd.c
+++ relayd.c
-/* $OpenBSD: relayd.c,v 1.197 2026/03/02 19:28:01 rsadowski Exp $ */
+/* $OpenBSD: relayd.c,v 1.198 2026/05/15 13:57:24 rsadowski Exp $ */
/*
* Copyright (c) 2007 - 2016 Reyk Floeter <reyk@openbsd.org>
}
int
-relay_load_certfiles(struct relayd *env, struct relay *rlay, const char *name)
+relay_load_certfiles(struct relayd *env, struct relay *rlay, const struct keyname *name)
{
char certfile[PATH_MAX];
char hbuf[PATH_MAX];
struct protocol *proto = rlay->rl_proto;
struct relay_cert *cert;
int useport = htons(rlay->rl_conf.port);
- int cert_fd = -1, key_fd = -1, ocsp_fd = -1;
+ int cert_fd = -1, key_fd = -1, ocsp_fd = -1, ret = 0;
if (rlay->rl_conf.flags & F_TLSCLIENT) {
if (strlen(proto->tlsca) && rlay->rl_tls_ca_fd == -1) {
print_host(&rlay->rl_conf.ss, hbuf, sizeof(hbuf)) == NULL)
goto fail;
else if (name != NULL &&
- strlcpy(hbuf, name, sizeof(hbuf)) >= sizeof(hbuf))
+ strlcpy(hbuf, name->name, sizeof(hbuf)) >= sizeof(hbuf))
goto fail;
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/%s:%u.crt", hbuf, useport) == -1)
- goto fail;
+ if (name != NULL && strcmp(name->certificate, "") != 0) {
+ if (strlcpy(certfile, name->certificate, sizeof(certfile))
+ >= sizeof(certfile)) {
+ log_warnx("certificate truncated");
+ goto fail;
+ }
+ }
+ else {
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/%s:%u.crt", hbuf, useport);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
+ goto fail;
+ }
if ((cert_fd = open(certfile, O_RDONLY)) == -1) {
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/%s.crt", hbuf) == -1)
+
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/%s.crt", hbuf);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
goto fail;
if ((cert_fd = open(certfile, O_RDONLY)) == -1)
goto fail;
}
log_debug("%s: using certificate %s", __func__, certfile);
- if (useport) {
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/private/%s:%u.key", hbuf, useport) == -1)
+ if (name != NULL && strcmp(name->key, "") != 0) {
+ if (strlcpy(certfile, name->key, sizeof(certfile))
+ >= sizeof(certfile)) {
+ log_warnx("certificate key truncated");
goto fail;
- } else {
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/private/%s.key", hbuf) == -1)
- goto fail;
+ }
}
+ else {
+ if (useport) {
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/private/%s:%u.key",
+ hbuf, useport);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
+ goto fail;
+ } else {
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/private/%s.key", hbuf);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
+ goto fail;
+ }
+ }
if ((key_fd = open(certfile, O_RDONLY)) == -1)
goto fail;
log_debug("%s: using private key %s", __func__, certfile);
- if (useport) {
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/%s:%u.ocsp", hbuf, useport) == -1)
+ if (name != NULL && strcmp(name->ocsp, "") != 0) {
+ if (strlcpy(certfile, name->ocsp, sizeof(certfile))
+ >= sizeof(certfile)) {
+ log_warnx("certificate ocsp truncated");
goto fail;
- } else {
- if (snprintf(certfile, sizeof(certfile),
- "/etc/ssl/%s.ocsp", hbuf) == -1)
- goto fail;
+ }
+
}
+ else {
+ if (useport) {
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/%s:%u.ocsp",
+ hbuf, useport);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
+ goto fail;
+ } else {
+ ret = snprintf(certfile, sizeof(certfile),
+ "/etc/ssl/%s.ocsp", hbuf);
+
+ if (ret < 0 || (size_t)ret >= sizeof(certfile))
+ goto fail;
+ }
+ }
if ((ocsp_fd = open(certfile, O_RDONLY)) != -1)
log_debug("%s: using OCSP staple file %s", __func__, certfile);
blob - a63dd4e3a41c38d9399b068d271ce69a342febce
blob + f51bf540fa6ed755484a9b290e57de2668fb7337
--- relayd.conf.5
+++ relayd.conf.5
-.\" $OpenBSD: relayd.conf.5,v 1.215 2026/02/18 22:27:03 kirill Exp $
+.\" $OpenBSD: relayd.conf.5,v 1.216 2026/05/15 13:57:24 rsadowski Exp $
.\"
.\" Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
.\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 18 2026 $
+.Dd $Mdocdate: May 15 2026 $
.Dt RELAYD.CONF 5
.Os
.Sh NAME
The default is
.Ic no edh .
.It Ic keypair Ar name
-The relay will attempt to look up a private key in
+.It Ic keypair Ar name Op Ic cert Ar "path"
+.It Ic keypair Ar name Op Ic key Ar "path"
+.It Ic keypair Ar name Op Ic ocsp Ar "path"
+The relay will attempt to look up the TLS assets associated with
+.Ar name .
+The optional
+.Ar path
+arguments must be enclosed in double quotes and specify the absolute path to
+the respective file.
+By default, it searches for a private key in
.Pa /etc/ssl/private/name:port.key
and a public certificate in
.Pa /etc/ssl/name:port.crt ,
.Pa /etc/ssl/private/name.key
and
.Pa /etc/ssl/name.crt .
+.Pp
+If the
+.Ic cert ,
+.Ic key ,
+or
+.Ic ocsp
+keywords are followed by an explicit
+.Ar path ,
+that file will be used instead of the default location.
+.Pp
This option can be specified multiple times for TLS Server Name Indication.
If not specified,
a keypair will be loaded using the specified IP address of the relay as
.Xr ssl 8
for details about TLS server certificates.
.Pp
-An optional OCSP staple file will be used during TLS handshakes with
-this server if it is found as a non-empty file in
+An optional OCSP staple file will be used during TLS handshakes.
+If no explicit
+.Ic ocsp Ar path
+is given, it will be searched as a non-empty file in
.Pa /etc/ssl/name:port.ocsp
or
.Pa /etc/ssl/name.ocsp .
blob - a5363989f4b4cbcca6c899b12de4ccd3cdf4dfcb
blob + 5536b4789e4a72220ebafef985a5ab8fc8e945b8
--- relayd.h
+++ relayd.h
-/* $OpenBSD: relayd.h,v 1.278 2026/03/02 19:28:01 rsadowski Exp $ */
+/* $OpenBSD: relayd.h,v 1.279 2026/05/15 13:57:24 rsadowski Exp $ */
/*
* Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org>
struct keyname {
TAILQ_ENTRY(keyname) entry;
char *name;
+ char certificate[PATH_MAX];
+ char key[PATH_MAX];
+ char ocsp[PATH_MAX];
};
TAILQ_HEAD(keynamelist, keyname);
struct relay_cert *cert_find(struct relayd *, objid_t);
char *relay_load_fd(int, off_t *);
int relay_load_certfiles(struct relayd *, struct relay *,
- const char *);
+ const struct keyname *);
int expand_string(char *, size_t, const char *, const char *);
void translate_string(char *);
void purge_key(char **, off_t);