Bugzilla – Attachment 2690 Details for
Bug 2377
Add ssh-agent support to ssh-keygen
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
add support for ssh agent to sign certificates
0001-ssh-keygen-Add-ssh-agent-support-for-generating-cert.patch (text/plain), 8.15 KB, created by
Meghana Bhat
on 2015-08-29 06:42:46 AEST
(
hide
)
Description:
add support for ssh agent to sign certificates
Filename:
MIME Type:
Creator:
Meghana Bhat
Created:
2015-08-29 06:42:46 AEST
Size:
8.15 KB
patch
obsolete
>From 915a8d850b6d68bd0749b0544caf9af4a283c93d Mon Sep 17 00:00:00 2001 >From: Meghana Bhat <mebhat@akamai.com> >Date: Fri, 28 Aug 2015 16:19:05 -0400 >Subject: [PATCH] ssh-keygen: Add ssh agent support for generating certificates > >Communicate with the ssh agent to sign certificates if agent is present >and is loaded with the specified certificate authority. >In order for the agent to sign, the certificate authority public key >must be alongside the private key with the same file name but a .pub >extension. >This patch addresses the bug at: >https://bugzilla.mindrot.org/show_bug.cgi?id=2377 >Patch developed against 7.1p. >--- > authfd.c | 2 +- > authfd.h | 1 + > ssh-keygen.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- > sshkey.c | 36 +++++++++++++++----- > sshkey.h | 1 + > 5 files changed, 126 insertions(+), 23 deletions(-) > >diff --git a/authfd.c b/authfd.c >index eaa1426..f7933fc 100644 >--- a/authfd.c >+++ b/authfd.c >@@ -121,7 +121,7 @@ ssh_get_authentication_socket(int *fdp) > } > > /* Communicate with agent: send request and read reply */ >-static int >+int > ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) > { > int r; >diff --git a/authfd.h b/authfd.h >index bea20c2..f58af43 100644 >--- a/authfd.h >+++ b/authfd.h >@@ -42,6 +42,7 @@ int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, > int ssh_agent_sign(int sock, struct sshkey *key, > u_char **sigp, size_t *lenp, > const u_char *data, size_t datalen, u_int compat); >+int ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply); > > /* Messages for the authentication agent connection. */ > #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 >diff --git a/ssh-keygen.c b/ssh-keygen.c >index 4e0a855..168d6c0 100644 >--- a/ssh-keygen.c >+++ b/ssh-keygen.c >@@ -57,6 +57,7 @@ > #include "atomicio.h" > #include "krl.h" > #include "digest.h" >+#include "authfd.h" > > #ifdef WITH_OPENSSL > # define DEFAULT_KEY_TYPE_NAME "rsa" >@@ -1566,25 +1567,92 @@ load_pkcs11_key(char *path) > #endif /* ENABLE_PKCS11 */ > } > >+static int >+do_agent_sign(int agent_fd, struct sshkey *k, struct sshkey *ca_pk, >+ u_char *ca_blob, size_t ca_len) >+{ >+ u_char type; >+ u_char *sig; >+ size_t slen; >+ struct sshbuf *msg, *cert_blob; >+ u_int flags = 0; >+ int ret = 0, r = 0; >+ >+ cert_blob = k->cert->certblob; /* for readability */ >+ if ((msg = sshbuf_new()) == NULL) >+ fatal("%s: sshbuf_new failed", __func__); >+ if ((r = sshkey_cert_prepare_sign(k, ca_pk)) != 0) { >+ ret = -1; >+ } >+ >+ if (ret == 0) { >+ if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || >+ (r = sshbuf_put_string(msg, ca_blob, ca_len)) != 0 || >+ (r = sshbuf_put_string(msg, sshbuf_ptr(cert_blob), >+ sshbuf_len(cert_blob))) != 0 || >+ (r = sshbuf_put_u32(msg, flags)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ if ((r = ssh_request_reply(agent_fd, msg, msg)) != 0) >+ ret = -1; >+ else if ((r = sshbuf_get_u8(msg, &type)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ else if ((type == SSH_AGENT_FAILURE) || >+ (type == SSH2_AGENT_FAILURE)) >+ ret = -1; >+ else if ((r = sshbuf_get_string(msg, &sig, &slen)) != 0 || >+ (r = sshbuf_put_string(cert_blob, sig, slen)) != 0) >+ fatal("%s: buffer error: %s", __func__, ssh_err(r)); >+ else >+ free(sig); >+ } >+ >+ sshbuf_free(msg); >+ return ret; >+} >+ > static void > do_ca_sign(struct passwd *pw, int argc, char **argv) > { >- int r, i, fd; >+ int r, i, fd, agent_fd; > u_int n; >- struct sshkey *ca, *public; >+ struct sshkey *ca, *ca_pk, *public; > char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; > FILE *f; >+ u_char *ca_blob; >+ size_t ca_len; >+ /* flag indicating whether to try the ssh-agent to sign certificates */ >+ int try_agent = 0; > > #ifdef ENABLE_PKCS11 > pkcs11_init(1); > #endif >+ >+ /* load pubkey of CA first (ca_blob), if it works, try getting agent socket */ > tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); >- if (pkcs11provider != NULL) { >- if ((ca = load_pkcs11_key(tmp)) == NULL) >- fatal("No PKCS#11 key matching %s found", ca_key_path); >- } else >- ca = load_identity(tmp); >- free(tmp); >+ if ((r = sshkey_load_public(tmp, &ca_pk, NULL)) == 0 && >+ (r = sshkey_to_blob(ca_pk, &ca_blob, &ca_len)) == 0) { >+ switch (r = ssh_get_authentication_socket(&agent_fd)) { >+ case SSH_ERR_SUCCESS: >+ try_agent = 1; >+ ca = NULL; >+ break; >+ case SSH_ERR_AGENT_NOT_PRESENT: >+ debug("Couldn't open connection to agent"); >+ break; >+ default: >+ debug("Error connecting to agent"); >+ break; >+ } >+ } >+ >+ if (!try_agent) { >+ if (pkcs11provider != NULL) { >+ if ((ca = load_pkcs11_key(tmp)) == NULL) >+ fatal("No PKCS#11 key matching %s found", ca_key_path); >+ } else >+ ca = load_identity(tmp); >+ free(tmp); >+ } > > for (i = 0; i < argc; i++) { > /* Split list of principals */ >@@ -1623,13 +1691,28 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) > prepare_options_buf(public->cert->critical, OPTIONS_CRITICAL); > prepare_options_buf(public->cert->extensions, > OPTIONS_EXTENSIONS); >- if ((r = sshkey_from_private(ca, >- &public->cert->signature_key)) != 0) >- fatal("key_from_private (ca key): %s", ssh_err(r)); > >- if (sshkey_certify(public, ca) != 0) >- fatal("Couldn't not certify key %s", tmp); >+ if (try_agent && >+ (r = do_agent_sign(agent_fd, public, ca_pk, ca_blob, ca_len)) != 0) { >+ try_agent = 0; >+ otmp = tilde_expand_filename(ca_key_path, pw->pw_uid); >+ if (pkcs11provider != NULL) { >+ if ((ca = load_pkcs11_key(otmp)) == NULL) >+ fatal("No PKCS#11 key matching %s found", ca_key_path); >+ } else >+ ca = load_identity(otmp); >+ free(otmp); >+ } > >+ if (!try_agent) { >+ if ((r = sshkey_from_private(ca, >+ &public->cert->signature_key)) != 0) >+ fatal("key_from_private (ca key): %s", ssh_err(r)); >+ >+ if (sshkey_certify(public, ca) != 0) >+ fatal("Couldn't not certify key %s", tmp); >+ } >+ > if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) > *cp = '\0'; > xasprintf(&out, "%s-cert.pub", tmp); >diff --git a/sshkey.c b/sshkey.c >index 32dd8f2..bded18a 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -2370,13 +2370,12 @@ sshkey_drop_cert(struct sshkey *k) > return 0; > } > >-/* Sign a certified key, (re-)generating the signed certblob. */ >+/* Prepare a certificate blob for CA signing. */ > int >-sshkey_certify(struct sshkey *k, struct sshkey *ca) >-{ >+sshkey_cert_prepare_sign(struct sshkey *k, struct sshkey *ca) { > struct sshbuf *principals = NULL; >- u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; >- size_t i, ca_len, sig_len; >+ u_char *ca_blob = NULL, nonce[32]; >+ size_t i, ca_len; > int ret = SSH_ERR_INTERNAL_ERROR; > struct sshbuf *cert; > >@@ -2459,7 +2458,30 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca) > (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */ > (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0) > goto out; >+ ret = 0; >+ out: >+ if (ret != 0) >+ sshbuf_reset(cert); >+ if (ca_blob != NULL) >+ free(ca_blob); >+ if (principals != NULL) >+ sshbuf_free(principals); >+ return ret; >+} > >+/* Sign a certified key, (re-)generating the signed certblob. */ >+int >+sshkey_certify(struct sshkey *k, struct sshkey *ca) >+{ >+ u_char *sig_blob = NULL; >+ size_t sig_len; >+ int ret = SSH_ERR_INTERNAL_ERROR; >+ struct sshbuf *cert; >+ >+ cert = k->cert->certblob; /* for readability */ >+ if ((ret = sshkey_cert_prepare_sign(k, ca)) != 0) >+ goto out; >+ > /* Sign the whole mess */ > if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), > sshbuf_len(cert), 0)) != 0) >@@ -2474,10 +2496,6 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca) > sshbuf_reset(cert); > if (sig_blob != NULL) > free(sig_blob); >- if (ca_blob != NULL) >- free(ca_blob); >- if (principals != NULL) >- sshbuf_free(principals); > return ret; > } > >diff --git a/sshkey.h b/sshkey.h >index c8d3cdd..0a62563 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -137,6 +137,7 @@ int sshkey_type_is_cert(int); > int sshkey_type_plain(int); > int sshkey_to_certified(struct sshkey *); > int sshkey_drop_cert(struct sshkey *); >+int sshkey_cert_prepare_sign(struct sshkey *, struct sshkey *); > int sshkey_certify(struct sshkey *, struct sshkey *); > int sshkey_cert_copy(const struct sshkey *, struct sshkey *); > int sshkey_cert_check_authority(const struct sshkey *, int, int, >-- >2.3.2 (Apple Git-55) >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2377
:
2690
|
2692
|
2887
|
2983