version 1.415, 2020/08/03 02:53:51 |
version 1.416, 2020/08/27 01:06:18 |
|
|
|
|
/* try the key */ |
/* try the key */ |
if (sshkey_sign(key, &sig, &slen, data, sizeof(data), |
if (sshkey_sign(key, &sig, &slen, data, sizeof(data), |
NULL, NULL, 0) != 0 || |
NULL, NULL, NULL, 0) != 0 || |
sshkey_verify(key, sig, slen, data, sizeof(data), |
sshkey_verify(key, sig, slen, data, sizeof(data), |
NULL, 0, NULL) != 0) { |
NULL, 0, NULL) != 0) { |
sshkey_free(key); |
sshkey_free(key); |
|
|
static int |
static int |
agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, |
agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, |
const u_char *data, size_t datalen, |
const u_char *data, size_t datalen, |
const char *alg, const char *provider, u_int compat, void *ctx) |
const char *alg, const char *provider, const char *pin, |
|
u_int compat, void *ctx) |
{ |
{ |
int *agent_fdp = (int *)ctx; |
int *agent_fdp = (int *)ctx; |
|
|
|
|
u_int n; |
u_int n; |
struct sshkey *ca, *public; |
struct sshkey *ca, *public; |
char valid[64], *otmp, *tmp, *cp, *out, *comment; |
char valid[64], *otmp, *tmp, *cp, *out, *comment; |
char *ca_fp = NULL, **plist = NULL; |
char *ca_fp = NULL, **plist = NULL, *pin = NULL; |
struct ssh_identitylist *agent_ids; |
struct ssh_identitylist *agent_ids; |
size_t j; |
size_t j; |
struct notifier_ctx *notifier = NULL; |
struct notifier_ctx *notifier = NULL; |
|
|
} else { |
} else { |
/* CA key is assumed to be a private key on the filesystem */ |
/* CA key is assumed to be a private key on the filesystem */ |
ca = load_identity(tmp, NULL); |
ca = load_identity(tmp, NULL); |
|
if (sshkey_is_sk(ca) && |
|
(ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) { |
|
if ((pin = read_passphrase("Enter PIN for CA key: ", |
|
RP_ALLOW_STDIN)) == NULL) |
|
fatal("%s: couldn't read PIN", __func__); |
|
} |
} |
} |
free(tmp); |
free(tmp); |
|
|
|
|
|
|
if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { |
if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { |
if ((r = sshkey_certify_custom(public, ca, |
if ((r = sshkey_certify_custom(public, ca, |
key_type_name, sk_provider, agent_signer, |
key_type_name, sk_provider, NULL, agent_signer, |
&agent_fd)) != 0) |
&agent_fd)) != 0) |
fatal("Couldn't certify key %s via agent: %s", |
fatal("Couldn't certify key %s via agent: %s", |
tmp, ssh_err(r)); |
tmp, ssh_err(r)); |
|
|
sshkey_type(ca), ca_fp); |
sshkey_type(ca), ca_fp); |
} |
} |
r = sshkey_certify(public, ca, key_type_name, |
r = sshkey_certify(public, ca, key_type_name, |
sk_provider); |
sk_provider, pin); |
notify_complete(notifier); |
notify_complete(notifier); |
if (r != 0) |
if (r != 0) |
fatal("Couldn't certify key %s: %s", |
fatal("Couldn't certify key %s: %s", |
|
|
if (cert_serial_autoinc) |
if (cert_serial_autoinc) |
cert_serial++; |
cert_serial++; |
} |
} |
|
if (pin != NULL) |
|
freezero(pin, strlen(pin)); |
free(ca_fp); |
free(ca_fp); |
#ifdef ENABLE_PKCS11 |
#ifdef ENABLE_PKCS11 |
pkcs11_terminate(); |
pkcs11_terminate(); |
|
|
struct sshbuf *sigbuf = NULL, *abuf = NULL; |
struct sshbuf *sigbuf = NULL, *abuf = NULL; |
int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno; |
int r = SSH_ERR_INTERNAL_ERROR, wfd = -1, oerrno; |
char *wfile = NULL, *asig = NULL, *fp = NULL; |
char *wfile = NULL, *asig = NULL, *fp = NULL; |
|
char *pin = NULL, *prompt = NULL; |
|
|
if (!quiet) { |
if (!quiet) { |
if (fd == STDIN_FILENO) |
if (fd == STDIN_FILENO) |
|
|
else |
else |
fprintf(stderr, "Signing file %s\n", filename); |
fprintf(stderr, "Signing file %s\n", filename); |
} |
} |
if (signer == NULL && sshkey_is_sk(signkey) && |
if (signer == NULL && sshkey_is_sk(signkey)) { |
(signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { |
if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) { |
if ((fp = sshkey_fingerprint(signkey, fingerprint_hash, |
xasprintf(&prompt, "Enter PIN for %s key: ", |
SSH_FP_DEFAULT)) == NULL) |
sshkey_type(signkey)); |
fatal("%s: sshkey_fingerprint failed", __func__); |
if ((pin = read_passphrase(prompt, |
fprintf(stderr, "Confirm user presence for key %s %s\n", |
RP_ALLOW_STDIN)) == NULL) |
sshkey_type(signkey), fp); |
fatal("%s: couldn't read PIN", __func__); |
free(fp); |
} |
|
if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { |
|
if ((fp = sshkey_fingerprint(signkey, fingerprint_hash, |
|
SSH_FP_DEFAULT)) == NULL) |
|
fatal("%s: fingerprint failed", __func__); |
|
fprintf(stderr, "Confirm user presence for key %s %s\n", |
|
sshkey_type(signkey), fp); |
|
free(fp); |
|
} |
} |
} |
if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, fd, sig_namespace, |
if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, pin, |
&sigbuf, signer, signer_ctx)) != 0) { |
fd, sig_namespace, &sigbuf, signer, signer_ctx)) != 0) { |
error("Signing %s failed: %s", filename, ssh_err(r)); |
error("Signing %s failed: %s", filename, ssh_err(r)); |
goto out; |
goto out; |
} |
} |
|
|
r = 0; |
r = 0; |
out: |
out: |
free(wfile); |
free(wfile); |
|
free(prompt); |
free(asig); |
free(asig); |
|
if (pin != NULL) |
|
freezero(pin, strlen(pin)); |
sshbuf_free(abuf); |
sshbuf_free(abuf); |
sshbuf_free(sigbuf); |
sshbuf_free(sigbuf); |
if (wfd != -1) |
if (wfd != -1) |
|
|
for (i = 0; i < nopts; i++) { |
for (i = 0; i < nopts; i++) { |
if (strcasecmp(opts[i], "no-touch-required") == 0) { |
if (strcasecmp(opts[i], "no-touch-required") == 0) { |
sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; |
sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; |
|
} else if (strcasecmp(opts[i], "verify-required") == 0) { |
|
sk_flags |= SSH_SK_USER_VERIFICATION_REQD; |
} else if (strcasecmp(opts[i], "resident") == 0) { |
} else if (strcasecmp(opts[i], "resident") == 0) { |
sk_flags |= SSH_SK_RESIDENT_KEY; |
sk_flags |= SSH_SK_RESIDENT_KEY; |
} else if (strncasecmp(opts[i], "device=", 7) == 0) { |
} else if (strncasecmp(opts[i], "device=", 7) == 0) { |