crypt: Move implementation-independent code to separate file.
[paraslash.git] / crypt_common.c
1 /*
2 * Copyright (C) 2005-2011 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 the implementation. */
8
9 #include <regex.h>
10 #include <stdbool.h>
11
12 #include "para.h"
13 #include "error.h"
14 #include "string.h"
15 #include "crypt_backend.h"
16 #include "crypt.h"
17
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 * Skips all whitespace anywhere. Converts characters, four at a time, starting
59 * at (or after) src from base - 64 numbers into three 8 bit bytes in the
60 * target area. it returns the number of data bytes stored at the target, or -1
61 * on error.
62 */
63 static int base64_decode(char const *src, unsigned char *target, size_t targsize)
64 {
65 unsigned int tarindex, state;
66 int ch;
67 char *pos;
68
69 state = 0;
70 tarindex = 0;
71
72 while ((ch = *src++) != '\0') {
73 if (para_isspace(ch)) /* Skip whitespace anywhere. */
74 continue;
75
76 if (ch == Pad64)
77 break;
78
79 pos = strchr(Base64, ch);
80 if (pos == 0) /* A non-base64 character. */
81 return -1;
82
83 switch (state) {
84 case 0:
85 if (target) {
86 if (tarindex >= targsize)
87 return (-1);
88 target[tarindex] = (pos - Base64) << 2;
89 }
90 state = 1;
91 break;
92 case 1:
93 if (target) {
94 if (tarindex + 1 >= targsize)
95 return (-1);
96 target[tarindex] |= (pos - Base64) >> 4;
97 target[tarindex+1] = ((pos - Base64) & 0x0f)
98 << 4 ;
99 }
100 tarindex++;
101 state = 2;
102 break;
103 case 2:
104 if (target) {
105 if (tarindex + 1 >= targsize)
106 return (-1);
107 target[tarindex] |= (pos - Base64) >> 2;
108 target[tarindex+1] = ((pos - Base64) & 0x03)
109 << 6;
110 }
111 tarindex++;
112 state = 3;
113 break;
114 case 3:
115 if (target) {
116 if (tarindex >= targsize)
117 return (-1);
118 target[tarindex] |= (pos - Base64);
119 }
120 tarindex++;
121 state = 0;
122 break;
123 }
124 }
125
126 /*
127 * We are done decoding Base-64 chars. Let's see if we ended
128 * on a byte boundary, and/or with erroneous trailing characters.
129 */
130
131 if (ch == Pad64) { /* We got a pad char. */
132 ch = *src++; /* Skip it, get next. */
133 switch (state) {
134 case 0: /* Invalid = in first position */
135 case 1: /* Invalid = in second position */
136 return (-1);
137
138 case 2: /* Valid, means one byte of info */
139 /* Skip any number of spaces. */
140 for (; ch != '\0'; ch = *src++)
141 if (!isspace(ch))
142 break;
143 /* Make sure there is another trailing = sign. */
144 if (ch != Pad64)
145 return (-1);
146 ch = *src++; /* Skip the = */
147 /* Fall through to "single trailing =" case. */
148 /* FALLTHROUGH */
149
150 case 3: /* Valid, means two bytes of info */
151 /*
152 * We know this char is an =. Is there anything but
153 * whitespace after it?
154 */
155 for (; ch != '\0'; ch = *src++)
156 if (!isspace(ch))
157 return (-1);
158
159 /*
160 * Now make sure for cases 2 and 3 that the "extra"
161 * bits that slopped past the last full byte were
162 * zeros. If we don't check them, they become a
163 * subliminal channel.
164 */
165 if (target && target[tarindex] != 0)
166 return (-1);
167 }
168 } else {
169 /*
170 * We ended by seeing the end of the string. Make sure we
171 * have no partial bytes lying around.
172 */
173 if (state != 0)
174 return (-1);
175 }
176
177 return (tarindex);
178 }
179
180 int uudecode(const char *src, unsigned char *target, size_t targsize)
181 {
182 int len;
183 char *encoded, *p;
184
185 /* copy the 'readonly' source */
186 encoded = para_strdup(src);
187 /* skip whitespace and data */
188 for (p = encoded; *p == ' ' || *p == '\t'; p++)
189 ;
190 for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
191 ;
192 /* and remove trailing whitespace because base64_decode needs this */
193 *p = '\0';
194 len = base64_decode(encoded, target, targsize);
195 free(encoded);
196 return len >= 0? len : -E_BASE64;
197 }
198
199 /*
200 * Can not use the inline functions of portable_io.h here because the byte
201 * order is different.
202 */
203 uint32_t read_ssh_u32(const void *vp)
204 {
205 const unsigned char *p = (const unsigned char *)vp;
206 uint32_t v;
207
208 v = (uint32_t)p[0] << 24;
209 v |= (uint32_t)p[1] << 16;
210 v |= (uint32_t)p[2] << 8;
211 v |= (uint32_t)p[3];
212
213 return v;
214 }
215
216 int check_ssh_key_header(const unsigned char *blob, int blen)
217 {
218 const unsigned char *p = blob, *end = blob + blen;
219 uint32_t rlen;
220
221 if (p + 4 > end)
222 return -E_SSH_KEY_HEADER;
223 rlen = read_ssh_u32(p);
224 p += 4;
225 if (p + rlen < p)
226 return -E_SSH_KEY_HEADER;
227 if (p + rlen > end)
228 return -E_SSH_KEY_HEADER;
229 if (rlen < strlen(KEY_TYPE_TXT))
230 return -E_SSH_KEY_HEADER;
231 PARA_DEBUG_LOG("type: %s, rlen: %d\n", p, rlen);
232 if (strncmp((char *)p, KEY_TYPE_TXT, strlen(KEY_TYPE_TXT)))
233 return -E_SSH_KEY_HEADER;
234 return 4 + rlen;
235 }
236
237 int check_key_file(const char *file, bool private_key)
238 {
239 struct stat st;
240
241 if (stat(file, &st) != 0)
242 return -ERRNO_TO_PARA_ERROR(errno);
243 if (!private_key)
244 return 0;
245 if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
246 return -E_KEY_PERM;
247 return 1;
248 }
249
250 /**
251 * Convert a hash value to ascii format.
252 *
253 * \param hash the hash value.
254 * \param asc Result pointer.
255 *
256 * \a asc must point to an area of at least 2 * \p HASH_SIZE + 1 bytes which
257 * will be filled by the function with the ascii representation of the hash
258 * value given by \a hash, and a terminating \p NULL byte.
259 */
260 void hash_to_asc(unsigned char *hash, char *asc)
261 {
262 int i;
263 const char hexchar[] = "0123456789abcdef";
264
265 for (i = 0; i < HASH_SIZE; i++) {
266 asc[2 * i] = hexchar[hash[i] >> 4];
267 asc[2 * i + 1] = hexchar[hash[i] & 0xf];
268 }
269 asc[2 * HASH_SIZE] = '\0';
270 }
271
272 /**
273 * Compare two hashes.
274 *
275 * \param h1 Pointer to the first hash value.
276 * \param h2 Pointer to the second hash value.
277 *
278 * \return 1, -1, or zero, depending on whether \a h1 is greater than,
279 * less than or equal to h2, respectively.
280 */
281 int hash_compare(unsigned char *h1, unsigned char *h2)
282 {
283 int i;
284
285 for (i = 0; i < HASH_SIZE; i++) {
286 if (h1[i] < h2[i])
287 return -1;
288 if (h1[i] > h2[i])
289 return 1;
290 }
291 return 0;
292 }
293
294 /**
295 * Receive a buffer, decrypt it and write terminating NULL byte.
296 *
297 * \param scc The context.
298 * \param buf The buffer to write the decrypted data to.
299 * \param size The size of \a buf.
300 *
301 * Read at most \a size - 1 bytes from file descriptor given by \a scc, decrypt
302 * the received data and write a NULL byte at the end of the decrypted data.
303 *
304 * \return The return value of the underlying call to \ref
305 * sc_recv_bin_buffer().
306 */
307 int sc_recv_buffer(struct stream_cipher_context *scc, char *buf, size_t size)
308 {
309 int n;
310
311 assert(size);
312 n = sc_recv_bin_buffer(scc, buf, size - 1);
313 if (n >= 0)
314 buf[n] = '\0';
315 else
316 *buf = '\0';
317 return n;
318 }
319
320 /**
321 * Encrypt and send a \p NULL-terminated buffer.
322 *
323 * \param scc The context.
324 * \param buf The buffer to send.
325 *
326 * \return The return value of the underyling call to sc_send_bin_buffer().
327 */
328 int sc_send_buffer(struct stream_cipher_context *scc, const char *buf)
329 {
330 return sc_send_bin_buffer(scc, buf, strlen(buf));
331 }
332
333 /**
334 * Format, encrypt and send a buffer.
335 *
336 * \param scc The context.
337 * \param fmt A format string.
338 *
339 * \return The return value of the underyling call to sc_send_buffer().
340 */
341 __printf_2_3 int sc_send_va_buffer(struct stream_cipher_context *scc,
342 const char *fmt, ...)
343 {
344 char *msg;
345 int ret;
346
347 PARA_VSPRINTF(fmt, msg);
348 ret = sc_send_buffer(scc, msg);
349 free(msg);
350 return ret;
351 }