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