Re: [s...@spacehopper.org: Re: Remove useless line from daemon class in login.conf]

2020-10-15 Thread Kurt Mosiejczuk
On Wed, Oct 14, 2020 at 02:41:51PM +0100, Stuart Henderson wrote:
> Just found this in my local tree still, iirc danj liked it but there
> wasn't much other enthusiasm. Any other comments? Should I just drop
> the diff? Change 'a' to use 2^10 minimum? Change to fixed 2^10 with
> no auto measurement?

I think this makes sense. I like it.

ok kmos

--Kurt

> - Forwarded message from Stuart Henderson  -
> 
> From: Stuart Henderson 
> Date: Sat, 23 May 2020 22:08:11 +0100
> Subject: Re: Remove useless line from daemon class in login.conf
> 
> On 2020/05/22 16:04, Theo de Raadt wrote:
> > Stuart Henderson  wrote:
> > 
> > > On 2020/05/22 17:06, Daniel Jakots wrote:
> > > > Hi,
> > > > 
> > > > We used to have different numbers of blowfish rounds between the
> > > > default and daemon classes in login.conf. On Jun 26, 2016, tedu
> > > > committed "upgrade selected login.conf to use auto rounds for bcrypt"
> > > > for amd64, sparc64, i386, and maccpc [1].
> > > > 
> > > > Since the class daemon inherits from the default class, the 
> > > > :localcipher=blowfish,a:\
> > > > is a duplicate.
> > > > 
> > > > Here's a diff to remove them.
> > > 
> > > I'm OK with unifying these settings, but FWIW I never switched to auto
> > > for these, it doesn't seem all that sensible for somebody with the ability
> > > to generate enough load on the machine to be able to reduce the strength
> > > of bcrypt down to the 64 (2^6) rounds minimum.
> > 
> > Yes, that is problematic.
> > 
> > The minimum should be probably be raised, we should consider if auto
> > should even exist anymore.
> > 
> 
> As long as it doesn't allow weakening things I think auto should still
> exist so that machines can have a stronger bcrypt where it's cheap.
> 
> When this was introduced, login.conf for amd64/i386/macppc/sparc64
> changed from 8 (normal users) and 9 (daemon class i.e. root) to auto.
> Since other, mainly slower, arches stayed with hardcoded 8/9 I don't
> think the current minimum reachable in the code makes sense at all.
> 
> I've gone to a few machines and done:
> 
> - 50 runs of "encrypt -b a" to see what setting was chosen by auto
> 
> for i in `jot 50`; do echo foo | encrypt -b a; sleep .1; done | cut -d'$' -f3 
> | sort | uniq -c
> 
> - 50 runs of "encrypt -b 9" or "encrypt -b 10" and averaged, to see
> how long those two settings take
> 
> time for i in `jot 50`; do echo foo | encrypt -b 10; done
> (divided by 50)
> 
>   Chosen  -b 9-b 10
> Cortex-A53 1.4GHz (pi3)   all 8   0.220.40
> GX-412TC 1GHz (APU2)  all 8   0.160.31
> Cortex-A72 1.5GHz (pi4)   all 9   0.070.14
> L5520 2.27GHz all 9   0.080.16
> E3-1225v3 3.2GHz  12x8 3x9 35x10  0.050.10
> E3-1240v5 3.5GHz  all 10  0.040.08
> E3-1270v6 3.8GHz  all 11  0.030.05
> 
> I think bumping the minimum to 2^9 would be reasonable, there's a more
> noticeable delay on some machines but I think that's fair enough (any
> cracking is likely to be done on a fast machine, and the user can force
> it lower themselves if they want to take the risk).
> 
> With a higher minimum than that the delay starts to get very noticeable
> in some cases, so I'm not sure we're ready for that yet.
> 
> I think it also makes sense to use blowfish,a in login.conf on all
> arches, replacing the old 8/9. Actually -b a is already used in the
> installer for both root and the standard user on all archs, whatever
> they have in login.conf. Resulting in the situation that on some
> archs, the bcrypt created during install for root's password is
> weaker than it would be if reset after boot.
> 
> So maybe this or something like it?
> 
> Index: lib/libc/crypt/bcrypt.c
> ===
> RCS file: /cvs/src/lib/libc/crypt/bcrypt.c,v
> retrieving revision 1.57
> diff -u -p -r1.57 bcrypt.c
> --- lib/libc/crypt/bcrypt.c   26 Aug 2016 08:25:02 -  1.57
> +++ lib/libc/crypt/bcrypt.c   23 May 2020 20:16:46 -
> @@ -237,14 +237,15 @@ bcrypt_checkpass(const char *pass, const
>  DEF_WEAK(bcrypt_checkpass);
>  
>  /*
> - * Measure this system's performance by measuring the time for 8 rounds.
> - * We are aiming for something that takes around 0.1s, but not too much over.
> + * Measure this system's performance by measuring the time for 2^9 rounds.
> + * We are aiming for something that takes around 0.1s, not too much over,
> + * but without allowing it to be too weak.
>   */
>  int
>  _bcrypt_autorounds(void)
>  {
>   struct timespec before, after;
> - int r = 8;
> + int r = 9;
>   char buf[_PASSWORD_LEN];
>   int duration;
>  
> @@ -257,12 +258,12 @@ _bcrypt_autorounds(void)
>   duration += (after.tv_nsec - before.tv_nsec) / 1000;
>  
>   /* too quick? slow it down. */
> - while (r < 16 && duration <= 6) {
> + while (r < 16 && duration <= 75000) {
>   r += 1;
>   

Non-const basename: usr.bin/ftp

2020-10-15 Thread Christian Weisgerber
Accommodate POSIX basename(3) that takes a non-const parameter and
may modify the string buffer.

I've tried to follow the conventions of the existing code.

ok?

Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.197
diff -u -p -r1.197 fetch.c
--- usr.bin/ftp/fetch.c 4 Jul 2020 11:23:35 -   1.197
+++ usr.bin/ftp/fetch.c 15 Oct 2020 21:14:28 -
@@ -192,7 +192,7 @@ file_get(const char *path, const char *o
int  fd, out = -1, rval = -1, save_errno;
volatile sig_t   oldintr, oldinti;
const char  *savefile;
-   char*buf = NULL, *cp;
+   char*buf = NULL, *cp, *pathbuf = NULL;
const size_t buflen = 128 * 1024;
off_thashbytes;
ssize_t  len, wlen;
@@ -215,8 +215,12 @@ file_get(const char *path, const char *o
else {
if (path[strlen(path) - 1] == '/')  /* Consider no file */
savefile = NULL;/* after dir invalid. */
-   else
-   savefile = basename(path);
+   else {
+   pathbuf = strdup(path);
+   if (pathbuf == NULL)
+   errx(1, "Can't allocate memory for filename");
+   savefile = basename(pathbuf);
+   }
}
 
if (EMPTYSTRING(savefile)) {
@@ -294,6 +298,7 @@ file_get(const char *path, const char *o
 
 cleanup_copy:
free(buf);
+   free(pathbuf);
if (out >= 0 && out != fileno(stdout))
close(out);
close(fd);
@@ -315,6 +320,7 @@ url_get(const char *origline, const char
int isunavail = 0, retryafter = -1;
struct addrinfo hints, *res0, *res;
const char *savefile;
+   char *pathbuf = NULL;
char *proxyurl = NULL;
char *credentials = NULL, *proxy_credentials = NULL;
int fd = -1, out = -1;
@@ -412,8 +418,12 @@ noslash:
else {
if (path[strlen(path) - 1] == '/')  /* Consider no file */
savefile = NULL;/* after dir invalid. */
-   else
-   savefile = basename(path);
+   else {
+   pathbuf = strdup(path);
+   if (pathbuf == NULL)
+   errx(1, "Can't allocate memory for filename");
+   savefile = basename(pathbuf);
+   }
}
 
if (EMPTYSTRING(savefile)) {
@@ -1106,6 +1116,7 @@ cleanup_url_get:
if (out >= 0 && out != fileno(stdout))
close(out);
free(buf);
+   free(pathbuf);
free(proxyhost);
free(proxyurl);
free(newline);
Index: usr.bin/ftp/util.c
===
RCS file: /cvs/src/usr.bin/ftp/util.c,v
retrieving revision 1.93
diff -u -p -r1.93 util.c
--- usr.bin/ftp/util.c  6 Jul 2020 17:11:29 -   1.93
+++ usr.bin/ftp/util.c  15 Oct 2020 21:31:55 -
@@ -763,7 +763,7 @@ progressmeter(int flag, const char *file
off_t cursize, abbrevsize;
double elapsed;
int ratio, barlength, i, remaining, overhead = 30;
-   char buf[512];
+   char buf[512], *filenamebuf;
 
if (flag == -1) {
clock_gettime(CLOCK_MONOTONIC, );
@@ -782,11 +782,13 @@ progressmeter(int flag, const char *file
ratio = MAXIMUM(ratio, 0);
ratio = MINIMUM(ratio, 100);
if (!verbose && flag == -1) {
-   filename = basename(filename);
-   if (filename != NULL) {
+   filenamebuf = strdup(filename);
+   filename = basename(filenamebuf);
+   if (filenamebuf != NULL && filename != NULL) {
free(title);
title = strdup(filename);
}
+   free(filenamebuf);
}
 
buf[0] = 0;
-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: _exit(2), execve(2): cancel interval timers MP-safely

2020-10-15 Thread Mark Kettenis
> Date: Wed, 14 Oct 2020 20:14:18 -0500
> From: Scott Cheloha 
> 
> On Wed, Oct 14, 2020 at 08:06:52PM -0500, Scott Cheloha wrote:
> > _exit(2) and execve(2) need to obey the locking protocol described in
> > proc.h when manipulating the per-process interval timer state.
> > 
> > While we're here we can also remove the now pointless splclock/splx
> > dance from execve(2).
> > 
> > The easiest way to obey the locking protocol is to reuse the interface
> > the syscalls are using: setitimer() in kern_time.c.
> > 
> > Given that we only want to cancel the timers I wrote a small helper
> > function, cancelitimer().  I think it's tidier than putting the
> > prototype for setitimer() into sys/time.h and requiring the caller to
> > prepare an itimerval struct before calling.
> > 
> > Compare:
> > 
> > struct itimerval itv;
> > timerclear(_value);
> > timerclear(_interval);
> > setitimer(ITIMER_REAL, , NULL);
> > 
> > with:
> > 
> > cancelitimer(ITIMER_REAL);
> > 
> > ... should I shove the for-loop into the helper function too?  Maybe
> > call it "cancel_all_itimers()"?  I have a vague feeling that showing
> > the reader that there are multiple timers is a good thing here, but
> > then again maybe I'm wrong and nobody cares.
> > 
> > Preferences?  ok?
> 
> Whoops, forgot the kern_time.c part of the diff.
> 
> Index: kern/kern_exit.c
> ===
> RCS file: /cvs/src/sys/kern/kern_exit.c,v
> retrieving revision 1.188
> diff -u -p -r1.188 kern_exit.c
> --- kern/kern_exit.c  18 Mar 2020 15:48:21 -  1.188
> +++ kern/kern_exit.c  15 Oct 2020 01:12:50 -
> @@ -194,7 +194,11 @@ exit1(struct proc *p, int xexit, int xsi
>   /* close open files and release open-file table */
>   fdfree(p);
>  
> - timeout_del(>ps_realit_to);
> + /* cancel all interval timers */
> + int i;

Don't put variable definitions in the middle of a function.

> + for (i = 0; i < nitems(pr->ps_timer); i++)
> + cancelitimer(i);
> +
>   timeout_del(>ps_rucheck_to);
>  #ifdef SYSVSEM
>   semexit(pr);
> Index: kern/kern_exec.c
> ===
> RCS file: /cvs/src/sys/kern/kern_exec.c,v
> retrieving revision 1.217
> diff -u -p -r1.217 kern_exec.c
> --- kern/kern_exec.c  11 Jul 2020 22:59:05 -  1.217
> +++ kern/kern_exec.c  15 Oct 2020 01:12:50 -
> @@ -656,14 +656,9 @@ sys_execve(struct proc *p, void *v, regi
>   }
>  
>   if (pr->ps_flags & PS_SUGIDEXEC) {
> - int i, s = splclock();
> -
> - timeout_del(>ps_realit_to);
> - for (i = 0; i < nitems(pr->ps_timer); i++) {
> - timespecclear(>ps_timer[i].it_interval);
> - timespecclear(>ps_timer[i].it_value);
> - }
> - splx(s);
> + int i;

You should put a blank line here to separate definitions from the code.

> + for (i = 0; i < nitems(pr->ps_timer); i++)
> + cancelitimer(i);
>   }
>  
>   /* reset CPU time usage for the thread, but not the process */
> Index: kern/kern_time.c
> ===
> RCS file: /cvs/src/sys/kern/kern_time.c,v
> retrieving revision 1.146
> diff -u -p -r1.146 kern_time.c
> --- kern/kern_time.c  13 Oct 2020 17:33:39 -  1.146
> +++ kern/kern_time.c  15 Oct 2020 01:12:50 -
> @@ -572,6 +572,16 @@ setitimer(int which, const struct itimer
>   }
>  }
>  
> +void
> +cancelitimer(int which)
> +{
> + struct itimerval itv;
> +
> + timerclear(_value);
> + timerclear(_interval);
> + setitimer(which, , NULL);
> +}
> +
>  int
>  sys_getitimer(struct proc *p, void *v, register_t *retval)
>  {
> Index: sys/time.h
> ===
> RCS file: /cvs/src/sys/sys/time.h,v
> retrieving revision 1.55
> diff -u -p -r1.55 time.h
> --- sys/time.h6 Jul 2020 13:33:09 -   1.55
> +++ sys/time.h15 Oct 2020 01:12:50 -
> @@ -307,6 +307,7 @@ time_tgetuptime(void);
>  struct proc;
>  int  clock_gettime(struct proc *, clockid_t, struct timespec *);
>  
> +void cancelitimer(int);
>  int  itimerfix(struct timeval *);
>  int  itimerdecr(struct itimerspec *, long);
>  int  settime(const struct timespec *);
> 
> 



Re: _exit(2), execve(2): cancel interval timers MP-safely

2020-10-15 Thread Todd C . Miller
On Wed, 14 Oct 2020 20:06:50 -0500, Scott Cheloha wrote:

> ... should I shove the for-loop into the helper function too?  Maybe
> call it "cancel_all_itimers()"?  I have a vague feeling that showing
> the reader that there are multiple timers is a good thing here, but
> then again maybe I'm wrong and nobody cares.

Since the consumers of this function all iterate over the array of
timers my inclination would be to push the for-loop into the helper
too.

 - todd



Re: Non-const basename: usr.bin/rcs

2020-10-15 Thread Todd C . Miller
On Wed, 14 Oct 2020 22:19:52 +0200, Christian Weisgerber wrote:

> Accommodate POSIX basename(3) that takes a non-const parameter and
> may in fact modify the string buffer.

OK millert@

 - todd



Re: Expose touchpad sensitivity in wsconsctl

2020-10-15 Thread Ulf Brosziewski
Thanks for these hints.  I will consider reducing the default threshold for
deceleration.  The current default is a compromise that is several years old,
it might well be that is not ideal for the average touchpad of today.

On 10/14/20 11:24 PM, Brennan Vincent wrote:
> People who prefer flatter profiles are not as rare as one might think, cf 
> similar discussions on Libinput:
> https://bugs.freedesktop.org/show_bug.cgi?id=89485
> 
> I found setting it to 4 gives best results (it was 16 by default) so I 
> wouldn't want to totally remove it either.
> 
> Feel free to not merge this patch if you don't want it; I will not be 
> offended. As long as I have things working how I like on my own system :)
> 
> On 10/14/20 5:16 PM, Ulf Brosziewski wrote:
>> I'm not convinced that this makes sense.  While there are still a lot of
>> touchpads around that need deceleration, modern ones tend to be larger and
>> more precise, so maybe we want to drop it at some point in the future?
>> Given that up to now, nobody else reported a problem with it, I'd prefer
>> to leave it in the set of "inofficial" configuration options.
>>
>> On 10/14/20 9:13 PM, Brennan Vincent wrote:
>>> Oops, the subject should be "Expose touchpad _decleration threshold_ in 
>>> wsconsctl". Not sure why I wrote "sensitivity".
>>>
>>> On Wed, 14 Oct 2020, Brennan Vincent wrote:
>>>
 diff --git sbin/wsconsctl/mouse.c sbin/wsconsctl/mouse.c
 index e04642dacbc..0f1594e17e0 100644
 --- sbin/wsconsctl/mouse.c
 +++ sbin/wsconsctl/mouse.c
 @@ -61,6 +61,7 @@ struct field mouse_field_tab[] = {
   { "tp.swapsides",    _swapsides,    FMT_CFG,    FLG_NORDBACK 
 },
   { "tp.disable",    _disable,    FMT_CFG,    FLG_NORDBACK },
   { "tp.edges",    _edges,    FMT_CFG,    FLG_NORDBACK },
 +    { "tp.deceleration",    _decel,    FMT_CFG,    FLG_NORDBACK },
   { "tp.param",    _param,    FMT_CFG,    FLG_WRONLY },
   /* Add an alias.  This field is valid for all wsmouse devices. */
   { "param",    _param,    FMT_CFG,    FLG_WRONLY },
 diff --git sbin/wsconsctl/mousecfg.c sbin/wsconsctl/mousecfg.c
 index 6d52bcbfc9c..6162df5c229 100644
 --- sbin/wsconsctl/mousecfg.c
 +++ sbin/wsconsctl/mousecfg.c
 @@ -109,6 +109,12 @@ struct wsmouse_parameters cfg_revscroll = {
   1
   };
   +struct wsmouse_parameters cfg_decel = {
 +    (struct wsmouse_param[]) {
 +    { WSMOUSECFG_DECELERATION, 0 }, },
 +    1
 +};
 +
   struct wsmouse_parameters cfg_param = {
   (struct wsmouse_param[]) {
   { -1, 0 },
 diff --git sbin/wsconsctl/mousecfg.h sbin/wsconsctl/mousecfg.h
 index 8e99139d280..97ef153fcb3 100644
 --- sbin/wsconsctl/mousecfg.h
 +++ sbin/wsconsctl/mousecfg.h
 @@ -22,6 +22,7 @@ extern struct wsmouse_parameters cfg_edges;
   extern struct wsmouse_parameters cfg_swapsides;
   extern struct wsmouse_parameters cfg_disable;
   extern struct wsmouse_parameters cfg_revscroll;
 +extern struct wsmouse_parameters cfg_decel;
   extern struct wsmouse_parameters cfg_param;
   extern int cfg_touchpad;
  
> 



Re: sys/kernel.h: delete dead externs

2020-10-15 Thread Jonathan Gray
On Thu, Oct 15, 2020 at 03:17:22AM -0500, Scott Cheloha wrote:
> Several of the externs in sys/kernel.h are for variables that don't
> exist.  I can't find global declarations for tickfix, tickfixinterval,
> tickdelta, or timedelta.
> 
> ok to delete these?

These went away in 'unifdef -D __HAVE_TIMECOUNTER' from miod in 2012.

ok jsg@

> 
> Index: sys/kernel.h
> ===
> RCS file: /cvs/src/sys/sys/kernel.h,v
> retrieving revision 1.23
> diff -u -p -r1.23 kernel.h
> --- sys/kernel.h  20 May 2020 17:24:17 -  1.23
> +++ sys/kernel.h  15 Oct 2020 08:09:11 -
> @@ -51,13 +51,9 @@ extern int utc_offset; /* seconds east 
>  
>  extern int tick; /* usec per tick (100 / hz) */
>  extern int tick_nsec;/* nsec per tick */
> -extern int tickfix;  /* periodic tick adj. tick not integral */
> -extern int tickfixinterval;  /* interval at which to apply adjustment */
>  extern int tickadj;  /* "standard" clock skew, us./tick */
>  extern int ticks;/* # of hardclock ticks */
>  extern int hz;   /* system clock's frequency */
>  extern int stathz;   /* statistics clock's frequency */
>  extern int profhz;   /* profiling clock's frequency */
>  extern int lbolt;/* once a second sleep address */
> -extern int tickdelta;
> -extern long timedelta;
> 
> 



sys/kernel.h: delete dead externs

2020-10-15 Thread Scott Cheloha
Several of the externs in sys/kernel.h are for variables that don't
exist.  I can't find global declarations for tickfix, tickfixinterval,
tickdelta, or timedelta.

ok to delete these?

Index: sys/kernel.h
===
RCS file: /cvs/src/sys/sys/kernel.h,v
retrieving revision 1.23
diff -u -p -r1.23 kernel.h
--- sys/kernel.h20 May 2020 17:24:17 -  1.23
+++ sys/kernel.h15 Oct 2020 08:09:11 -
@@ -51,13 +51,9 @@ extern int utc_offset;   /* seconds east 
 
 extern int tick;   /* usec per tick (100 / hz) */
 extern int tick_nsec;  /* nsec per tick */
-extern int tickfix;/* periodic tick adj. tick not integral */
-extern int tickfixinterval;/* interval at which to apply adjustment */
 extern int tickadj;/* "standard" clock skew, us./tick */
 extern int ticks;  /* # of hardclock ticks */
 extern int hz; /* system clock's frequency */
 extern int stathz; /* statistics clock's frequency */
 extern int profhz; /* profiling clock's frequency */
 extern int lbolt;  /* once a second sleep address */
-extern int tickdelta;
-extern long timedelta;



relayd and TLS client cert verification

2020-10-15 Thread Ashe Connor
Hi there,

A year or two ago I submitted a patch for adding TLS client certificate 
validation to relayd.  At the time it didn't make it in, and I stopped pursuing 
it further.  (https://marc.info/?l=openbsd-tech=154509330608643=2)

I'd still like to see this landed, if at all possible.  I'm continuing to use 
this feature on my own personal websites, and it works well.

The latest diff is attached, or can be viewed online here: 
https://github.com/openbsd/src/compare/master...kivikakk:relayd-client-verification.patch

I've added a test that confirms client failure to connect without a certificate 
at regress/usr.sbin/relayd/args-ssl-client-verify-fail.pl -- it's a bit 
awkward.  Let me know if I can redo it better.

Best,

Ashe

---

>From c63bca7ba7889b43e0a9317e807499eb8ca0db55 Mon Sep 17 00:00:00 2001
From: Asherah Connor 
Date: Thu, 15 Oct 2020 17:23:15 +1100
Subject: [PATCH] TLS client certificate validation

---
 regress/usr.sbin/relayd/Client.pm | 13 ++
 regress/usr.sbin/relayd/Makefile  | 18 -
 regress/usr.sbin/relayd/Relayd.pm |  3 +++
 .../relayd/args-ssl-client-verify-fail.pl | 25 +++
 .../usr.sbin/relayd/args-ssl-client-verify.pl | 19 ++
 usr.sbin/relayd/config.c  | 21 
 usr.sbin/relayd/parse.y   | 15 ++-
 usr.sbin/relayd/relay.c   | 21 
 usr.sbin/relayd/relayd.c  |  9 +++
 usr.sbin/relayd/relayd.conf.5 |  4 +++
 usr.sbin/relayd/relayd.h  | 14 +++
 11 files changed, 155 insertions(+), 7 deletions(-)
 create mode 100644 regress/usr.sbin/relayd/args-ssl-client-verify-fail.pl
 create mode 100644 regress/usr.sbin/relayd/args-ssl-client-verify.pl

diff --git a/regress/usr.sbin/relayd/Client.pm 
b/regress/usr.sbin/relayd/Client.pm
index b3e011de13d..ec6fa64274e 100644
--- a/regress/usr.sbin/relayd/Client.pm
+++ b/regress/usr.sbin/relayd/Client.pm
@@ -57,6 +57,11 @@ sub child {
PeerAddr=> $self->{connectaddr},
PeerPort=> $self->{connectport},
SSL_verify_mode => SSL_VERIFY_NONE,
+   SSL_use_cert=> $self->{offertlscert} ? 1 : 0,
+   SSL_cert_file   => $self->{offertlscert} ?
+  "client.crt" : "",
+   SSL_key_file=> $self->{offertlscert} ?
+  "client.key" : "",
) or die ref($self), " $iosocket socket connect failed: $!,$SSL_ERROR";
if ($self->{sndbuf}) {
setsockopt($cs, SOL_SOCKET, SO_SNDBUF,
@@ -86,6 +91,14 @@ sub child {
print STDERR "ssl cipher: ",$cs->get_cipher(),"\n";
print STDERR "ssl peer certificate:\n",
$cs->dump_peer_certificate();
+
+   if ($self->{offertlscert}) {
+   print STDERR "ssl client certificate:\n";
+   print STDERR "Subject Name: ",
+   "${\$cs->sock_certificate('subject')}\n";
+   print STDERR "Issuer  Name: ",
+   "${\$cs->sock_certificate('issuer')}\n";
+   }
}
 
*STDIN = *STDOUT = $self->{cs} = $cs;
diff --git a/regress/usr.sbin/relayd/Makefile b/regress/usr.sbin/relayd/Makefile
index cd01aa3fb63..f2198f43cc9 100644
--- a/regress/usr.sbin/relayd/Makefile
+++ b/regress/usr.sbin/relayd/Makefile
@@ -96,7 +96,23 @@ server.req:
 server.crt: ca.crt server.req
openssl x509 -CAcreateserial -CAkey ca.key -CA ca.crt -req -in 
server.req -out server.crt
 
-${REGRESS_TARGETS:M*ssl*} ${REGRESS_TARGETS:M*https*}: server.crt
+client-ca.crt:
+   openssl req -batch -new \
+   -subj /L=OpenBSD/O=relayd-regress/OU=client-ca/CN=root/ \
+   -nodes -newkey rsa -keyout client-ca.key -x509 \
+   -out client-ca.crt
+
+client.req:
+   openssl req -batch -new \
+   -subj /L=OpenBSD/O=relayd-regress/OU=client/CN=localhost/ \
+   -nodes -newkey rsa -keyout client.key \
+   -out client.req
+
+client.crt: client-ca.crt client.req
+   openssl x509 -CAcreateserial -CAkey client-ca.key -CA client-ca.crt \
+   -req -in client.req -out client.crt
+
+${REGRESS_TARGETS:M*ssl*} ${REGRESS_TARGETS:M*https*}: server.crt client.crt
 .if empty (REMOTE_SSH)
 ${REGRESS_TARGETS:M*ssl*} ${REGRESS_TARGETS:M*https*}: 127.0.0.1.crt
 .else
diff --git a/regress/usr.sbin/relayd/Relayd.pm 
b/regress/usr.sbin/relayd/Relayd.pm
index 98f2ada5db9..896c0b401be 100644
--- a/regress/usr.sbin/relayd/Relayd.pm
+++ b/regress/usr.sbin/relayd/Relayd.pm
@@ -84,6 +84,9 @@ sub new {
print $fh "\n\ttls ca cert ca.crt";
print $fh "\n\ttls ca key ca.key password ''";
}
+   if ($self->{verifyclient}) {
+   print $fh "\n\ttls