summaryrefslogtreecommitdiff
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2021-01-26 00:49:30 +0000
committerDamien Miller <djm@mindrot.org>2021-01-26 12:21:48 +1100
commit3b44f2513cae89c920e8fe927b9bc910a1c8c65a (patch)
treec67b9a8583b9795bec5a5dd56f7a8556c8da2d5e /sshkey.c
parent1fe16fd61bb53944ec510882acc0491abd66ff76 (diff)
downloadopenssh-git-3b44f2513cae89c920e8fe927b9bc910a1c8c65a.tar.gz
upstream: move check_host_cert() from sshconnect,c to sshkey.c and
refactor it to make it more generally usable and testable. ok markus@ OpenBSD-Commit-ID: 536f489f5ff38808c1fa711ba58d4579b636f9e4
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/sshkey.c b/sshkey.c
index d195a593..24d8ec20 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $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.
@@ -3076,7 +3076,7 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg,
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;
@@ -3084,7 +3084,10 @@ sshkey_cert_check_authority(const struct sshkey *k,
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";
@@ -3117,7 +3120,13 @@ sshkey_cert_check_authority(const struct sshkey *k,
} 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;
}
@@ -3131,6 +3140,28 @@ sshkey_cert_check_authority(const struct sshkey *k,
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)
{