diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2011-08-21 13:42:49 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-08-21 13:42:49 +0200 |
commit | af82d8dfabc73fdf6477c2da521f2ba23deb2ca5 (patch) | |
tree | 43d79385166748d6d10177ddf4a5693ce5a37526 | |
parent | a98301d2b09be81e4299e1d5b1adaf25ecdb59fe (diff) | |
download | libssh-af82d8dfabc73fdf6477c2da521f2ba23deb2ca5.tar.gz libssh-af82d8dfabc73fdf6477c2da521f2ba23deb2ca5.tar.xz libssh-af82d8dfabc73fdf6477c2da521f2ba23deb2ca5.zip |
agent: Add ssh_agent_sign_data().
-rw-r--r-- | include/libssh/agent.h | 3 | ||||
-rw-r--r-- | src/agent.c | 90 |
2 files changed, 92 insertions, 1 deletions
diff --git a/include/libssh/agent.h b/include/libssh/agent.h index b620b33..2a0f229 100644 --- a/include/libssh/agent.h +++ b/include/libssh/agent.h @@ -91,6 +91,9 @@ struct ssh_public_key_struct *agent_get_first_ident(struct ssh_session_struct *s ssh_string agent_sign_data(struct ssh_session_struct *session, struct ssh_buffer_struct *data, struct ssh_public_key_struct *pubkey); +ssh_string ssh_agent_sign_data(ssh_session session, + const ssh_key pubkey, + struct ssh_buffer_struct *data); #endif #endif /* __AGENT_H */ diff --git a/src/agent.c b/src/agent.c index 9ab5175..2f03ce5 100644 --- a/src/agent.c +++ b/src/agent.c @@ -502,6 +502,94 @@ int agent_is_running(ssh_session session) { return 0; } +ssh_string ssh_agent_sign_data(ssh_session session, + const ssh_key pubkey, + struct ssh_buffer_struct *data) +{ + ssh_buffer request; + ssh_buffer reply; + ssh_string key_blob; + ssh_string sig_blob; + int type = SSH2_AGENT_FAILURE; + int flags = 0; + uint32_t dlen; + int rc; + + request = ssh_buffer_new(); + if (request == NULL) { + return NULL; + } + + /* create request */ + if (buffer_add_u8(request, SSH2_AGENTC_SIGN_REQUEST) < 0) { + return NULL; + } + + key_blob = ssh_pki_export_pubkey_blob(pubkey); + if (key_blob == NULL) { + ssh_buffer_free(request); + return NULL; + } + + /* adds len + blob */ + rc = buffer_add_ssh_string(request, key_blob); + ssh_string_free(key_blob); + if (rc < 0) { + ssh_buffer_free(request); + return NULL; + } + + /* Add data */ + dlen = buffer_get_rest_len(data); + if (buffer_add_u32(request, htonl(dlen)) < 0) { + ssh_buffer_free(request); + return NULL; + } + if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) { + ssh_buffer_free(request); + return NULL; + } + + if (buffer_add_u32(request, htonl(flags)) < 0) { + ssh_buffer_free(request); + return NULL; + } + + reply = ssh_buffer_new(); + if (reply == NULL) { + ssh_buffer_free(request); + return NULL; + } + + /* send the request */ + if (agent_talk(session, request, reply) < 0) { + ssh_buffer_free(request); + return NULL; + } + ssh_buffer_free(request); + + /* check if reply is valid */ + if (buffer_get_u8(reply, (uint8_t *) &type) != sizeof(uint8_t)) { + ssh_buffer_free(reply); + return NULL; + } + + if (agent_failed(type)) { + ssh_log(session, SSH_LOG_RARE, "Agent reports failure in signing the key"); + ssh_buffer_free(reply); + return NULL; + } else if (type != SSH2_AGENT_SIGN_RESPONSE) { + ssh_set_error(session, SSH_FATAL, "Bad authentication response: %d", type); + ssh_buffer_free(reply); + return NULL; + } + + sig_blob = buffer_get_ssh_string(reply); + ssh_buffer_free(reply); + + return sig_blob; +} + #endif /* _WIN32 */ -/* vim: set ts=2 sw=2 et cindent: */ +/* vim: set ts=4 sw=4 et cindent: */ |