version 1.308, 2019/08/05 11:50:33 |
version 1.309, 2019/10/31 21:18:28 |
|
|
#include "hostfile.h" |
#include "hostfile.h" |
#include "ssherr.h" |
#include "ssherr.h" |
#include "utf8.h" |
#include "utf8.h" |
|
#include "ssh-sk.h" |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
#include "ssh-gss.h" |
#include "ssh-gss.h" |
|
|
format_identity(Identity *id) |
format_identity(Identity *id) |
{ |
{ |
char *fp = NULL, *ret = NULL; |
char *fp = NULL, *ret = NULL; |
|
const char *note = ""; |
|
|
if (id->key != NULL) { |
if (id->key != NULL) { |
fp = sshkey_fingerprint(id->key, options.fingerprint_hash, |
fp = sshkey_fingerprint(id->key, options.fingerprint_hash, |
SSH_FP_DEFAULT); |
SSH_FP_DEFAULT); |
} |
} |
|
if (id->key) { |
|
if ((id->key->flags & SSHKEY_FLAG_EXT) != 0) |
|
note = " token"; |
|
else if (sshkey_type_plain(id->key->type) == KEY_ECDSA_SK) |
|
note = " security-key"; |
|
} |
xasprintf(&ret, "%s %s%s%s%s%s%s", |
xasprintf(&ret, "%s %s%s%s%s%s%s", |
id->filename, |
id->filename, |
id->key ? sshkey_type(id->key) : "", id->key ? " " : "", |
id->key ? sshkey_type(id->key) : "", id->key ? " " : "", |
fp ? fp : "", |
fp ? fp : "", |
id->userprovided ? " explicit" : "", |
id->userprovided ? " explicit" : "", note, |
(id->key && (id->key->flags & SSHKEY_FLAG_EXT)) ? " token" : "", |
|
id->agent_fd != -1 ? " agent" : ""); |
id->agent_fd != -1 ? " agent" : ""); |
free(fp); |
free(fp); |
return ret; |
return ret; |
|
|
identity_sign(struct identity *id, u_char **sigp, size_t *lenp, |
identity_sign(struct identity *id, u_char **sigp, size_t *lenp, |
const u_char *data, size_t datalen, u_int compat, const char *alg) |
const u_char *data, size_t datalen, u_int compat, const char *alg) |
{ |
{ |
struct sshkey *prv; |
struct sshkey *sign_key = NULL, *prv = NULL; |
int r; |
int r = SSH_ERR_INTERNAL_ERROR; |
|
|
|
*sigp = NULL; |
|
*lenp = 0; |
|
|
/* The agent supports this key. */ |
/* The agent supports this key. */ |
if (id->key != NULL && id->agent_fd != -1) { |
if (id->key != NULL && id->agent_fd != -1) { |
return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, |
return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, |
|
|
*/ |
*/ |
if (id->key != NULL && |
if (id->key != NULL && |
(id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) { |
(id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) { |
if ((r = sshkey_sign(id->key, sigp, lenp, data, datalen, |
sign_key = id->key; |
alg, compat)) != 0) |
} else { |
return r; |
/* Load the private key from the file. */ |
/* |
if ((prv = load_identity_file(id)) == NULL) |
* PKCS#11 tokens may not support all signature algorithms, |
return SSH_ERR_KEY_NOT_FOUND; |
* so check what we get back. |
if (id->key != NULL && !sshkey_equal_public(prv, id->key)) { |
*/ |
error("%s: private key %s contents do not match public", |
if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) |
__func__, id->filename); |
return r; |
r = SSH_ERR_KEY_NOT_FOUND; |
return 0; |
goto out; |
|
} |
|
sign_key = prv; |
} |
} |
|
|
/* Load the private key from the file. */ |
if (sshkey_type_plain(sign_key->type) == KEY_ECDSA_SK) { |
if ((prv = load_identity_file(id)) == NULL) |
if (options.sk_provider == NULL) { |
return SSH_ERR_KEY_NOT_FOUND; |
/* Shouldn't happen here; checked in pubkey_prepare() */ |
if (id->key != NULL && !sshkey_equal_public(prv, id->key)) { |
fatal("%s: missing SecurityKeyProvider", __func__); |
error("%s: private key %s contents do not match public", |
} |
__func__, id->filename); |
if ((r = sshsk_ecdsa_sign(options.sk_provider, sign_key, |
return SSH_ERR_KEY_NOT_FOUND; |
sigp, lenp, data, datalen, compat)) != 0) { |
|
debug("%s: sshsk_ecdsa_sign: %s", __func__, ssh_err(r)); |
|
goto out; |
|
} |
|
} else if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen, |
|
alg, compat)) != 0) { |
|
debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); |
|
goto out; |
} |
} |
r = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat); |
/* |
|
* PKCS#11 tokens may not support all signature algorithms, |
|
* so check what we get back. |
|
*/ |
|
if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) { |
|
debug("%s: sshkey_check_sigtype: %s", __func__, ssh_err(r)); |
|
goto out; |
|
} |
|
/* success */ |
|
r = 0; |
|
out: |
sshkey_free(prv); |
sshkey_free(prv); |
return r; |
return r; |
} |
} |
|
|
quit = 1; |
quit = 1; |
break; |
break; |
} |
} |
|
if (private != NULL && |
|
sshkey_type_plain(private->type) == KEY_ECDSA_SK && |
|
options.sk_provider == NULL) { |
|
debug("key \"%s\" is a security key, but no " |
|
"provider specified", id->filename); |
|
sshkey_free(private); |
|
private = NULL; |
|
quit = 1; |
|
} |
if (!quit && private != NULL && id->agent_fd == -1 && |
if (!quit && private != NULL && id->agent_fd == -1 && |
!(id->key && id->isprivate)) |
!(id->key && id->isprivate)) |
maybe_add_key_to_agent(id->filename, private, comment, |
maybe_add_key_to_agent(id->filename, private, comment, |
|
|
/* list of keys stored in the filesystem and PKCS#11 */ |
/* list of keys stored in the filesystem and PKCS#11 */ |
for (i = 0; i < options.num_identity_files; i++) { |
for (i = 0; i < options.num_identity_files; i++) { |
key = options.identity_keys[i]; |
key = options.identity_keys[i]; |
if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) |
if (key && key->cert && |
|
key->cert->type != SSH2_CERT_TYPE_USER) { |
|
debug("%s: ignoring certificate %s: not a user " |
|
"certificate", __func__, |
|
options.identity_files[i]); |
continue; |
continue; |
|
} |
|
if (key && sshkey_type_plain(key->type) == KEY_ECDSA_SK && |
|
options.sk_provider == NULL) { |
|
debug("%s: ignoring security key %s as no " |
|
"SecurityKeyProvider has been specified", |
|
__func__, options.identity_files[i]); |
|
continue; |
|
} |
options.identity_keys[i] = NULL; |
options.identity_keys[i] = NULL; |
id = xcalloc(1, sizeof(*id)); |
id = xcalloc(1, sizeof(*id)); |
id->agent_fd = -1; |
id->agent_fd = -1; |
|
|
for (i = 0; i < options.num_certificate_files; i++) { |
for (i = 0; i < options.num_certificate_files; i++) { |
key = options.certificates[i]; |
key = options.certificates[i]; |
if (!sshkey_is_cert(key) || key->cert == NULL || |
if (!sshkey_is_cert(key) || key->cert == NULL || |
key->cert->type != SSH2_CERT_TYPE_USER) |
key->cert->type != SSH2_CERT_TYPE_USER) { |
|
debug("%s: ignoring certificate %s: not a user " |
|
"certificate", __func__, |
|
options.identity_files[i]); |
continue; |
continue; |
|
} |
|
if (key && sshkey_type_plain(key->type) == KEY_ECDSA_SK && |
|
options.sk_provider == NULL) { |
|
debug("%s: ignoring security key certificate %s as no " |
|
"SecurityKeyProvider has been specified", |
|
__func__, options.identity_files[i]); |
|
continue; |
|
} |
id = xcalloc(1, sizeof(*id)); |
id = xcalloc(1, sizeof(*id)); |
id->agent_fd = -1; |
id->agent_fd = -1; |
id->key = key; |
id->key = key; |