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