xref: /openssh-portable/sshbuf-misc.c (revision 1910a286)
1 /*	$OpenBSD: sshbuf-misc.c,v 1.3 2015/02/05 12:59:57 millert Exp $	*/
2 /*
3  * Copyright (c) 2011 Damien Miller
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 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <limits.h>
28 #include <string.h>
29 #include <resolv.h>
30 #include <ctype.h>
31 
32 #include "ssherr.h"
33 #define SSHBUF_INTERNAL
34 #include "sshbuf.h"
35 
36 void
37 sshbuf_dump_data(const void *s, size_t len, FILE *f)
38 {
39 	size_t i, j;
40 	const u_char *p = (const u_char *)s;
41 
42 	for (i = 0; i < len; i += 16) {
43 		fprintf(f, "%.4zd: ", i);
44 		for (j = i; j < i + 16; j++) {
45 			if (j < len)
46 				fprintf(f, "%02x ", p[j]);
47 			else
48 				fprintf(f, "   ");
49 		}
50 		fprintf(f, " ");
51 		for (j = i; j < i + 16; j++) {
52 			if (j < len) {
53 				if  (isascii(p[j]) && isprint(p[j]))
54 					fprintf(f, "%c", p[j]);
55 				else
56 					fprintf(f, ".");
57 			}
58 		}
59 		fprintf(f, "\n");
60 	}
61 }
62 
63 void
64 sshbuf_dump(struct sshbuf *buf, FILE *f)
65 {
66 	fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf));
67 	sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);
68 }
69 
70 char *
71 sshbuf_dtob16(struct sshbuf *buf)
72 {
73 	size_t i, j, len = sshbuf_len(buf);
74 	const u_char *p = sshbuf_ptr(buf);
75 	char *ret;
76 	const char hex[] = "0123456789abcdef";
77 
78 	if (len == 0)
79 		return strdup("");
80 	if (SIZE_MAX / 2 <= len || (ret = malloc(len * 2 + 1)) == NULL)
81 		return NULL;
82 	for (i = j = 0; i < len; i++) {
83 		ret[j++] = hex[(p[i] >> 4) & 0xf];
84 		ret[j++] = hex[p[i] & 0xf];
85 	}
86 	ret[j] = '\0';
87 	return ret;
88 }
89 
90 char *
91 sshbuf_dtob64(struct sshbuf *buf)
92 {
93 	size_t len = sshbuf_len(buf), plen;
94 	const u_char *p = sshbuf_ptr(buf);
95 	char *ret;
96 	int r;
97 
98 	if (len == 0)
99 		return strdup("");
100 	plen = ((len + 2) / 3) * 4 + 1;
101 	if (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL)
102 		return NULL;
103 	if ((r = b64_ntop(p, len, ret, plen)) == -1) {
104 		bzero(ret, plen);
105 		free(ret);
106 		return NULL;
107 	}
108 	return ret;
109 }
110 
111 int
112 sshbuf_b64tod(struct sshbuf *buf, const char *b64)
113 {
114 	size_t plen = strlen(b64);
115 	int nlen, r;
116 	u_char *p;
117 
118 	if (plen == 0)
119 		return 0;
120 	if ((p = malloc(plen)) == NULL)
121 		return SSH_ERR_ALLOC_FAIL;
122 	if ((nlen = b64_pton(b64, p, plen)) < 0) {
123 		bzero(p, plen);
124 		free(p);
125 		return SSH_ERR_INVALID_FORMAT;
126 	}
127 	if ((r = sshbuf_put(buf, p, nlen)) < 0) {
128 		bzero(p, plen);
129 		free(p);
130 		return r;
131 	}
132 	bzero(p, plen);
133 	free(p);
134 	return 0;
135 }
136 
137