OpenCoverage

ssh-pkcs11-client.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/ssh-pkcs11-client.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: ssh-pkcs11-client.c,v 1.10 2018/07/09 21:59:10 markus Exp $ */-
2/*-
3 * Copyright (c) 2010 Markus Friedl. All rights reserved.-
4 *-
5 * Permission to use, copy, modify, and distribute this software for any-
6 * purpose with or without fee is hereby granted, provided that the above-
7 * copyright notice and this permission notice appear in all copies.-
8 *-
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR-
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN-
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF-
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
16 */-
17-
18#include "includes.h"-
19-
20#ifdef ENABLE_PKCS11-
21-
22#include <sys/types.h>-
23#ifdef HAVE_SYS_TIME_H-
24# include <sys/time.h>-
25#endif-
26#include <sys/socket.h>-
27-
28#include <stdarg.h>-
29#include <string.h>-
30#include <unistd.h>-
31#include <errno.h>-
32-
33#include <openssl/rsa.h>-
34-
35#include "openbsd-compat/openssl-compat.h"-
36-
37#include "pathnames.h"-
38#include "xmalloc.h"-
39#include "sshbuf.h"-
40#include "log.h"-
41#include "misc.h"-
42#include "sshkey.h"-
43#include "authfd.h"-
44#include "atomicio.h"-
45#include "ssh-pkcs11.h"-
46#include "ssherr.h"-
47-
48/* borrows code from sftp-server and ssh-agent */-
49-
50int fd = -1;-
51pid_t pid = -1;-
52-
53static void-
54send_msg(struct sshbuf *m)-
55{-
56 u_char buf[4];-
57 size_t mlen = sshbuf_len(m);-
58 int r;-
59-
60 POKE_U32(buf, mlen);-
61 if (atomicio(vwrite, fd, buf, 4) != 4 ||
atomicio((ssiz..., buf, 4) != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
62 atomicio(vwrite, fd, sshbuf_mutable_ptr(m),
atomicio((ssiz... sshbuf_len(m)Description
TRUEnever evaluated
FALSEnever evaluated
0
63 sshbuf_len(m)) != sshbuf_len(m))
atomicio((ssiz... sshbuf_len(m)Description
TRUEnever evaluated
FALSEnever evaluated
0
64 error("write to helper failed");
never executed: error("write to helper failed");
0
65 if ((r = sshbuf_consume(m, mlen)) != 0)
(r = sshbuf_co...m, mlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
66 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
67}
never executed: end of block
0
68-
69static int-
70recv_msg(struct sshbuf *m)-
71{-
72 u_int l, len;-
73 u_char c, buf[1024];-
74 int r;-
75-
76 if ((len = atomicio(read, fd, buf, 4)) != 4) {
(len = atomici... buf, 4)) != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
77 error("read from helper failed: %u", len);-
78 return (0); /* XXX */
never executed: return (0);
0
79 }-
80 len = PEEK_U32(buf);-
81 if (len > 256 * 1024)
len > 256 * 1024Description
TRUEnever evaluated
FALSEnever evaluated
0
82 fatal("response too long: %u", len);
never executed: fatal("response too long: %u", len);
0
83 /* read len bytes into m */-
84 sshbuf_reset(m);-
85 while (len > 0) {
len > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
86 l = len;-
87 if (l > sizeof(buf))
l > sizeof(buf)Description
TRUEnever evaluated
FALSEnever evaluated
0
88 l = sizeof(buf);
never executed: l = sizeof(buf);
0
89 if (atomicio(read, fd, buf, l) != l) {
atomicio(read,..., buf, l) != lDescription
TRUEnever evaluated
FALSEnever evaluated
0
90 error("response from helper failed.");-
91 return (0); /* XXX */
never executed: return (0);
0
92 }-
93 if ((r = sshbuf_put(m, buf, l)) != 0)
(r = sshbuf_pu... buf, l)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
94 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
95 len -= l;-
96 }
never executed: end of block
0
97 if ((r = sshbuf_get_u8(m, &c)) != 0)
(r = sshbuf_ge...8(m, &c)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
98 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
99 return c;
never executed: return c;
0
100}-
101-
102int-
103pkcs11_init(int interactive)-
104{-
105 return (0);
never executed: return (0);
0
106}-
107-
108void-
109pkcs11_terminate(void)-
110{-
111 if (fd >= 0)
fd >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
112 close(fd);
never executed: close(fd);
0
113}
never executed: end of block
0
114-
115static int-
116pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,-
117 int padding)-
118{-
119 struct sshkey key; /* XXX */-
120 u_char *blob, *signature = NULL;-
121 size_t blen, slen = 0;-
122 int r, ret = -1;-
123 struct sshbuf *msg;-
124-
125 if (padding != RSA_PKCS1_PADDING)
padding != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
126 return (-1);
never executed: return (-1);
0
127 key.type = KEY_RSA;-
128 key.rsa = rsa;-
129 if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) {
(r = sshkey_to..., &blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
130 error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));-
131 return -1;
never executed: return -1;
0
132 }-
133 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
134 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
135 if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
(r = sshbuf_pu...msg, 13)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
136 (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
(r = sshbuf_pu...b, blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
137 (r = sshbuf_put_string(msg, from, flen)) != 0 ||
(r = sshbuf_pu...m, flen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
138 (r = sshbuf_put_u32(msg, 0)) != 0)
(r = sshbuf_pu...(msg, 0)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
139 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
140 free(blob);-
141 send_msg(msg);-
142 sshbuf_reset(msg);-
143-
144 if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
recv_msg(msg) == 14Description
TRUEnever evaluated
FALSEnever evaluated
0
145 if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
(r = sshbuf_ge..., &slen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
146 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
147 if (slen <= (size_t)RSA_size(rsa)) {
slen <= (size_t)RSA_size(rsa)Description
TRUEnever evaluated
FALSEnever evaluated
0
148 memcpy(to, signature, slen);-
149 ret = slen;-
150 }
never executed: end of block
0
151 free(signature);-
152 }
never executed: end of block
0
153 sshbuf_free(msg);-
154 return (ret);
never executed: return (ret);
0
155}-
156-
157/* redirect the private key encrypt operation to the ssh-pkcs11-helper */-
158static int-
159wrap_key(RSA *rsa)-
160{-
161 static RSA_METHOD *helper_rsa;-
162-
163 if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
(helper_rsa = ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
164 fatal("%s: RSA_meth_dup failed", __func__);
never executed: fatal("%s: RSA_meth_dup failed", __func__);
0
165 if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
!RSA_meth_set1...kcs11-helper")Description
TRUEnever evaluated
FALSEnever evaluated
0
166 !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt))
!RSA_meth_set_...ivate_encrypt)Description
TRUEnever evaluated
FALSEnever evaluated
0
167 fatal("%s: failed to prepare method", __func__);
never executed: fatal("%s: failed to prepare method", __func__);
0
168 RSA_set_method(rsa, helper_rsa);-
169 return (0);
never executed: return (0);
0
170}-
171-
172static int-
173pkcs11_start_helper(void)-
174{-
175 int pair[2];-
176-
177 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
socketpair( 1 ...0, pair) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
178 error("socketpair: %s", strerror(errno));-
179 return (-1);
never executed: return (-1);
0
180 }-
181 if ((pid = fork()) == -1) {
(pid = fork()) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
182 error("fork: %s", strerror(errno));-
183 return (-1);
never executed: return (-1);
0
184 } else if (pid == 0) {
pid == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
185 if ((dup2(pair[1], STDIN_FILENO) == -1) ||
(dup2(pair[1], 0 ) == -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
186 (dup2(pair[1], STDOUT_FILENO) == -1)) {
(dup2(pair[1], 1 ) == -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
187 fprintf(stderr, "dup2: %s\n", strerror(errno));-
188 _exit(1);-
189 }
never executed: end of block
0
190 close(pair[0]);-
191 close(pair[1]);-
192 execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER,-
193 (char *)NULL);-
194 fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER,-
195 strerror(errno));-
196 _exit(1);-
197 }
never executed: end of block
0
198 close(pair[1]);-
199 fd = pair[0];-
200 return (0);
never executed: return (0);
0
201}-
202-
203int-
204pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)-
205{-
206 struct sshkey *k;-
207 int r;-
208 u_char *blob;-
209 size_t blen;-
210 u_int nkeys, i;-
211 struct sshbuf *msg;-
212-
213 if (fd < 0 && pkcs11_start_helper() < 0)
fd < 0Description
TRUEnever evaluated
FALSEnever evaluated
pkcs11_start_helper() < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
214 return (-1);
never executed: return (-1);
0
215-
216 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
217 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
218 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 ||
(r = sshbuf_pu...msg, 20)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
219 (r = sshbuf_put_cstring(msg, name)) != 0 ||
(r = sshbuf_pu...g, name)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
220 (r = sshbuf_put_cstring(msg, pin)) != 0)
(r = sshbuf_pu...sg, pin)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
221 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
222 send_msg(msg);-
223 sshbuf_reset(msg);-
224-
225 if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
recv_msg(msg) == 12Description
TRUEnever evaluated
FALSEnever evaluated
0
226 if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
(r = sshbuf_ge... &nkeys)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
227 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
228 *keysp = xcalloc(nkeys, sizeof(struct sshkey *));-
229 for (i = 0; i < nkeys; i++) {
i < nkeysDescription
TRUEnever evaluated
FALSEnever evaluated
0
230 /* XXX clean up properly instead of fatal() */-
231 if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
(r = sshbuf_ge..., &blen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
232 (r = sshbuf_skip_string(msg)) != 0)
(r = sshbuf_ge...d *)0) )) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
233 fatal("%s: buffer error: %s",
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
234 __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
235 if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
(r = sshkey_fr...len, &k)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
236 fatal("%s: bad key: %s", __func__, ssh_err(r));
never executed: fatal("%s: bad key: %s", __func__, ssh_err(r));
0
237 wrap_key(k->rsa);-
238 (*keysp)[i] = k;-
239 free(blob);-
240 }
never executed: end of block
0
241 } else {
never executed: end of block
0
242 nkeys = -1;-
243 }
never executed: end of block
0
244 sshbuf_free(msg);-
245 return (nkeys);
never executed: return (nkeys);
0
246}-
247-
248int-
249pkcs11_del_provider(char *name)-
250{-
251 int r, ret = -1;-
252 struct sshbuf *msg;-
253-
254 if ((msg = sshbuf_new()) == NULL)
(msg = sshbuf_...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
255 fatal("%s: sshbuf_new failed", __func__);
never executed: fatal("%s: sshbuf_new failed", __func__);
0
256 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
(r = sshbuf_pu...msg, 21)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
257 (r = sshbuf_put_cstring(msg, name)) != 0 ||
(r = sshbuf_pu...g, name)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
258 (r = sshbuf_put_cstring(msg, "")) != 0)
(r = sshbuf_pu...msg, "")) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
259 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
260 send_msg(msg);-
261 sshbuf_reset(msg);-
262-
263 if (recv_msg(msg) == SSH_AGENT_SUCCESS)
recv_msg(msg) == 6Description
TRUEnever evaluated
FALSEnever evaluated
0
264 ret = 0;
never executed: ret = 0;
0
265 sshbuf_free(msg);-
266 return (ret);
never executed: return (ret);
0
267}-
268-
269#endif /* ENABLE_PKCS11 */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2