it to make it more generally usable and testable.
ok markus@
-/* $OpenBSD: auth2-hostbased.c,v 1.43 2020/10/18 11:32:01 djm Exp $ */
+/* $OpenBSD: auth2-hostbased.c,v 1.44 2021/01/26 00:49:30 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
debug2_f("access allowed by auth_rhosts2");
if (sshkey_is_cert(key) &&
- sshkey_cert_check_authority(key, 1, 0, lookup, &reason)) {
+ sshkey_cert_check_authority(key, 1, 0, 0, lookup, &reason)) {
error("%s", reason);
auth_debug_add("%s", reason);
return 0;
-/* $OpenBSD: auth2-pubkey.c,v 1.104 2021/01/22 02:44:58 dtucker Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.105 2021/01/26 00:49:30 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
reason = "Certificate does not contain an authorized principal";
goto fail_reason;
}
- if (sshkey_cert_check_authority(key, 0, 0,
+ if (sshkey_cert_check_authority(key, 0, 0, 0,
keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0)
goto fail_reason;
}
if (use_authorized_principals && principals_opts == NULL)
fatal_f("internal error: missing principals_opts");
- if (sshkey_cert_check_authority(key, 0, 1,
+ if (sshkey_cert_check_authority(key, 0, 1, 0,
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
goto fail_reason;
-/* $OpenBSD: hostfile.c,v 1.87 2020/12/20 23:36:51 djm Exp $ */
+/* $OpenBSD: hostfile.c,v 1.88 2021/01/26 00:49:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "ssherr.h"
#include "digest.h"
#include "hmac.h"
+#include "sshbuf.h"
struct hostkeys {
struct hostkey_entry *entries;
-/* $OpenBSD: sshconnect.c,v 1.349 2020/12/22 00:15:23 djm Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.350 2021/01/26 00:49:30 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
}
}
-static int
-check_host_cert(const char *host, const struct sshkey *key)
-{
- const char *reason;
- int r;
-
- if (sshkey_cert_check_authority(key, 1, 0, host, &reason) != 0) {
- error("%s", reason);
- return 0;
- }
- if (sshbuf_len(key->cert->critical) != 0) {
- error("Certificate for %s contains unsupported "
- "critical options(s)", host);
- return 0;
- }
- if ((r = sshkey_check_cert_sigtype(key,
- options.ca_sign_algorithms)) != 0) {
- logit_fr(r, "certificate signature algorithm %s",
- (key->cert == NULL || key->cert->signature_type == NULL) ?
- "(null)" : key->cert->signature_type);
- return 0;
- }
- /* Do not attempt hostkey update if a certificate was successful */
- if (options.update_hostkeys != 0) {
- options.update_hostkeys = 0;
- debug3_f("certificate host key in use; disabling UpdateHostkeys");
- }
- return 1;
-}
-
static int
sockaddr_is_local(struct sockaddr *hostaddr)
{
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp, *ra;
char msg[1024];
- const char *type;
+ const char *type, *fail_reason;
const struct hostkey_entry *host_found = NULL, *ip_found = NULL;
int len, cancelled_forwarding = 0, confirmed;
int local = sockaddr_is_local(hostaddr);
host, type, want_cert ? "certificate" : "key");
debug("Found %s in %s:%lu", want_cert ? "CA key" : "key",
host_found->file, host_found->line);
- if (want_cert &&
- !check_host_cert(options.host_key_alias == NULL ?
- hostname : options.host_key_alias, host_key))
- goto fail;
+ if (want_cert) {
+ if (sshkey_cert_check_host(host_key,
+ options.host_key_alias == NULL ?
+ hostname : options.host_key_alias, 0,
+ options.ca_sign_algorithms, &fail_reason) != 0) {
+ error("%s", fail_reason);
+ goto fail;
+ }
+ /*
+ * Do not attempt hostkey update if a certificate was
+ * successfully matched.
+ */
+ if (options.update_hostkeys != 0) {
+ options.update_hostkeys = 0;
+ debug3_f("certificate host key in use; "
+ "disabling UpdateHostkeys");
+ }
+ }
/* Turn off UpdateHostkeys if key was in system known_hosts */
if (options.update_hostkeys != 0 &&
(path_in_hostfiles(host_found->file,
-/* $OpenBSD: sshkey.c,v 1.113 2021/01/15 04:31:25 dtucker Exp $ */
+/* $OpenBSD: sshkey.c,v 1.114 2021/01/26 00:49:30 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
int
sshkey_cert_check_authority(const struct sshkey *k,
- int want_host, int require_principal,
+ int want_host, int require_principal, int wildcard_pattern,
const char *name, const char **reason)
{
u_int i, principal_matches;
if (reason == NULL)
return SSH_ERR_INVALID_ARGUMENT;
-
+ if (!sshkey_is_cert(k)) {
+ *reason = "Key is not a certificate";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
if (want_host) {
if (k->cert->type != SSH2_CERT_TYPE_HOST) {
*reason = "Certificate invalid: not a host certificate";
} else if (name != NULL) {
principal_matches = 0;
for (i = 0; i < k->cert->nprincipals; i++) {
- if (strcmp(name, k->cert->principals[i]) == 0) {
+ if (wildcard_pattern) {
+ if (match_pattern(k->cert->principals[i],
+ name)) {
+ principal_matches = 1;
+ break;
+ }
+ } else if (strcmp(name, k->cert->principals[i]) == 0) {
principal_matches = 1;
break;
}
return 0;
}
+int
+sshkey_cert_check_host(const struct sshkey *key, const char *host,
+ int wildcard_principals, const char *ca_sign_algorithms,
+ const char **reason)
+{
+ int r;
+
+ if ((r = sshkey_cert_check_authority(key, 1, 0, wildcard_principals,
+ host, reason)) != 0)
+ return r;
+ if (sshbuf_len(key->cert->critical) != 0) {
+ *reason = "Certificate contains unsupported critical options";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
+ if (ca_sign_algorithms != NULL &&
+ (r = sshkey_check_cert_sigtype(key, ca_sign_algorithms)) != 0) {
+ *reason = "Certificate signed with disallowed algorithm";
+ return SSH_ERR_KEY_CERT_INVALID;
+ }
+ return 0;
+}
+
size_t
sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)
{
-/* $OpenBSD: sshkey.h,v 1.48 2020/11/08 11:46:12 dtucker Exp $ */
+/* $OpenBSD: sshkey.h,v 1.49 2021/01/26 00:49:30 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
int sshkey_to_certified(struct sshkey *);
int sshkey_drop_cert(struct sshkey *);
int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
-int sshkey_cert_check_authority(const struct sshkey *, int, int,
+int sshkey_cert_check_authority(const struct sshkey *, int, int, int,
const char *, const char **);
+int sshkey_cert_check_host(const struct sshkey *, const char *,
+ int , const char *, const char **);
size_t sshkey_format_cert_validity(const struct sshkey_cert *,
char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
int sshkey_check_cert_sigtype(const struct sshkey *, const char *);
-/* $OpenBSD: sshsig.c,v 1.18 2020/10/18 11:32:02 djm Exp $ */
+/* $OpenBSD: sshsig.c,v 1.19 2021/01/26 00:49:30 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
} else if (sigopts->ca && sshkey_is_cert(sign_key) &&
sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
/* Match of certificate's CA key */
- if ((r = sshkey_cert_check_authority(sign_key, 0, 1,
+ if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0,
principal, &reason)) != 0) {
error("%s:%lu: certificate not authorized: %s",
path, linenum, reason);
continue;
}
/* Check against principals list in certificate */
- if ((r = sshkey_cert_check_authority(cert, 0, 1,
+ if ((r = sshkey_cert_check_authority(cert, 0, 1, 0,
cp, &reason)) != 0) {
debug("%s:%lu: principal \"%s\" not authorized: %s",
path, linenum, cp, reason);