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