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