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