summaryrefslogtreecommitdiff
path: root/ssh-pkcs11-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-pkcs11-client.c')
-rw-r--r--ssh-pkcs11-client.c136
1 files changed, 79 insertions, 57 deletions
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index fc7582827..028b272cb 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11-client.c,v 1.8 2018/02/05 05:37:46 tb Exp $ */ 1/* $OpenBSD: ssh-pkcs11-client.c,v 1.10 2018/07/09 21:59:10 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -34,13 +34,14 @@
34 34
35#include "pathnames.h" 35#include "pathnames.h"
36#include "xmalloc.h" 36#include "xmalloc.h"
37#include "buffer.h" 37#include "sshbuf.h"
38#include "log.h" 38#include "log.h"
39#include "misc.h" 39#include "misc.h"
40#include "key.h" 40#include "sshkey.h"
41#include "authfd.h" 41#include "authfd.h"
42#include "atomicio.h" 42#include "atomicio.h"
43#include "ssh-pkcs11.h" 43#include "ssh-pkcs11.h"
44#include "ssherr.h"
44 45
45/* borrows code from sftp-server and ssh-agent */ 46/* borrows code from sftp-server and ssh-agent */
46 47
@@ -48,34 +49,37 @@ int fd = -1;
48pid_t pid = -1; 49pid_t pid = -1;
49 50
50static void 51static void
51send_msg(Buffer *m) 52send_msg(struct sshbuf *m)
52{ 53{
53 u_char buf[4]; 54 u_char buf[4];
54 int mlen = buffer_len(m); 55 size_t mlen = sshbuf_len(m);
56 int r;
55 57
56 put_u32(buf, mlen); 58 POKE_U32(buf, mlen);
57 if (atomicio(vwrite, fd, buf, 4) != 4 || 59 if (atomicio(vwrite, fd, buf, 4) != 4 ||
58 atomicio(vwrite, fd, buffer_ptr(m), 60 atomicio(vwrite, fd, sshbuf_mutable_ptr(m),
59 buffer_len(m)) != buffer_len(m)) 61 sshbuf_len(m)) != sshbuf_len(m))
60 error("write to helper failed"); 62 error("write to helper failed");
61 buffer_consume(m, mlen); 63 if ((r = sshbuf_consume(m, mlen)) != 0)
64 fatal("%s: buffer error: %s", __func__, ssh_err(r));
62} 65}
63 66
64static int 67static int
65recv_msg(Buffer *m) 68recv_msg(struct sshbuf *m)
66{ 69{
67 u_int l, len; 70 u_int l, len;
68 u_char buf[1024]; 71 u_char c, buf[1024];
72 int r;
69 73
70 if ((len = atomicio(read, fd, buf, 4)) != 4) { 74 if ((len = atomicio(read, fd, buf, 4)) != 4) {
71 error("read from helper failed: %u", len); 75 error("read from helper failed: %u", len);
72 return (0); /* XXX */ 76 return (0); /* XXX */
73 } 77 }
74 len = get_u32(buf); 78 len = PEEK_U32(buf);
75 if (len > 256 * 1024) 79 if (len > 256 * 1024)
76 fatal("response too long: %u", len); 80 fatal("response too long: %u", len);
77 /* read len bytes into m */ 81 /* read len bytes into m */
78 buffer_clear(m); 82 sshbuf_reset(m);
79 while (len > 0) { 83 while (len > 0) {
80 l = len; 84 l = len;
81 if (l > sizeof(buf)) 85 if (l > sizeof(buf))
@@ -84,10 +88,13 @@ recv_msg(Buffer *m)
84 error("response from helper failed."); 88 error("response from helper failed.");
85 return (0); /* XXX */ 89 return (0); /* XXX */
86 } 90 }
87 buffer_append(m, buf, l); 91 if ((r = sshbuf_put(m, buf, l)) != 0)
92 fatal("%s: buffer error: %s", __func__, ssh_err(r));
88 len -= l; 93 len -= l;
89 } 94 }
90 return (buffer_get_char(m)); 95 if ((r = sshbuf_get_u8(m, &c)) != 0)
96 fatal("%s: buffer error: %s", __func__, ssh_err(r));
97 return c;
91} 98}
92 99
93int 100int
@@ -109,34 +116,39 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
109{ 116{
110 struct sshkey key; /* XXX */ 117 struct sshkey key; /* XXX */
111 u_char *blob, *signature = NULL; 118 u_char *blob, *signature = NULL;
112 u_int blen, slen = 0; 119 size_t blen, slen = 0;
113 int ret = -1; 120 int r, ret = -1;
114 Buffer msg; 121 struct sshbuf *msg;
115 122
116 if (padding != RSA_PKCS1_PADDING) 123 if (padding != RSA_PKCS1_PADDING)
117 return (-1); 124 return (-1);
118 key.type = KEY_RSA; 125 key.type = KEY_RSA;
119 key.rsa = rsa; 126 key.rsa = rsa;
120 if (key_to_blob(&key, &blob, &blen) == 0) 127 if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) {
128 error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
121 return -1; 129 return -1;
122 buffer_init(&msg); 130 }
123 buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); 131 if ((msg = sshbuf_new()) == NULL)
124 buffer_put_string(&msg, blob, blen); 132 fatal("%s: sshbuf_new failed", __func__);
125 buffer_put_string(&msg, from, flen); 133 if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
126 buffer_put_int(&msg, 0); 134 (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
135 (r = sshbuf_put_string(msg, from, flen)) != 0 ||
136 (r = sshbuf_put_u32(msg, 0)) != 0)
137 fatal("%s: buffer error: %s", __func__, ssh_err(r));
127 free(blob); 138 free(blob);
128 send_msg(&msg); 139 send_msg(msg);
129 buffer_clear(&msg); 140 sshbuf_reset(msg);
130 141
131 if (recv_msg(&msg) == SSH2_AGENT_SIGN_RESPONSE) { 142 if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
132 signature = buffer_get_string(&msg, &slen); 143 if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
133 if (slen <= (u_int)RSA_size(rsa)) { 144 fatal("%s: buffer error: %s", __func__, ssh_err(r));
145 if (slen <= (size_t)RSA_size(rsa)) {
134 memcpy(to, signature, slen); 146 memcpy(to, signature, slen);
135 ret = slen; 147 ret = slen;
136 } 148 }
137 free(signature); 149 free(signature);
138 } 150 }
139 buffer_free(&msg); 151 sshbuf_free(msg);
140 return (ret); 152 return (ret);
141} 153}
142 154
@@ -185,31 +197,39 @@ pkcs11_start_helper(void)
185} 197}
186 198
187int 199int
188pkcs11_add_provider(char *name, char *pin, Key ***keysp) 200pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
189{ 201{
190 struct sshkey *k; 202 struct sshkey *k;
191 int i, nkeys; 203 int r;
192 u_char *blob; 204 u_char *blob;
193 u_int blen; 205 size_t blen;
194 Buffer msg; 206 u_int nkeys, i;
207 struct sshbuf *msg;
195 208
196 if (fd < 0 && pkcs11_start_helper() < 0) 209 if (fd < 0 && pkcs11_start_helper() < 0)
197 return (-1); 210 return (-1);
198 211
199 buffer_init(&msg); 212 if ((msg = sshbuf_new()) == NULL)
200 buffer_put_char(&msg, SSH_AGENTC_ADD_SMARTCARD_KEY); 213 fatal("%s: sshbuf_new failed", __func__);
201 buffer_put_cstring(&msg, name); 214 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 ||
202 buffer_put_cstring(&msg, pin); 215 (r = sshbuf_put_cstring(msg, name)) != 0 ||
203 send_msg(&msg); 216 (r = sshbuf_put_cstring(msg, pin)) != 0)
204 buffer_clear(&msg); 217 fatal("%s: buffer error: %s", __func__, ssh_err(r));
218 send_msg(msg);
219 sshbuf_reset(msg);
205 220
206 if (recv_msg(&msg) == SSH2_AGENT_IDENTITIES_ANSWER) { 221 if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
207 nkeys = buffer_get_int(&msg); 222 if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
208 *keysp = xcalloc(nkeys, sizeof(Key *)); 223 fatal("%s: buffer error: %s", __func__, ssh_err(r));
224 *keysp = xcalloc(nkeys, sizeof(struct sshkey *));
209 for (i = 0; i < nkeys; i++) { 225 for (i = 0; i < nkeys; i++) {
210 blob = buffer_get_string(&msg, &blen); 226 /* XXX clean up properly instead of fatal() */
211 free(buffer_get_string(&msg, NULL)); 227 if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
212 k = key_from_blob(blob, blen); 228 (r = sshbuf_skip_string(msg)) != 0)
229 fatal("%s: buffer error: %s",
230 __func__, ssh_err(r));
231 if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
232 fatal("%s: bad key: %s", __func__, ssh_err(r));
213 wrap_key(k->rsa); 233 wrap_key(k->rsa);
214 (*keysp)[i] = k; 234 (*keysp)[i] = k;
215 free(blob); 235 free(blob);
@@ -217,26 +237,28 @@ pkcs11_add_provider(char *name, char *pin, Key ***keysp)
217 } else { 237 } else {
218 nkeys = -1; 238 nkeys = -1;
219 } 239 }
220 buffer_free(&msg); 240 sshbuf_free(msg);
221 return (nkeys); 241 return (nkeys);
222} 242}
223 243
224int 244int
225pkcs11_del_provider(char *name) 245pkcs11_del_provider(char *name)
226{ 246{
227 int ret = -1; 247 int r, ret = -1;
228 Buffer msg; 248 struct sshbuf *msg;
229 249
230 buffer_init(&msg); 250 if ((msg = sshbuf_new()) == NULL)
231 buffer_put_char(&msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY); 251 fatal("%s: sshbuf_new failed", __func__);
232 buffer_put_cstring(&msg, name); 252 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
233 buffer_put_cstring(&msg, ""); 253 (r = sshbuf_put_cstring(msg, name)) != 0 ||
234 send_msg(&msg); 254 (r = sshbuf_put_cstring(msg, "")) != 0)
235 buffer_clear(&msg); 255 fatal("%s: buffer error: %s", __func__, ssh_err(r));
256 send_msg(msg);
257 sshbuf_reset(msg);
236 258
237 if (recv_msg(&msg) == SSH_AGENT_SUCCESS) 259 if (recv_msg(msg) == SSH_AGENT_SUCCESS)
238 ret = 0; 260 ret = 0;
239 buffer_free(&msg); 261 sshbuf_free(msg);
240 return (ret); 262 return (ret);
241} 263}
242 264