gui: Check return value of para_exec_cmdline_pid().
[paraslash.git] / crypt_common.c
1 /*
2 * Copyright (C) 2005-2012 Andre Noll <maan@systemlinux.org>
3 *
4 * Licensed under the GPL v2. For licencing details see COPYING.
5 */
6
7 /** \file crypt_common.c Crypto functions independent of openssl/libgcrypt. */
8
9 #include <regex.h>
10
11 #include "para.h"
12 #include "error.h"
13 #include "string.h"
14 #include "crypt_backend.h"
15 #include "crypt.h"
16
17 /** If the key begins with this text, we treat it as an ssh key. */
18 #define KEY_TYPE_TXT "ssh-rsa"
19
20 /**
21 * Check if given buffer starts with a ssh rsa key signature.
22 *
23 * \param data The buffer.
24 * \param size Number of data bytes.
25 *
26 * \return Number of header bytes to be skipped on success, zero if
27 * ssh rsa signature was not found.
28 */
29 size_t is_ssh_rsa_key(char *data, size_t size)
30 {
31 char *cp;
32
33 if (size < strlen(KEY_TYPE_TXT) + 2)
34 return 0;
35 cp = memchr(data, ' ', size);
36 if (cp == NULL)
37 return 0;
38 if (strncmp(KEY_TYPE_TXT, data, strlen(KEY_TYPE_TXT)))
39 return 0;
40 cp++;
41 if (cp >= data + size)
42 return 0;
43 if (*cp == '\0')
44 return 0;
45 return cp - data;
46 }
47
48 /*
49 * This base64/uudecode stuff below is taken from openssh-5.2p1, Copyright (c)
50 * 1996 by Internet Software Consortium. Portions Copyright (c) 1995 by
51 * International Business Machines, Inc.
52 */
53
54 static const char Base64[] =
55 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56 static const char Pad64 = '=';
57
58 /**
59 * base64-decode a buffer.
60 *
61 * \param src The buffer to decode.
62 * \param target Result is stored here.
63 * \param targsize Number of bytes of \a target.
64 *
65 * Skips all whitespace anywhere. Converts characters, four at a time, starting
66 * at (or after) src from base - 64 numbers into three 8 bit bytes in the
67 * target area.
68 *
69 * \return The number of data bytes stored at the target, -E_BASE64 on errors.
70 */
71 int base64_decode(char const *src, unsigned char *target, size_t targsize)
72 {
73 unsigned int tarindex, state;
74 int ch;
75 char *pos;
76
77 state = 0;
78 tarindex = 0;
79
80 while ((ch = *src++) != '\0') {
81 if (para_isspace(ch)) /* Skip whitespace anywhere. */
82 continue;
83
84 if (ch == Pad64)
85 break;
86
87 pos = strchr(Base64, ch);
88 if (pos == NULL) /* A non-base64 character. */
89 return -E_BASE64;
90
91 switch (state) {
92 case 0:
93 if (target) {
94 if (tarindex >= targsize)
95 return -E_BASE64;
96 target[tarindex] = (pos - Base64) << 2;
97 }
98 state = 1;
99 break;
100 case 1:
101 if (target) {
102 if (tarindex + 1 >= targsize)
103 return -E_BASE64;
104 target[tarindex] |= (pos - Base64) >> 4;
105 target[tarindex+1] = ((pos - Base64) & 0x0f)
106 << 4 ;
107 }
108 tarindex++;
109 state = 2;
110 break;
111 case 2:
112 if (target) {
113 if (tarindex + 1 >= targsize)
114 return -E_BASE64;
115 target[tarindex] |= (pos - Base64) >> 2;
116 target[tarindex+1] = ((pos - Base64) & 0x03)
117 << 6;
118 }
119 tarindex++;
120 state = 3;
121 break;
122 case 3:
123 if (target) {
124 if (tarindex >= targsize)
125 return -E_BASE64;
126 target[tarindex] |= (pos - Base64);
127 }
128 tarindex++;
129 state = 0;
130 break;
131 }
132 }
133
134 /*
135 * We are done decoding Base-64 chars. Let's see if we ended
136 * on a byte boundary, and/or with erroneous trailing characters.
137 */
138
139 if (ch == Pad64) { /* We got a pad char. */
140 ch = *src++; /* Skip it, get next. */
141 switch (state) {
142 case 0: /* Invalid = in first position */
143 case 1: /* Invalid = in second position */
144 return -E_BASE64;
145
146 case 2: /* Valid, means one byte of info */
147 /* Skip any number of spaces. */
148 for (; ch != '\0'; ch = *src++)
149 if (!isspace(ch))
150 break;
151 /* Make sure there is another trailing = sign. */
152 if (ch != Pad64)
153 return -E_BASE64;
154 ch = *src++; /* Skip the = */
155 /* Fall through to "single trailing =" case. */
156 /* FALLTHROUGH */
157
158 case 3: /* Valid, means two bytes of info */
159 /*
160 * We know this char is an =. Is there anything but
161 * whitespace after it?
162 */
163 for (; ch != '\0'; ch = *src++)
164 if (!isspace(ch))
165 return -E_BASE64;
166
167 /*
168 * Now make sure for cases 2 and 3 that the "extra"
169 * bits that slopped past the last full byte were
170 * zeros. If we don't check them, they become a
171 * subliminal channel.
172 */
173 if (target && target[tarindex] != 0)
174 return -E_BASE64;
175 }
176 } else {
177 /*
178 * We ended by seeing the end of the string. Make sure we
179 * have no partial bytes lying around.
180 */
181 if (state != 0)
182 return -E_BASE64;
183 }
184
185 return tarindex;
186 }
187
188 /**
189 * uudecode a buffer.
190 *
191 * \param src The buffer to decode.
192 * \param target Result buffer.
193 * \param targsize The length of \a target in bytes.
194 *
195 * This is just a simple wrapper for base64_decode() which strips whitespace.
196 *
197 * \return The return value of the underlying call to base64_decode().
198 */
199 int uudecode(const char *src, unsigned char *target, size_t targsize)
200 {
201 int len;
202 char *encoded, *p;
203
204 /* copy the 'readonly' source */
205 encoded = para_strdup(src);
206 /* skip whitespace and data */
207 for (p = encoded; *p == ' ' || *p == '\t'; p++)
208 ;
209 for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
210 ;
211 /* and remove trailing whitespace because base64_decode needs this */
212 *p = '\0';
213 len = base64_decode(encoded, target, targsize);
214 free(encoded);
215 return len;
216 }
217
218 /**
219 * Read a 4-byte number from a buffer in big-endian format.
220 *
221 * \param vp The buffer.
222 *
223 * The byte-order of the buffer is expected to be big-endian, unlike read_u32()
224 * of portable_io.h which expects little endian.
225 *
226 * \return The 32 bit number given by \a vp.
227 */
228 uint32_t read_ssh_u32(const void *vp)
229 {
230 const unsigned char *p = (const unsigned char *)vp;
231 uint32_t v;
232
233 v = (uint32_t)p[0] << 24;
234 v |= (uint32_t)p[1] << 16;
235 v |= (uint32_t)p[2] << 8;
236 v |= (uint32_t)p[3];
237
238 return v;
239 }
240
241 /**
242 * Sanity checks for the header of an ssh key.
243 *
244 * \param blob The buffer.
245 * \param blen The number of bytes of \a blob.
246 *
247 * This performs some checks to make sure we really have an ssh key. It also
248 * computes the offset in bytes of the start of the key values (modulus,
249 * exponent..).
250 *
251 * \return The number of bytes to skip until the start of the first encoded
252 * number (usually 11).
253 */
254 int check_ssh_key_header(const unsigned char *blob, int blen)
255 {
256 const unsigned char *p = blob, *end = blob + blen;
257 uint32_t rlen;
258
259 if (p + 4 > end)
260 return -E_SSH_KEY_HEADER;
261 rlen = read_ssh_u32(p);
262 p += 4;
263 if (p + rlen < p)
264 return -E_SSH_KEY_HEADER;
265 if (p + rlen > end)
266 return -E_SSH_KEY_HEADER;
267 if (rlen < strlen(KEY_TYPE_TXT))
268 return -E_SSH_KEY_HEADER;
269 PARA_DEBUG_LOG("type: %s, rlen: %d\n", p, rlen);
270 if (strncmp((char *)p, KEY_TYPE_TXT, strlen(KEY_TYPE_TXT)))
271 return -E_SSH_KEY_HEADER;
272 return 4 + rlen;
273 }
274
275 /**
276 * Check existence and permissions of a key file.
277 *
278 * \param file The path of the key file.
279 * \param private_key Whether this is a private key.
280 *
281 * This checks whether the file exists. If it is a private key, we additionally
282 * check that the permissions are restrictive enough. It is considered an error
283 * if we own the file and it is readable for others.
284 *
285 * \return Standard.
286 */
287 int check_key_file(const char *file, bool private_key)
288 {
289 struct stat st;
290
291 if (stat(file, &st) != 0)
292 return -ERRNO_TO_PARA_ERROR(errno);
293 if (!private_key)
294 return 0;
295 if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
296 return -E_KEY_PERM;
297 return 1;
298 }
299
300 void hash_to_asc(unsigned char *hash, char *asc)
301 {
302 int i;
303 const char hexchar[] = "0123456789abcdef";
304
305 for (i = 0; i < HASH_SIZE; i++) {
306 asc[2 * i] = hexchar[hash[i] >> 4];
307 asc[2 * i + 1] = hexchar[hash[i] & 0xf];
308 }
309 asc[2 * HASH_SIZE] = '\0';
310 }
311
312 int hash_compare(unsigned char *h1, unsigned char *h2)
313 {
314 int i;
315
316 for (i = 0; i < HASH_SIZE; i++) {
317 if (h1[i] < h2[i])
318 return -1;
319 if (h1[i] > h2[i])
320 return 1;
321 }
322 return 0;
323 }
324
325 int sc_recv_buffer(struct stream_cipher_context *scc, char *buf, size_t size)
326 {
327 int n;
328
329 assert(size);
330 n = sc_recv_bin_buffer(scc, buf, size - 1);
331 if (n >= 0)
332 buf[n] = '\0';
333 else
334 *buf = '\0';
335 return n;
336 }
337
338 int sc_send_buffer(struct stream_cipher_context *scc, char *buf)
339 {
340 size_t len = strlen(buf);
341 int ret = sc_send_bin_buffer(scc, buf, len);
342
343 if (ret < 0 || ret == len)
344 return ret;
345 return -E_SHORT_WRITE;
346 }
347
348 __printf_2_3 int sc_send_va_buffer(struct stream_cipher_context *scc,
349 const char *fmt, ...)
350 {
351 char *msg;
352 int ret;
353 va_list ap;
354
355 va_start(ap, fmt);
356 ret = xvasprintf(&msg, fmt, ap);
357 va_end(ap);
358 ret = sc_send_bin_buffer(scc, msg, ret);
359 free(msg);
360 return ret;
361 }