1 /* $OpenBSD: tls_util.c,v 1.12 2018/02/08 07:55:29 jsing Exp $ */
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
5 * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 #include "tls_internal.h"
30 memdup(const void *in
, size_t len
)
34 if ((out
= malloc(len
)) == NULL
)
41 tls_set_mem(char **dest
, size_t *destlen
, const void *src
, size_t srclen
)
47 if ((*dest
= memdup(src
, srclen
)) == NULL
)
54 tls_set_string(const char **dest
, const char *src
)
59 if ((*dest
= strdup(src
)) == NULL
)
65 * Extract the host and port from a colon separated value. For a literal IPv6
66 * address the address must be contained with square braces. If a host and
67 * port are successfully extracted, the function will return 0 and the
68 * caller is responsible for freeing the host and port. If no port is found
69 * then the function will return 1, with both host and port being NULL.
70 * On memory allocation failure -1 will be returned.
73 tls_host_port(const char *hostport
, char **host
, char **port
)
81 if ((s
= strdup(hostport
)) == NULL
)
86 /* See if this is an IPv6 literal with square braces. */
89 if ((p
= strchr(s
, ']')) == NULL
)
94 /* Find the port seperator. */
95 if ((p
= strchr(p
, ':')) == NULL
)
98 /* If there is another separator then we have issues. */
99 if (strchr(p
+ 1, ':') != NULL
)
104 if (asprintf(host
, "%s", h
) == -1)
106 if (asprintf(port
, "%s", p
) == -1)
126 tls_password_cb(char *buf
, int size
, int rwflag
, void *u
)
134 memset(buf
, 0, size
);
138 if ((len
= strlcpy(buf
, u
, size
)) >= (size_t)size
)
145 tls_load_file(const char *name
, size_t *len
, char *password
)
148 EVP_PKEY
*key
= NULL
;
159 if ((fd
= open(name
, O_RDONLY
)) == -1)
162 /* Just load the file into memory without decryption */
163 if (password
== NULL
) {
164 if (fstat(fd
, &st
) != 0)
168 size
= (size_t)st
.st_size
;
169 if ((buf
= malloc(size
)) == NULL
)
171 n
= read(fd
, buf
, size
);
172 if (n
< 0 || (size_t)n
!= size
)
178 /* Or read the (possibly) encrypted key from file */
179 if ((fp
= fdopen(fd
, "r")) == NULL
)
183 key
= PEM_read_PrivateKey(fp
, NULL
, tls_password_cb
, password
);
188 /* Write unencrypted key to memory buffer */
189 if ((bio
= BIO_new(BIO_s_mem())) == NULL
)
191 if (!PEM_write_bio_PrivateKey(bio
, key
, NULL
, NULL
, 0, NULL
, NULL
))
193 if ((size
= BIO_get_mem_data(bio
, &data
)) <= 0)
195 if ((buf
= malloc(size
)) == NULL
)
197 memcpy(buf
, data
, size
);
217 tls_unload_file(uint8_t *buf
, size_t len
)