xref: /freebsd/crypto/openssh/sshbuf-misc.c (revision bc5531debefeb54993d01d4f3c8b33ccbe0b4d95)
1*bc5531deSDag-Erling Smørgrav /*	$OpenBSD: sshbuf-misc.c,v 1.3 2015/02/05 12:59:57 millert Exp $	*/
2a0ee8cc6SDag-Erling Smørgrav /*
3a0ee8cc6SDag-Erling Smørgrav  * Copyright (c) 2011 Damien Miller
4a0ee8cc6SDag-Erling Smørgrav  *
5a0ee8cc6SDag-Erling Smørgrav  * Permission to use, copy, modify, and distribute this software for any
6a0ee8cc6SDag-Erling Smørgrav  * purpose with or without fee is hereby granted, provided that the above
7a0ee8cc6SDag-Erling Smørgrav  * copyright notice and this permission notice appear in all copies.
8a0ee8cc6SDag-Erling Smørgrav  *
9a0ee8cc6SDag-Erling Smørgrav  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10a0ee8cc6SDag-Erling Smørgrav  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11a0ee8cc6SDag-Erling Smørgrav  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12a0ee8cc6SDag-Erling Smørgrav  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13a0ee8cc6SDag-Erling Smørgrav  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14a0ee8cc6SDag-Erling Smørgrav  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15a0ee8cc6SDag-Erling Smørgrav  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16a0ee8cc6SDag-Erling Smørgrav  */
17a0ee8cc6SDag-Erling Smørgrav 
18a0ee8cc6SDag-Erling Smørgrav #include "includes.h"
19a0ee8cc6SDag-Erling Smørgrav 
20a0ee8cc6SDag-Erling Smørgrav #include <sys/types.h>
21a0ee8cc6SDag-Erling Smørgrav #include <sys/socket.h>
22a0ee8cc6SDag-Erling Smørgrav #include <netinet/in.h>
23a0ee8cc6SDag-Erling Smørgrav #include <errno.h>
24a0ee8cc6SDag-Erling Smørgrav #include <stdlib.h>
25*bc5531deSDag-Erling Smørgrav #ifdef HAVE_STDINT_H
26*bc5531deSDag-Erling Smørgrav #include <stdint.h>
27*bc5531deSDag-Erling Smørgrav #endif
28a0ee8cc6SDag-Erling Smørgrav #include <stdio.h>
29a0ee8cc6SDag-Erling Smørgrav #include <limits.h>
30a0ee8cc6SDag-Erling Smørgrav #include <string.h>
31a0ee8cc6SDag-Erling Smørgrav #include <resolv.h>
32a0ee8cc6SDag-Erling Smørgrav #include <ctype.h>
33a0ee8cc6SDag-Erling Smørgrav 
34a0ee8cc6SDag-Erling Smørgrav #include "ssherr.h"
35a0ee8cc6SDag-Erling Smørgrav #define SSHBUF_INTERNAL
36a0ee8cc6SDag-Erling Smørgrav #include "sshbuf.h"
37a0ee8cc6SDag-Erling Smørgrav 
38a0ee8cc6SDag-Erling Smørgrav void
39a0ee8cc6SDag-Erling Smørgrav sshbuf_dump_data(const void *s, size_t len, FILE *f)
40a0ee8cc6SDag-Erling Smørgrav {
41a0ee8cc6SDag-Erling Smørgrav 	size_t i, j;
42a0ee8cc6SDag-Erling Smørgrav 	const u_char *p = (const u_char *)s;
43a0ee8cc6SDag-Erling Smørgrav 
44a0ee8cc6SDag-Erling Smørgrav 	for (i = 0; i < len; i += 16) {
45a0ee8cc6SDag-Erling Smørgrav 		fprintf(f, "%.4zd: ", i);
46a0ee8cc6SDag-Erling Smørgrav 		for (j = i; j < i + 16; j++) {
47a0ee8cc6SDag-Erling Smørgrav 			if (j < len)
48a0ee8cc6SDag-Erling Smørgrav 				fprintf(f, "%02x ", p[j]);
49a0ee8cc6SDag-Erling Smørgrav 			else
50a0ee8cc6SDag-Erling Smørgrav 				fprintf(f, "   ");
51a0ee8cc6SDag-Erling Smørgrav 		}
52a0ee8cc6SDag-Erling Smørgrav 		fprintf(f, " ");
53a0ee8cc6SDag-Erling Smørgrav 		for (j = i; j < i + 16; j++) {
54a0ee8cc6SDag-Erling Smørgrav 			if (j < len) {
55a0ee8cc6SDag-Erling Smørgrav 				if  (isascii(p[j]) && isprint(p[j]))
56a0ee8cc6SDag-Erling Smørgrav 					fprintf(f, "%c", p[j]);
57a0ee8cc6SDag-Erling Smørgrav 				else
58a0ee8cc6SDag-Erling Smørgrav 					fprintf(f, ".");
59a0ee8cc6SDag-Erling Smørgrav 			}
60a0ee8cc6SDag-Erling Smørgrav 		}
61a0ee8cc6SDag-Erling Smørgrav 		fprintf(f, "\n");
62a0ee8cc6SDag-Erling Smørgrav 	}
63a0ee8cc6SDag-Erling Smørgrav }
64a0ee8cc6SDag-Erling Smørgrav 
65a0ee8cc6SDag-Erling Smørgrav void
66a0ee8cc6SDag-Erling Smørgrav sshbuf_dump(struct sshbuf *buf, FILE *f)
67a0ee8cc6SDag-Erling Smørgrav {
68a0ee8cc6SDag-Erling Smørgrav 	fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf));
69a0ee8cc6SDag-Erling Smørgrav 	sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);
70a0ee8cc6SDag-Erling Smørgrav }
71a0ee8cc6SDag-Erling Smørgrav 
72a0ee8cc6SDag-Erling Smørgrav char *
73a0ee8cc6SDag-Erling Smørgrav sshbuf_dtob16(struct sshbuf *buf)
74a0ee8cc6SDag-Erling Smørgrav {
75a0ee8cc6SDag-Erling Smørgrav 	size_t i, j, len = sshbuf_len(buf);
76a0ee8cc6SDag-Erling Smørgrav 	const u_char *p = sshbuf_ptr(buf);
77a0ee8cc6SDag-Erling Smørgrav 	char *ret;
78a0ee8cc6SDag-Erling Smørgrav 	const char hex[] = "0123456789abcdef";
79a0ee8cc6SDag-Erling Smørgrav 
80a0ee8cc6SDag-Erling Smørgrav 	if (len == 0)
81a0ee8cc6SDag-Erling Smørgrav 		return strdup("");
82a0ee8cc6SDag-Erling Smørgrav 	if (SIZE_MAX / 2 <= len || (ret = malloc(len * 2 + 1)) == NULL)
83a0ee8cc6SDag-Erling Smørgrav 		return NULL;
84a0ee8cc6SDag-Erling Smørgrav 	for (i = j = 0; i < len; i++) {
85a0ee8cc6SDag-Erling Smørgrav 		ret[j++] = hex[(p[i] >> 4) & 0xf];
86a0ee8cc6SDag-Erling Smørgrav 		ret[j++] = hex[p[i] & 0xf];
87a0ee8cc6SDag-Erling Smørgrav 	}
88a0ee8cc6SDag-Erling Smørgrav 	ret[j] = '\0';
89a0ee8cc6SDag-Erling Smørgrav 	return ret;
90a0ee8cc6SDag-Erling Smørgrav }
91a0ee8cc6SDag-Erling Smørgrav 
92a0ee8cc6SDag-Erling Smørgrav char *
93a0ee8cc6SDag-Erling Smørgrav sshbuf_dtob64(struct sshbuf *buf)
94a0ee8cc6SDag-Erling Smørgrav {
95a0ee8cc6SDag-Erling Smørgrav 	size_t len = sshbuf_len(buf), plen;
96a0ee8cc6SDag-Erling Smørgrav 	const u_char *p = sshbuf_ptr(buf);
97a0ee8cc6SDag-Erling Smørgrav 	char *ret;
98a0ee8cc6SDag-Erling Smørgrav 	int r;
99a0ee8cc6SDag-Erling Smørgrav 
100a0ee8cc6SDag-Erling Smørgrav 	if (len == 0)
101a0ee8cc6SDag-Erling Smørgrav 		return strdup("");
102a0ee8cc6SDag-Erling Smørgrav 	plen = ((len + 2) / 3) * 4 + 1;
103a0ee8cc6SDag-Erling Smørgrav 	if (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL)
104a0ee8cc6SDag-Erling Smørgrav 		return NULL;
105a0ee8cc6SDag-Erling Smørgrav 	if ((r = b64_ntop(p, len, ret, plen)) == -1) {
106a0ee8cc6SDag-Erling Smørgrav 		bzero(ret, plen);
107a0ee8cc6SDag-Erling Smørgrav 		free(ret);
108a0ee8cc6SDag-Erling Smørgrav 		return NULL;
109a0ee8cc6SDag-Erling Smørgrav 	}
110a0ee8cc6SDag-Erling Smørgrav 	return ret;
111a0ee8cc6SDag-Erling Smørgrav }
112a0ee8cc6SDag-Erling Smørgrav 
113a0ee8cc6SDag-Erling Smørgrav int
114a0ee8cc6SDag-Erling Smørgrav sshbuf_b64tod(struct sshbuf *buf, const char *b64)
115a0ee8cc6SDag-Erling Smørgrav {
116a0ee8cc6SDag-Erling Smørgrav 	size_t plen = strlen(b64);
117a0ee8cc6SDag-Erling Smørgrav 	int nlen, r;
118a0ee8cc6SDag-Erling Smørgrav 	u_char *p;
119a0ee8cc6SDag-Erling Smørgrav 
120a0ee8cc6SDag-Erling Smørgrav 	if (plen == 0)
121a0ee8cc6SDag-Erling Smørgrav 		return 0;
122a0ee8cc6SDag-Erling Smørgrav 	if ((p = malloc(plen)) == NULL)
123a0ee8cc6SDag-Erling Smørgrav 		return SSH_ERR_ALLOC_FAIL;
124a0ee8cc6SDag-Erling Smørgrav 	if ((nlen = b64_pton(b64, p, plen)) < 0) {
125a0ee8cc6SDag-Erling Smørgrav 		bzero(p, plen);
126a0ee8cc6SDag-Erling Smørgrav 		free(p);
127a0ee8cc6SDag-Erling Smørgrav 		return SSH_ERR_INVALID_FORMAT;
128a0ee8cc6SDag-Erling Smørgrav 	}
129a0ee8cc6SDag-Erling Smørgrav 	if ((r = sshbuf_put(buf, p, nlen)) < 0) {
130a0ee8cc6SDag-Erling Smørgrav 		bzero(p, plen);
131a0ee8cc6SDag-Erling Smørgrav 		free(p);
132a0ee8cc6SDag-Erling Smørgrav 		return r;
133a0ee8cc6SDag-Erling Smørgrav 	}
134a0ee8cc6SDag-Erling Smørgrav 	bzero(p, plen);
135a0ee8cc6SDag-Erling Smørgrav 	free(p);
136a0ee8cc6SDag-Erling Smørgrav 	return 0;
137a0ee8cc6SDag-Erling Smørgrav }
138a0ee8cc6SDag-Erling Smørgrav 
139